diff --git a/algorithms-genetic/.gitignore b/algorithms-modules/algorithms-genetic/.gitignore similarity index 100% rename from algorithms-genetic/.gitignore rename to algorithms-modules/algorithms-genetic/.gitignore diff --git a/algorithms-genetic/README.md b/algorithms-modules/algorithms-genetic/README.md similarity index 100% rename from algorithms-genetic/README.md rename to algorithms-modules/algorithms-genetic/README.md diff --git a/algorithms-genetic/pom.xml b/algorithms-modules/algorithms-genetic/pom.xml similarity index 96% rename from algorithms-genetic/pom.xml rename to algorithms-modules/algorithms-genetic/pom.xml index c53ae0f776..c18ba0e7f1 100644 --- a/algorithms-genetic/pom.xml +++ b/algorithms-modules/algorithms-genetic/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/RunAlgorithm.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/RunAlgorithm.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/RunAlgorithm.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/RunAlgorithm.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/City.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/City.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/City.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/City.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Population.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Population.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Population.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/Population.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/Knapsack.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/Knapsack.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/Knapsack.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/Knapsack.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackFF.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackFF.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackFF.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackFF.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackItem.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackItem.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackItem.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/KnapsackItem.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SimpleGeneticAlgorithm.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SimpleGeneticAlgorithm.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SimpleGeneticAlgorithm.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SimpleGeneticAlgorithm.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenProblem.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenProblem.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenProblem.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenProblem.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenRecord.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenRecord.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenRecord.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SpringsteenRecord.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SubsetSum.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SubsetSum.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SubsetSum.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/SubsetSum.java diff --git a/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/TravelingSalesman.java b/algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/TravelingSalesman.java similarity index 100% rename from algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/TravelingSalesman.java rename to algorithms-modules/algorithms-genetic/src/main/java/com/baeldung/algorithms/ga/jenetics/TravelingSalesman.java diff --git a/algorithms-genetic/src/main/resources/logback.xml b/algorithms-modules/algorithms-genetic/src/main/resources/logback.xml similarity index 100% rename from algorithms-genetic/src/main/resources/logback.xml rename to algorithms-modules/algorithms-genetic/src/main/resources/logback.xml diff --git a/algorithms-genetic/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java b/algorithms-modules/algorithms-genetic/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java similarity index 100% rename from algorithms-genetic/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java rename to algorithms-modules/algorithms-genetic/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java diff --git a/algorithms-genetic/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java b/algorithms-modules/algorithms-genetic/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java similarity index 100% rename from algorithms-genetic/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java rename to algorithms-modules/algorithms-genetic/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java diff --git a/algorithms-genetic/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java b/algorithms-modules/algorithms-genetic/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java similarity index 100% rename from algorithms-genetic/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java rename to algorithms-modules/algorithms-genetic/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java diff --git a/algorithms-miscellaneous-1/README.md b/algorithms-modules/algorithms-miscellaneous-1/README.md similarity index 100% rename from algorithms-miscellaneous-1/README.md rename to algorithms-modules/algorithms-miscellaneous-1/README.md diff --git a/algorithms-miscellaneous-1/pom.xml b/algorithms-modules/algorithms-miscellaneous-1/pom.xml similarity index 97% rename from algorithms-miscellaneous-1/pom.xml rename to algorithms-modules/algorithms-miscellaneous-1/pom.xml index c6f247f4e3..62c9738f1a 100644 --- a/algorithms-miscellaneous-1/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-1/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/FiniteStateMachine.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtFiniteStateMachine.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtState.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtState.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtState.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtState.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtTransition.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtTransition.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtTransition.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/RtTransition.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/State.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/State.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/State.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/State.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/Transition.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/Transition.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/Transition.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/automata/Transition.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/HillClimbing.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/HillClimbing.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/HillClimbing.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/HillClimbing.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/State.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/State.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/State.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/hillclimbing/State.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/GameOfBones.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/GameOfBones.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/GameOfBones.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/GameOfBones.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/MiniMax.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/MiniMax.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/MiniMax.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/MiniMax.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Node.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Node.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Node.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Node.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Tree.java b/algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Tree.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Tree.java rename to algorithms-modules/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/minimax/Tree.java diff --git a/algorithms-miscellaneous-1/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-1/src/main/resources/logback.xml similarity index 100% rename from algorithms-miscellaneous-1/src/main/resources/logback.xml rename to algorithms-modules/algorithms-miscellaneous-1/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java b/algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java b/algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java b/algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java diff --git a/algorithms-miscellaneous-2/README.md b/algorithms-modules/algorithms-miscellaneous-2/README.md similarity index 100% rename from algorithms-miscellaneous-2/README.md rename to algorithms-modules/algorithms-miscellaneous-2/README.md diff --git a/algorithms-miscellaneous-2/pom.xml b/algorithms-modules/algorithms-miscellaneous-2/pom.xml similarity index 97% rename from algorithms-miscellaneous-2/pom.xml rename to algorithms-modules/algorithms-miscellaneous-2/pom.xml index a411cfdb71..f3b41cb7f8 100644 --- a/algorithms-miscellaneous-2/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-2/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/RunAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/RunAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/RunAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/RunAlgorithm.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/Node.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/Node.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/Node.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/linkedlist/Node.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/BFSMazeSolver.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Coordinate.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/DFSMazeSolver.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/Maze.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/maze/solver/MazeDriver.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/numberwordconverter/NumberWordConverter.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/InputData.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/InputData.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/InputData.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/InputData.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/Item.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/Item.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/Item.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/Item.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/User.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/User.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/User.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/slope_one/User.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/BacktrackingAlgorithm.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/ColumnNode.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinks.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingLinksAlgorithm.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java b/algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java rename to algorithms-modules/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/sudoku/DancingNode.java diff --git a/algorithms-miscellaneous-2/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-2/src/main/resources/logback.xml similarity index 100% rename from algorithms-miscellaneous-2/src/main/resources/logback.xml rename to algorithms-modules/algorithms-miscellaneous-2/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-2/src/main/resources/maze/maze1.txt b/algorithms-modules/algorithms-miscellaneous-2/src/main/resources/maze/maze1.txt similarity index 100% rename from algorithms-miscellaneous-2/src/main/resources/maze/maze1.txt rename to algorithms-modules/algorithms-miscellaneous-2/src/main/resources/maze/maze1.txt diff --git a/algorithms-miscellaneous-2/src/main/resources/maze/maze2.txt b/algorithms-modules/algorithms-miscellaneous-2/src/main/resources/maze/maze2.txt similarity index 100% rename from algorithms-miscellaneous-2/src/main/resources/maze/maze2.txt rename to algorithms-modules/algorithms-miscellaneous-2/src/main/resources/maze/maze2.txt diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Graph.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/GraphNode.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteFinder.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/RouteNode.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/Scorer.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/HaversineScorer.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/RouteFinderIntegrationTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/astar/underground/Station.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/moneywords/NumberWordConverterUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/CompleteGraphUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/DirectedGraphUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/EulerianCircuitUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/GraphImageGenerationUnitTest.java b/algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/GraphImageGenerationUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/GraphImageGenerationUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-2/src/test/java/com/baeldung/jgrapht/GraphImageGenerationUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/resources/graph.png b/algorithms-modules/algorithms-miscellaneous-2/src/test/resources/graph.png similarity index 100% rename from algorithms-miscellaneous-2/src/test/resources/graph.png rename to algorithms-modules/algorithms-miscellaneous-2/src/test/resources/graph.png diff --git a/algorithms-miscellaneous-3/.gitignore b/algorithms-modules/algorithms-miscellaneous-3/.gitignore similarity index 100% rename from algorithms-miscellaneous-3/.gitignore rename to algorithms-modules/algorithms-miscellaneous-3/.gitignore diff --git a/algorithms-miscellaneous-3/README.md b/algorithms-modules/algorithms-miscellaneous-3/README.md similarity index 100% rename from algorithms-miscellaneous-3/README.md rename to algorithms-modules/algorithms-miscellaneous-3/README.md diff --git a/algorithms-miscellaneous-3/pom.xml b/algorithms-modules/algorithms-miscellaneous-3/pom.xml similarity index 97% rename from algorithms-miscellaneous-3/pom.xml rename to algorithms-modules/algorithms-miscellaneous-3/pom.xml index 2f180da5e1..8958cbef88 100644 --- a/algorithms-miscellaneous-3/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-3/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestState.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestState.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestState.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestState.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Centroid.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Distance.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Errors.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/EuclideanDistance.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/KMeans.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFm.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/LastFmService.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/kmeans/Record.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamples.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddle.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddle.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddle.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddle.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/MyNode.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/MyNode.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/MyNode.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/MyNode.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/RotateArray.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/RotateArray.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/RotateArray.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/RotateArray.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/TwoSum.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/TwoSum.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/TwoSum.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/twopointertechnique/TwoSum.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/FoldingHash.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/FoldingHash.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/FoldingHash.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/FoldingHash.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/Main.java b/algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/Main.java similarity index 100% rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/Main.java rename to algorithms-modules/algorithms-miscellaneous-3/src/main/java/com/baeldung/folding/Main.java diff --git a/algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json b/algorithms-modules/algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json similarity index 100% rename from algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json rename to algorithms-modules/algorithms-miscellaneous-3/src/main/resources/kmeans/artists.json diff --git a/algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json b/algorithms-modules/algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json similarity index 100% rename from algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json rename to algorithms-modules/algorithms-miscellaneous-3/src/main/resources/kmeans/lastfm.json diff --git a/algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html b/algorithms-modules/algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html similarity index 100% rename from algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html rename to algorithms-modules/algorithms-miscellaneous-3/src/main/resources/kmeans/radial.html diff --git a/algorithms-miscellaneous-3/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-3/src/main/resources/logback.xml similarity index 100% rename from algorithms-miscellaneous-3/src/main/resources/logback.xml rename to algorithms-modules/algorithms-miscellaneous-3/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/analysis/AnalysisRunnerLiveTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestStateUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestStateUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestStateUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/enumstatemachine/LeaveRequestStateUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/printtriangles/PrintTriangleExamplesUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddleUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddleUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddleUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/LinkedListFindMiddleUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/RotateArrayUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/RotateArrayUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/RotateArrayUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/RotateArrayUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/TwoSumUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/TwoSumUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/TwoSumUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/twopointertechnique/TwoSumUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterStatistics.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterStatistics.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterStatistics.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterStatistics.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUnitTest.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUtil.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUtil.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUtil.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/counter/CounterUtil.java diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java b/algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java similarity index 100% rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-3/src/test/java/com/baeldung/folding/FoldingHashUnitTest.java diff --git a/algorithms-miscellaneous-4/README.md b/algorithms-modules/algorithms-miscellaneous-4/README.md similarity index 100% rename from algorithms-miscellaneous-4/README.md rename to algorithms-modules/algorithms-miscellaneous-4/README.md diff --git a/algorithms-miscellaneous-4/pom.xml b/algorithms-modules/algorithms-miscellaneous-4/pom.xml similarity index 94% rename from algorithms-miscellaneous-4/pom.xml rename to algorithms-modules/algorithms-miscellaneous-4/pom.xml index 1dc9a62f64..ed752a6b41 100644 --- a/algorithms-miscellaneous-4/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-4/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/MiddleElementLookup.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/MiddleElementLookup.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/MiddleElementLookup.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/MiddleElementLookup.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/middleelementlookup/Node.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Constants.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/FitnessFunction.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Multiswarm.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Particle.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/multiswarm/Swarm.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/permutation/Permutation.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/permutation/Permutation.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/permutation/Permutation.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/permutation/Permutation.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveInteger.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharacters.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharacters.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharacters.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharacters.java diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/SubstringPalindrome.java b/algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/SubstringPalindrome.java similarity index 100% rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/SubstringPalindrome.java rename to algorithms-modules/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/SubstringPalindrome.java diff --git a/algorithms-miscellaneous-4/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-4/src/main/resources/logback.xml similarity index 100% rename from algorithms-miscellaneous-4/src/main/resources/logback.xml rename to algorithms-modules/algorithms-miscellaneous-4/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/LolFitnessFunction.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/multiswarm/MultiswarmUnitTest.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/smallestinteger/SmallestMissingPositiveIntegerUnitTest.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharactersUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharactersUnitTest.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharactersUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/LongestSubstringNonRepeatingCharactersUnitTest.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/SubstringPalindromeUnitTest.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/SubstringPalindromeUnitTest.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/SubstringPalindromeUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/string/SubstringPalindromeUnitTest.java diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/support/MayFailRule.java b/algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/support/MayFailRule.java similarity index 100% rename from algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/support/MayFailRule.java rename to algorithms-modules/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/support/MayFailRule.java diff --git a/algorithms-miscellaneous-5/README.md b/algorithms-modules/algorithms-miscellaneous-5/README.md similarity index 100% rename from algorithms-miscellaneous-5/README.md rename to algorithms-modules/algorithms-miscellaneous-5/README.md diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-modules/algorithms-miscellaneous-5/pom.xml similarity index 96% rename from algorithms-miscellaneous-5/pom.xml rename to algorithms-modules/algorithms-miscellaneous-5/pom.xml index 7ceede9cb9..26b445555b 100644 --- a/algorithms-miscellaneous-5/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-5/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTree.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/balancedbinarytree/Tree.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/binarygap/BinaryGap.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/combinatorics/Combinatorics.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/combinatorics/Combinatorics.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/combinatorics/Combinatorics.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/combinatorics/Combinatorics.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream2.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream2.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream2.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStream2.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/knapsack/Knapsack.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/knapsack/Knapsack.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/knapsack/Knapsack.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/knapsack/Knapsack.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithm.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/mergesortedarrays/SortedArrays.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/mergesortedarrays/SortedArrays.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/mergesortedarrays/SortedArrays.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/mergesortedarrays/SortedArrays.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Edge.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Edge.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Edge.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Edge.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Prim.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Prim.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Prim.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Prim.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Vertex.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Vertex.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Vertex.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/prim/Vertex.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/relativelyprime/RelativelyPrime.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/relativelyprime/RelativelyPrime.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/relativelyprime/RelativelyPrime.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/relativelyprime/RelativelyPrime.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeNode.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeNode.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeNode.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeNode.java diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeReverser.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeReverser.java similarity index 100% rename from algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeReverser.java rename to algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/reversingtree/TreeReverser.java diff --git a/algorithms-miscellaneous-5/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-5/src/main/resources/logback.xml similarity index 100% rename from algorithms-miscellaneous-5/src/main/resources/logback.xml rename to algorithms-modules/algorithms-miscellaneous-5/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BalancedBinaryTreeUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/balancedbinarytree/BinaryTreeDataProvider.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/binarygap/BinaryGapUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/combinatorics/CombinatoricsUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/combinatorics/CombinatoricsUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/combinatorics/CombinatoricsUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/combinatorics/CombinatoricsUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStreamUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStreamUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStreamUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/integerstreammedian/MedianOfIntegerStreamUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/knapsack/KnapsackUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/knapsack/KnapsackUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/knapsack/KnapsackUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/knapsack/KnapsackUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithmUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithmUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/BruteForceAlgorithmUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/mergesortedarrays/SortedArraysUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/mergesortedarrays/SortedArraysUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/mergesortedarrays/SortedArraysUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/mergesortedarrays/SortedArraysUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/prim/PrimUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/prim/PrimUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/prim/PrimUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/prim/PrimUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/relativelyprime/RelativelyPrimeUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/relativelyprime/RelativelyPrimeUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/relativelyprime/RelativelyPrimeUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/relativelyprime/RelativelyPrimeUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/reversingtree/TreeReverserUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/reversingtree/TreeReverserUnitTest.java similarity index 100% rename from algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/reversingtree/TreeReverserUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/reversingtree/TreeReverserUnitTest.java diff --git a/algorithms-miscellaneous-5/src/test/resources/input.json b/algorithms-modules/algorithms-miscellaneous-5/src/test/resources/input.json similarity index 100% rename from algorithms-miscellaneous-5/src/test/resources/input.json rename to algorithms-modules/algorithms-miscellaneous-5/src/test/resources/input.json diff --git a/algorithms-miscellaneous-6/README.md b/algorithms-modules/algorithms-miscellaneous-6/README.md similarity index 100% rename from algorithms-miscellaneous-6/README.md rename to algorithms-modules/algorithms-miscellaneous-6/README.md diff --git a/algorithms-miscellaneous-6/pom.xml b/algorithms-modules/algorithms-miscellaneous-6/pom.xml similarity index 95% rename from algorithms-miscellaneous-6/pom.xml rename to algorithms-modules/algorithms-miscellaneous-6/pom.xml index 584ec8a8dd..34eae2e2b9 100644 --- a/algorithms-miscellaneous-6/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-6/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDeque.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDeque.java similarity index 97% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDeque.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDeque.java index 4c220b4047..45ef842670 100644 --- a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDeque.java +++ b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDeque.java @@ -31,6 +31,6 @@ public class BalancedBracketsUsingDeque { } } - return true; + return deque.isEmpty(); } } \ No newline at end of file diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingString.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingString.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingString.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingString.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/caesarcipher/CaesarCipher.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/caesarcipher/CaesarCipher.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/caesarcipher/CaesarCipher.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/caesarcipher/CaesarCipher.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/gradientdescent/GradientDescent.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/gradientdescent/GradientDescent.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/gradientdescent/GradientDescent.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/gradientdescent/GradientDescent.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/Follower.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/Follower.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/Follower.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/Follower.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/FollowersPath.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/FollowersPath.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/FollowersPath.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/FollowersPath.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/GreedyAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/GreedyAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/GreedyAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/GreedyAlgorithm.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/NonGreedyAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/NonGreedyAlgorithm.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/NonGreedyAlgorithm.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/NonGreedyAlgorithm.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialConnector.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialConnector.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialConnector.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialConnector.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialUser.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialUser.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialUser.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/greedy/SocialUser.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/CycleDetector.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/CycleDetector.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/CycleDetector.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/CycleDetector.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/DisjointSetInfo.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/DisjointSetInfo.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/DisjointSetInfo.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/DisjointSetInfo.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/Kruskal.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/Kruskal.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/Kruskal.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/kruskal/Kruskal.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/LinkedListReversal.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/LinkedListReversal.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/LinkedListReversal.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/LinkedListReversal.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/ListNode.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/ListNode.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/ListNode.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/linkedlist/ListNode.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/HeapNode.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/HeapNode.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/HeapNode.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/HeapNode.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/MinHeap.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/MinHeap.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/MinHeap.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/minheapmerge/MinHeap.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Board.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Board.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Board.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Board.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Cell.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Cell.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Cell.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Cell.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Computer.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Computer.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Computer.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Computer.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Human.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Human.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Human.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Human.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Move.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Move.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Move.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Move.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Play2048.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Play2048.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Play2048.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/play2048/Play2048.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/BruteForceTopKElementsFinder.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/BruteForceTopKElementsFinder.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/BruteForceTopKElementsFinder.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/BruteForceTopKElementsFinder.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/MaxHeapTopKElementsFinder.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/MaxHeapTopKElementsFinder.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/MaxHeapTopKElementsFinder.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/MaxHeapTopKElementsFinder.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TopKElementsFinder.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TopKElementsFinder.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TopKElementsFinder.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TopKElementsFinder.java diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TreeSetTopKElementsFinder.java b/algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TreeSetTopKElementsFinder.java similarity index 100% rename from algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TreeSetTopKElementsFinder.java rename to algorithms-modules/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/topkelements/TreeSetTopKElementsFinder.java diff --git a/algorithms-miscellaneous-6/src/main/resources/logback.xml b/algorithms-modules/algorithms-miscellaneous-6/src/main/resources/logback.xml similarity index 100% rename from algorithms-miscellaneous-6/src/main/resources/logback.xml rename to algorithms-modules/algorithms-miscellaneous-6/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDequeUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDequeUnitTest.java similarity index 91% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDequeUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDequeUnitTest.java index 964c1ce11a..4c0a56dabc 100644 --- a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDequeUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingDequeUnitTest.java @@ -49,6 +49,12 @@ public class BalancedBracketsUsingDequeUnitTest { assertThat(result).isFalse(); } + @Test + public void givenAnotherEvenLengthUnbalancedString_whenCheckingForBalance_shouldReturnFalse() { + boolean result = balancedBracketsUsingDeque.isBalanced("{{}("); + assertThat(result).isFalse(); + } + @Test public void givenEvenLengthBalancedString_whenCheckingForBalance_shouldReturnTrue() { boolean result = balancedBracketsUsingDeque.isBalanced("{[()]}"); diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingStringUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingStringUnitTest.java similarity index 91% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingStringUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingStringUnitTest.java index 69ce42b0f1..bda85a75ce 100644 --- a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingStringUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/balancedbrackets/BalancedBracketsUsingStringUnitTest.java @@ -49,6 +49,12 @@ public class BalancedBracketsUsingStringUnitTest { assertThat(result).isFalse(); } + @Test + public void givenAnotherEvenLengthUnbalancedString_whenCheckingForBalance_shouldReturnFalse() { + boolean result = balancedBracketsUsingString.isBalanced("{{}("); + assertThat(result).isFalse(); + } + @Test public void givenEvenLengthBalancedString_whenCheckingForBalance_shouldReturnTrue() { boolean result = balancedBracketsUsingString.isBalanced("{[()]}"); diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/caesarcipher/CaesarCipherUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/caesarcipher/CaesarCipherUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/caesarcipher/CaesarCipherUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/caesarcipher/CaesarCipherUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/gradientdescent/GradientDescentUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/gradientdescent/GradientDescentUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/gradientdescent/GradientDescentUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/gradientdescent/GradientDescentUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/greedy/GreedyAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/greedy/GreedyAlgorithmUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/greedy/GreedyAlgorithmUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/greedy/GreedyAlgorithmUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/kruskal/KruskalUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/kruskal/KruskalUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/kruskal/KruskalUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/kruskal/KruskalUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/linkedlist/LinkedListReversalUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/linkedlist/LinkedListReversalUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/linkedlist/LinkedListReversalUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/linkedlist/LinkedListReversalUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/minheapmerge/MinHeapUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/minheapmerge/MinHeapUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/minheapmerge/MinHeapUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/minheapmerge/MinHeapUnitTest.java diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/topkelements/TopKElementsFinderUnitTest.java b/algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/topkelements/TopKElementsFinderUnitTest.java similarity index 100% rename from algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/topkelements/TopKElementsFinderUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/topkelements/TopKElementsFinderUnitTest.java diff --git a/algorithms-searching/README.md b/algorithms-modules/algorithms-searching/README.md similarity index 100% rename from algorithms-searching/README.md rename to algorithms-modules/algorithms-searching/README.md diff --git a/algorithms-searching/pom.xml b/algorithms-modules/algorithms-searching/pom.xml similarity index 92% rename from algorithms-searching/pom.xml rename to algorithms-modules/algorithms-searching/pom.xml index edb8a0c423..f981b4542f 100644 --- a/algorithms-searching/pom.xml +++ b/algorithms-modules/algorithms-searching/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/kthsmallest/KthSmallest.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/kthsmallest/KthSmallest.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/kthsmallest/KthSmallest.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/kthsmallest/KthSmallest.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Point.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Point.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Point.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Point.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/QuadTree.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/QuadTree.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/QuadTree.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/QuadTree.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Region.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Region.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Region.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/quadtree/Region.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/Node.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/Node.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/Node.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/Node.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/SuffixTree.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/SuffixTree.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/SuffixTree.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/suffixtree/SuffixTree.java diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java b/algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java similarity index 100% rename from algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java rename to algorithms-modules/algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java diff --git a/algorithms-searching/src/main/resources/logback.xml b/algorithms-modules/algorithms-searching/src/main/resources/logback.xml similarity index 100% rename from algorithms-searching/src/main/resources/logback.xml rename to algorithms-modules/algorithms-searching/src/main/resources/logback.xml diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/kthsmallest/KthSmallestUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/kthsmallest/KthSmallestUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/kthsmallest/KthSmallestUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/kthsmallest/KthSmallestUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/quadtree/QuadTreeSearchUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/quadtree/QuadTreeSearchUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/quadtree/QuadTreeSearchUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/quadtree/QuadTreeSearchUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/suffixtree/SuffixTreeUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/suffixtree/SuffixTreeUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/suffixtree/SuffixTreeUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/suffixtree/SuffixTreeUnitTest.java diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java b/algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java similarity index 100% rename from algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java rename to algorithms-modules/algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java diff --git a/algorithms-sorting-2/.gitignore b/algorithms-modules/algorithms-sorting-2/.gitignore similarity index 100% rename from algorithms-sorting-2/.gitignore rename to algorithms-modules/algorithms-sorting-2/.gitignore diff --git a/algorithms-sorting-2/README.md b/algorithms-modules/algorithms-sorting-2/README.md similarity index 100% rename from algorithms-sorting-2/README.md rename to algorithms-modules/algorithms-sorting-2/README.md diff --git a/algorithms-sorting-2/pom.xml b/algorithms-modules/algorithms-sorting-2/pom.xml similarity index 95% rename from algorithms-sorting-2/pom.xml rename to algorithms-modules/algorithms-sorting-2/pom.xml index a8477bf624..d81df0adec 100644 --- a/algorithms-sorting-2/pom.xml +++ b/algorithms-modules/algorithms-sorting-2/pom.xml @@ -8,7 +8,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/bynumber/NaturalOrderComparators.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/bynumber/NaturalOrderComparators.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/bynumber/NaturalOrderComparators.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/bynumber/NaturalOrderComparators.java diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/inoutsort/InOutSort.java diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/BentleyMcIlroyPartioning.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/BentleyMcIlroyPartioning.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/BentleyMcIlroyPartioning.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/BentleyMcIlroyPartioning.java diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/DutchNationalFlagPartioning.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/DutchNationalFlagPartioning.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/DutchNationalFlagPartioning.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/DutchNationalFlagPartioning.java diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/Partition.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/Partition.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/Partition.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/Partition.java diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/SortingUtils.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/SortingUtils.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/SortingUtils.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/quicksort/SortingUtils.java diff --git a/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/stringsort/AnagramValidator.java b/algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/stringsort/AnagramValidator.java similarity index 100% rename from algorithms-sorting-2/src/main/java/com/baeldung/algorithms/stringsort/AnagramValidator.java rename to algorithms-modules/algorithms-sorting-2/src/main/java/com/baeldung/algorithms/stringsort/AnagramValidator.java diff --git a/algorithms-sorting-2/src/main/resources/logback.xml b/algorithms-modules/algorithms-sorting-2/src/main/resources/logback.xml similarity index 100% rename from algorithms-sorting-2/src/main/resources/logback.xml rename to algorithms-modules/algorithms-sorting-2/src/main/resources/logback.xml diff --git a/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/bynumber/NaturalOrderComparatorsUnitTest.java b/algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/bynumber/NaturalOrderComparatorsUnitTest.java similarity index 100% rename from algorithms-sorting-2/src/test/java/com/baeldung/algorithms/bynumber/NaturalOrderComparatorsUnitTest.java rename to algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/bynumber/NaturalOrderComparatorsUnitTest.java diff --git a/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java b/algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java similarity index 100% rename from algorithms-sorting-2/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java rename to algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/inoutsort/InOutSortUnitTest.java diff --git a/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/BentleyMcilroyPartitioningUnitTest.java b/algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/BentleyMcilroyPartitioningUnitTest.java similarity index 100% rename from algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/BentleyMcilroyPartitioningUnitTest.java rename to algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/BentleyMcilroyPartitioningUnitTest.java diff --git a/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/DNFThreeWayQuickSortUnitTest.java b/algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/DNFThreeWayQuickSortUnitTest.java similarity index 100% rename from algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/DNFThreeWayQuickSortUnitTest.java rename to algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/quicksort/DNFThreeWayQuickSortUnitTest.java diff --git a/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/AnagramValidatorUnitTest.java b/algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/AnagramValidatorUnitTest.java similarity index 100% rename from algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/AnagramValidatorUnitTest.java rename to algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/AnagramValidatorUnitTest.java diff --git a/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/SortStringUnitTest.java b/algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/SortStringUnitTest.java similarity index 100% rename from algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/SortStringUnitTest.java rename to algorithms-modules/algorithms-sorting-2/src/test/java/com/baeldung/algorithms/stringsort/SortStringUnitTest.java diff --git a/algorithms-sorting/.gitignore b/algorithms-modules/algorithms-sorting/.gitignore similarity index 100% rename from algorithms-sorting/.gitignore rename to algorithms-modules/algorithms-sorting/.gitignore diff --git a/algorithms-sorting/README.md b/algorithms-modules/algorithms-sorting/README.md similarity index 100% rename from algorithms-sorting/README.md rename to algorithms-modules/algorithms-sorting/README.md diff --git a/algorithms-sorting/pom.xml b/algorithms-modules/algorithms-sorting/pom.xml similarity index 95% rename from algorithms-sorting/pom.xml rename to algorithms-modules/algorithms-sorting/pom.xml index 383014d528..eeccbf814d 100644 --- a/algorithms-sorting/pom.xml +++ b/algorithms-modules/algorithms-sorting/pom.xml @@ -9,7 +9,7 @@ com.baeldung - parent-modules + algorithms-modules 1.0.0-SNAPSHOT diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorter.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorter.java similarity index 97% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorter.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorter.java index 002d4997f4..cf86eda4a6 100644 --- a/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorter.java +++ b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorter.java @@ -1,4 +1,4 @@ -package com.baeldung.bucketsort; +package com.baeldung.algorithms.bucketsort; import java.util.ArrayList; import java.util.Comparator; diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/Sorter.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/Sorter.java similarity index 68% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/Sorter.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/Sorter.java index b86f60324f..c1207088da 100644 --- a/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/Sorter.java +++ b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/bucketsort/Sorter.java @@ -1,4 +1,4 @@ -package com.baeldung.bucketsort; +package com.baeldung.algorithms.bucketsort; import java.util.List; diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/counting/CountingSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/heapsort/Heap.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/heapsort/Heap.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/heapsort/Heap.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/heapsort/Heap.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/radixsort/RadixSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/radixsort/RadixSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/radixsort/RadixSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/radixsort/RadixSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/selectionsort/SelectionSort.java diff --git a/algorithms-sorting/src/main/java/com/baeldung/algorithms/shellsort/ShellSort.java b/algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/shellsort/ShellSort.java similarity index 100% rename from algorithms-sorting/src/main/java/com/baeldung/algorithms/shellsort/ShellSort.java rename to algorithms-modules/algorithms-sorting/src/main/java/com/baeldung/algorithms/shellsort/ShellSort.java diff --git a/algorithms-sorting/src/main/resources/logback.xml b/algorithms-modules/algorithms-sorting/src/main/resources/logback.xml similarity index 100% rename from algorithms-sorting/src/main/resources/logback.xml rename to algorithms-modules/algorithms-sorting/src/main/resources/logback.xml diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorterUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorterUnitTest.java similarity index 89% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorterUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorterUnitTest.java index 2773d8a68f..4671819673 100644 --- a/algorithms-sorting/src/test/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorterUnitTest.java +++ b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/bucketsort/IntegerBucketSorterUnitTest.java @@ -1,13 +1,12 @@ -package com.baeldung.bucketsort; +package com.baeldung.algorithms.bucketsort; -import com.baeldung.bucketsort.IntegerBucketSorter; -import org.junit.Before; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.List; -import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; public class IntegerBucketSorterUnitTest { diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/counting/CountingSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/heapsort/HeapUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/radixsort/RadixSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/radixsort/RadixSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/radixsort/RadixSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/radixsort/RadixSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/selectionsort/SelectionSortUnitTest.java diff --git a/algorithms-sorting/src/test/java/com/baeldung/algorithms/shellsort/ShellSortUnitTest.java b/algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/shellsort/ShellSortUnitTest.java similarity index 100% rename from algorithms-sorting/src/test/java/com/baeldung/algorithms/shellsort/ShellSortUnitTest.java rename to algorithms-modules/algorithms-sorting/src/test/java/com/baeldung/algorithms/shellsort/ShellSortUnitTest.java diff --git a/algorithms-modules/pom.xml b/algorithms-modules/pom.xml new file mode 100644 index 0000000000..4ba819cfe3 --- /dev/null +++ b/algorithms-modules/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + algorithms-modules + algorithms-modules + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + algorithms-genetic + algorithms-miscellaneous-1 + algorithms-miscellaneous-2 + algorithms-miscellaneous-3 + algorithms-miscellaneous-4 + algorithms-miscellaneous-5 + algorithms-miscellaneous-6 + algorithms-searching + algorithms-sorting + algorithms-sorting-2 + + + \ No newline at end of file diff --git a/httpclient-2/.gitignore b/apache-httpclient-2/.gitignore similarity index 100% rename from httpclient-2/.gitignore rename to apache-httpclient-2/.gitignore diff --git a/httpclient-2/README.md b/apache-httpclient-2/README.md similarity index 60% rename from httpclient-2/README.md rename to apache-httpclient-2/README.md index 49adf470e9..45f1e41637 100644 --- a/httpclient-2/README.md +++ b/apache-httpclient-2/README.md @@ -1,6 +1,6 @@ -## HttpClient 4.x +## Apache HttpClient -This module contains articles about HttpClient 4.x +This module contains articles about Apache HttpClient ### The Course @@ -12,5 +12,6 @@ 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) +- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url) +- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient) +- More articles: [[<-- prev]](../apache-httpclient) diff --git a/httpclient-2/pom.xml b/apache-httpclient-2/pom.xml similarity index 77% rename from httpclient-2/pom.xml rename to apache-httpclient-2/pom.xml index 32f2e80b18..c5b8195472 100644 --- a/httpclient-2/pom.xml +++ b/apache-httpclient-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 - httpclient-2 + apache-httpclient-2 0.1-SNAPSHOT - httpclient-2 + apache-httpclient-2 com.baeldung @@ -55,10 +55,26 @@ spring-boot-starter-webflux ${spring-boot.version} + + org.mock-server + mockserver-netty + ${mockserver.version} + + + org.mock-server + mockserver-client-java + ${mockserver.version} + + + org.assertj + assertj-core + ${assertj.version} + test + - httpclient-2 + apache-httpclient-2 src/main/resources @@ -79,8 +95,10 @@ + 3.22.0 + 5.11.2 4.5.8 - 5.1 + 5.1.3 11 11 2.1.7.RELEASE diff --git a/httpclient-2/src/main/java/com/baeldung/tlsversion/ClientTlsVersionExamples.java b/apache-httpclient-2/src/main/java/com/baeldung/tlsversion/ClientTlsVersionExamples.java similarity index 100% rename from httpclient-2/src/main/java/com/baeldung/tlsversion/ClientTlsVersionExamples.java rename to apache-httpclient-2/src/main/java/com/baeldung/tlsversion/ClientTlsVersionExamples.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java similarity index 89% rename from httpclient-2/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java index efa7953ba8..5a8c87f4aa 100644 --- a/httpclient-2/src/test/java/com/baeldung/httpclient/rare/HttpClientUnshortenLiveTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java @@ -1,4 +1,4 @@ -package com.baeldung.httpclient.rare; +package com.baeldung.httpclient.expandurl; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; @@ -22,35 +22,29 @@ import java.util.List; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; -public class HttpClientUnshortenLiveTest { +public class HttpClientExpandUrlLiveTest { private CloseableHttpClient client; - // fixtures - @Before public final void before() { client = HttpClientBuilder.create().disableRedirectHandling().build(); } - // tests - @Test - public final void givenShortenedOnce_whenUrlIsUnshortened_thenCorrectResult() throws IOException { - final String expectedResult = "http://www.baeldung.com/rest-versioning"; - final String actualResult = expandSingleLevel("http://bit.ly/13jEoS1"); + public final void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException { + final String expectedResult = "https://www.baeldung.com/rest-versioning"; + final String actualResult = expandSingleLevel("http://bit.ly/3LScTri"); assertThat(actualResult, equalTo(expectedResult)); } @Test - public final void givenShortenedMultiple_whenUrlIsUnshortened_thenCorrectResult() throws IOException { - final String expectedResult = "http://www.baeldung.com/rest-versioning"; + public final void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException { + final String expectedResult = "https://www.baeldung.com/rest-versioning"; final String actualResult = expand("http://t.co/e4rDDbnzmk"); assertThat(actualResult, equalTo(expectedResult)); } - // API - private String expand(final String urlArg) throws IOException { String originalUrl = urlArg; String newUrl = expandSingleLevel(originalUrl); diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java new file mode 100644 index 0000000000..0d45eedc12 --- /dev/null +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java @@ -0,0 +1,78 @@ +package com.baeldung.httpclient.httpclient; + +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpResponse; +import org.apache.hc.core5.http.HttpStatus; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +class ApacheHttpClientUnitTest extends GetRequestMockServer { + + @Test + void givenDeveloperUsedHttpClient_whenExecutingGetRequest_thenStatusIsOkButSonarReportsAnIssue() throws IOException { + HttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(serviceOneUrl); + HttpResponse response = httpClient.execute(httpGet); + assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); + } + + @Test + void givenDeveloperUsedCloseableHttpClient_whenExecutingGetRequest_thenStatusIsOk() throws IOException { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(serviceOneUrl); + HttpResponse response = httpClient.execute(httpGet); + assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); + } + } + + @Test + void givenDeveloperUsedHttpClientBuilder_whenExecutingGetRequest_thenStatusIsOk() throws IOException { + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { + HttpGet httpGet = new HttpGet(serviceOneUrl); + HttpResponse response = httpClient.execute(httpGet); + assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); + } + } + + @Test + void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException { + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { + HttpGet httpGet = new HttpGet(serviceOneUrl); + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + HttpEntity entity = response.getEntity(); + EntityUtils.consume(entity); + assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK); + } + } + } + + @Test + void givenDeveloperUsedSingleClient_whenExecutingTwoGetRequest_thenStatusIsOk() throws IOException { + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { + HttpGet httpGetOne = new HttpGet(serviceOneUrl); + try (CloseableHttpResponse responseOne = httpClient.execute(httpGetOne)) { + HttpEntity entityOne = responseOne.getEntity(); + EntityUtils.consume(entityOne); + assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK); + } + + HttpGet httpGetTwo = new HttpGet(serviceTwoUrl); + try (CloseableHttpResponse responseTwo = httpClient.execute(httpGetTwo)) { + HttpEntity entityTwo = responseTwo.getEntity(); + EntityUtils.consume(entityTwo); + assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK); + } + } + } + +} diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/GetRequestMockServer.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/GetRequestMockServer.java new file mode 100644 index 0000000000..2c08cfa6e4 --- /dev/null +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/GetRequestMockServer.java @@ -0,0 +1,78 @@ +package com.baeldung.httpclient.httpclient; + +import org.apache.hc.core5.http.HttpStatus; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.mockserver.client.MockServerClient; +import org.mockserver.integration.ClientAndServer; + +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 GetRequestMockServer { + + public static ClientAndServer mockServer; + public static String serviceOneUrl; + public static String serviceTwoUrl; + + private static int serverPort; + + public static final String SERVER_ADDRESS = "127.0.0.1"; + public static final String PATH_ONE = "/test1"; + public static final String PATH_TWO = "/test2"; + public static final String METHOD = "GET"; + + @BeforeAll + static void startServer() throws IOException, URISyntaxException { + serverPort = getFreePort(); + serviceOneUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_ONE; + serviceTwoUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_TWO; + mockServer = startClientAndServer(serverPort); + mockGetRequest(); + } + + @AfterAll + static void stopServer() { + mockServer.stop(); + } + + private static void mockGetRequest() { + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH_ONE) + .withMethod(METHOD), + exactly(5) + ) + .respond( + response() + .withStatusCode(HttpStatus.SC_OK) + .withBody("{\"status\":\"ok\"}") + ); + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH_TWO) + .withMethod(METHOD), + exactly(1) + ) + .respond( + response() + .withStatusCode(HttpStatus.SC_OK) + .withBody("{\"status\":\"ok\"}") + ); + } + + private static int getFreePort () throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } + +} diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java diff --git a/httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java similarity index 100% rename from httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java rename to apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java diff --git a/httpclient-2/src/test/resources/logback.xml b/apache-httpclient-2/src/test/resources/logback.xml similarity index 100% rename from httpclient-2/src/test/resources/logback.xml rename to apache-httpclient-2/src/test/resources/logback.xml diff --git a/httpclient/.gitignore b/apache-httpclient/.gitignore similarity index 100% rename from httpclient/.gitignore rename to apache-httpclient/.gitignore diff --git a/httpclient/README.md b/apache-httpclient/README.md similarity index 80% rename from httpclient/README.md rename to apache-httpclient/README.md index ea3bc28572..338b416df1 100644 --- a/httpclient/README.md +++ b/apache-httpclient/README.md @@ -1,6 +1,6 @@ -## HttpClient 4.x +## Apache HttpClient -This module contains articles about HttpClient 4.x +This module contains articles about Apache HttpClient ### The Course @@ -13,8 +13,8 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [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) +- [Advanced Apache 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 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) +- More articles: [[next -->]](../apache-httpclient-2) diff --git a/httpclient/pom.xml b/apache-httpclient/pom.xml similarity index 95% rename from httpclient/pom.xml rename to apache-httpclient/pom.xml index b69981fb13..26eb319ac0 100644 --- a/httpclient/pom.xml +++ b/apache-httpclient/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 - httpclient + apache-httpclient 0.1-SNAPSHOT - httpclient + apache-httpclient com.baeldung @@ -63,7 +63,7 @@ - httpclient + apache-httpclient src/main/resources diff --git a/httpclient/src/main/resources/logback.xml b/apache-httpclient/src/main/resources/logback.xml similarity index 100% rename from httpclient/src/main/resources/logback.xml rename to apache-httpclient/src/main/resources/logback.xml diff --git a/httpclient/src/main/resources/temp.txt b/apache-httpclient/src/main/resources/temp.txt similarity index 100% rename from httpclient/src/main/resources/temp.txt rename to apache-httpclient/src/main/resources/temp.txt diff --git a/httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java diff --git a/httpclient/src/test/java/com/baeldung/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java similarity index 100% rename from httpclient/src/test/java/com/baeldung/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java rename to apache-httpclient/src/test/java/com/baeldung/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java diff --git a/httpclient/src/test/resources/.gitignore b/apache-httpclient/src/test/resources/.gitignore similarity index 100% rename from httpclient/src/test/resources/.gitignore rename to apache-httpclient/src/test/resources/.gitignore diff --git a/httpclient/src/test/resources/test.in b/apache-httpclient/src/test/resources/test.in similarity index 100% rename from httpclient/src/test/resources/test.in rename to apache-httpclient/src/test/resources/test.in diff --git a/httpclient/src/test/resources/uploads/image.jpg b/apache-httpclient/src/test/resources/uploads/image.jpg similarity index 100% rename from httpclient/src/test/resources/uploads/image.jpg rename to apache-httpclient/src/test/resources/uploads/image.jpg diff --git a/httpclient/src/test/resources/uploads/sandbox.txt b/apache-httpclient/src/test/resources/uploads/sandbox.txt similarity index 100% rename from httpclient/src/test/resources/uploads/sandbox.txt rename to apache-httpclient/src/test/resources/uploads/sandbox.txt diff --git a/httpclient/src/test/resources/uploads/temp.txt b/apache-httpclient/src/test/resources/uploads/temp.txt similarity index 100% rename from httpclient/src/test/resources/uploads/temp.txt rename to apache-httpclient/src/test/resources/uploads/temp.txt diff --git a/httpclient/src/test/resources/uploads/zipFile.zip b/apache-httpclient/src/test/resources/uploads/zipFile.zip similarity index 100% rename from httpclient/src/test/resources/uploads/zipFile.zip rename to apache-httpclient/src/test/resources/uploads/zipFile.zip diff --git a/apache-poi-2/pom.xml b/apache-poi-2/pom.xml index 30270cd7be..af959292fa 100644 --- a/apache-poi-2/pom.xml +++ b/apache-poi-2/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 apache-poi-2 0.0.1-SNAPSHOT @@ -25,5 +25,4 @@ 5.2.0 - - + \ No newline at end of file diff --git a/apache-spark/README.md b/apache-spark/README.md index 3a2d2f4e15..862626988b 100644 --- a/apache-spark/README.md +++ b/apache-spark/README.md @@ -9,3 +9,4 @@ This module contains articles about Apache Spark - [Machine Learning with Spark MLlib](https://www.baeldung.com/spark-mlib-machine-learning) - [Introduction to Spark Graph Processing with GraphFrames](https://www.baeldung.com/spark-graph-graphframes) - [Apache Spark: Differences between Dataframes, Datasets and RDDs](https://www.baeldung.com/java-spark-dataframe-dataset-rdd) +- [Spark DataFrame](https://www.baeldung.com/spark-dataframes) diff --git a/apache-spark/data/customerData.csv b/apache-spark/data/customerData.csv new file mode 100644 index 0000000000..8661bcb352 --- /dev/null +++ b/apache-spark/data/customerData.csv @@ -0,0 +1,9 @@ +id,zoneId,FIRST_NAME,MIDDLE_NAME,LAST_NAME,CITY,gender,transaction_date,transaction_amount +1,EU11,Ana1,A,MN, London,Female,1/2/2018,5200 +2,EU12,Ana2,A,MN, London,Female,29/3/2018,1000 +3,EU13,Jack1,Josh,MN, London,Male,19/6/2018,9600 +4,EU14,Jack2,Josh,MN, London,Male,9/9/2018,1000 +5,EU15,Nick1,H,Dee,London,Male,9/6/2021,3000 +6,EU16,Nick2,H,Dee,London,Male,27/9/2021,500 +7,EU17,Nick3,H,Dee,London,Male,8/12/2021,500 +8,EU18,Sara1,H,Dee,London,Female,7/4/2021,2000 \ No newline at end of file diff --git a/apache-spark/data/customerData.json b/apache-spark/data/customerData.json new file mode 100644 index 0000000000..d713d75678 --- /dev/null +++ b/apache-spark/data/customerData.json @@ -0,0 +1,114 @@ +[ + { + "zoneId": "LONDON", + "customerId": 1, + "gender": "Female", + "name": "jane austin", + "contact": { + "street_Address": "XYZ Road", + "address2": "house 47", + "zipcode": "MK1110", + "county": "DCounty", + "phone_number": "(919) 403-0025", + "customer_city": "CityA" + }, + "transaction_date": "2021-02-05", + "transaction_amount": 15000 + }, + { + "zoneId": "LONDON", + "customerId": 2, + "gender": "Male", + "name": "Jack Trevor", + "contact": { + "street_Address": " kingfisher road", + "address2": "SUITE 110", + "zipcode": "HM1190", + "county": "CCounty", + "phone_number": "(919) 403-0025", + "customer_city": "CityB" + }, + "transaction_date": "2021-02-05", + "transaction_amount": 12000 + }, + { + "zoneId": "LONDON", + "customerId": 11, + "gender": "Female", + "name": "jane1 austin", + "contact": { + "street_Address": "B Road", + "address2": "house 47", + "zipcode": "MK1110", + "county": "BCounty", + "phone_number": "(919) 403-0025", + "customer_city": "CityA" + }, + "transaction_date": "2021-02-05", + "transaction_amount": 1000 + }, + { + "zoneId": "LONDON", + "customerId": 21, + "gender": "Male", + "name": "Jack1 Trevor", + "contact": { + "street_Address": " A road", + "address2": "SUITE 777", + "zipcode": "AZ890", + "county": "ACounty", + "phone_number": "(919) 403-0025", + "customer_city": "CityB" + }, + "transaction_date": "2021-02-05", + "transaction_amount": 1000 + }, + { + "zoneId": "Wales", + "customerId": 3, + "gender": "Male", + "name": "John Jack", + "contact": { + "street_Address": "sunny croft", + "address2": "SUITE 1", + "zipcode": "SN1030", + "county": "bucks", + "phone_number": "(919) 403-0025", + "customer_city": "Cardiff" + }, + "transaction_date": "2018-02-05", + "transaction_amount": 5000 + }, + { + "zoneId": "LONDON", + "customerId": 4, + "gender": "Male", + "name": "Jack Trevor", + "contact": { + "street_Address": " kingfisher road", + "address2": "SUITE 110", + "zipcode": "HM1190", + "county": "Hampshire", + "phone_number": "(919) 403-0025", + "customer_city": "CityB" + }, + "transaction_date": "2021-02-05", + "transaction_amount": 500 + }, + { + "zoneId": "Wales", + "customerId": 5, + "gender": "Male", + "name": "John Jack", + "contact": { + "street_Address": "sunny croft", + "address2": "SUITE 1", + "zipcode": "SN1030", + "county": "ECounty", + "phone_number": "(919) 403-0025", + "customer_city": "Cardiff" + }, + "transaction_date": "2018-01-25", + "transaction_amount": 500 + } +] diff --git a/apache-spark/data/minCustomerData.json b/apache-spark/data/minCustomerData.json new file mode 100644 index 0000000000..a47a739d51 --- /dev/null +++ b/apache-spark/data/minCustomerData.json @@ -0,0 +1,20 @@ +[ + { + "id": "1", + "gender": "Female", + "name": "Jo", + "transaction_amount": 200 + }, + { + "id":"2", + "gender": "Male", + "name": "Mike", + "transaction_amount": 500 + }, + { + "id": "3", + "gender": "Male", + "name": "Dave", + "transaction_amount": 5000 + } +] \ No newline at end of file diff --git a/apache-spark/docker/docker-compose.yaml b/apache-spark/docker/docker-compose.yaml new file mode 100644 index 0000000000..960e543229 --- /dev/null +++ b/apache-spark/docker/docker-compose.yaml @@ -0,0 +1,33 @@ +version: "3" + +services: + postgres: + image: postgres:12.3-alpine + restart: always + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + expose: + - 5432 + ports: + - 5432:5432 + command: -p 5432 + volumes: + - ./init.sql:/docker-entrypoint-initdb.d/init.sql +# - postgres:/var/lib/postgresql/data + + pgadmin: + image: dpage/pgadmin4:4.23 + environment: + PGADMIN_DEFAULT_EMAIL: admin@pgadmin.com + PGADMIN_DEFAULT_PASSWORD: password + PGADMIN_LISTEN_PORT: 80 + ports: + - 15432:80 + volumes: + - pgadmin:/var/lib/pgadmin + depends_on: + - postgres + +volumes: + pgadmin: \ No newline at end of file diff --git a/apache-spark/docker/init.sql b/apache-spark/docker/init.sql new file mode 100755 index 0000000000..371135faa3 --- /dev/null +++ b/apache-spark/docker/init.sql @@ -0,0 +1 @@ +CREATE DATABASE customerdb; \ No newline at end of file diff --git a/apache-spark/pom.xml b/apache-spark/pom.xml index 05c5088662..b86e99433a 100644 --- a/apache-spark/pom.xml +++ b/apache-spark/pom.xml @@ -20,37 +20,31 @@ org.apache.spark spark-core_2.11 ${org.apache.spark.spark-core.version} - provided org.apache.spark spark-sql_2.11 ${org.apache.spark.spark-sql.version} - provided org.apache.spark spark-graphx_2.11 ${org.apache.spark.spark-graphx.version} - provided graphframes graphframes ${graphframes.version} - provided org.apache.spark spark-streaming_2.11 ${org.apache.spark.spark-streaming.version} - provided org.apache.spark spark-mllib_2.11 ${org.apache.spark.spark-mllib.version} - provided org.apache.spark @@ -67,6 +61,11 @@ spark-cassandra-connector-java_2.11 ${com.datastax.spark.spark-cassandra-connector-java.version} + + org.postgresql + postgresql + ${postgres.version} + @@ -108,6 +107,7 @@ 2.4.8 2.5.2 1.6.0-M1 + 42.3.3 \ No newline at end of file diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/Customer.java b/apache-spark/src/main/java/com/baeldung/dataframes/Customer.java new file mode 100644 index 0000000000..97fa160872 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/Customer.java @@ -0,0 +1,52 @@ +package com.baeldung.dataframes; + +public class Customer { + String id; + String name; + String gender; + int transaction_amount; + + public Customer() { + + } + + public Customer(String id, String name, String gender, int transaction_amount) { + this.id = id; + this.name = name; + this.gender = gender; + this.transaction_amount = transaction_amount; + } + + 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 getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public int getTransaction_amount() { + return transaction_amount; + } + + public void setTransaction_amount(int transaction_amount) { + this.transaction_amount = transaction_amount; + } + +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/CustomerDataAggregationPipeline.java b/apache-spark/src/main/java/com/baeldung/dataframes/CustomerDataAggregationPipeline.java new file mode 100644 index 0000000000..869645624a --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/CustomerDataAggregationPipeline.java @@ -0,0 +1,129 @@ +package com.baeldung.dataframes; + +import static org.apache.spark.sql.functions.col; +import static org.apache.spark.sql.functions.column; +import static org.apache.spark.sql.functions.concat; +import static org.apache.spark.sql.functions.lit; + +import java.util.Properties; + +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SaveMode; +import org.apache.spark.sql.SparkSession; +import org.apache.spark.sql.functions; + +public class CustomerDataAggregationPipeline { + private static final SparkSession SPARK_SESSION = SparkDriver.getSparkSession(); + + private final Properties dbProperties; + + public CustomerDataAggregationPipeline(Properties properties) { + dbProperties = properties; + } + + public static void main(String[] args) { + // replace with actual DB properties + Properties dbProps = new Properties(); + dbProps.setProperty("connectionURL", "jdbc:postgresql://localhost:5432/customerdb"); + dbProps.setProperty("driver", "org.postgresql.Driver"); + dbProps.setProperty("user", "postgres"); + dbProps.setProperty("password", "postgres"); + + new CustomerDataAggregationPipeline(dbProps).run(); + } + + public void run() { + Dataset ebayDFRaw = ingestCustomerDataFromEbay(); + Dataset ebayDf = normalizeCustomerDataFromEbay(ebayDFRaw); + + Dataset amazonDFRaw = ingestCustomerDataFromAmazon(); + Dataset amazonDf = normalizeCustomerDataFromAmazon(amazonDFRaw); + + Dataset combineDataframes = combineDataframes(ebayDf, amazonDf); + + Dataset rowDataset = aggregateYearlySalesByGender(combineDataframes); + + exportData(rowDataset); + } + + private static Dataset ingestCustomerDataFromAmazon() { + return SPARK_SESSION.read() + .format("csv") + .option("header", "true") + .schema(SchemaFactory.customerSchema()) + .option("dateFormat", "m/d/YYYY") + .load("data/customerData.csv"); + } + + private static Dataset ingestCustomerDataFromEbay() { + return SPARK_SESSION.read() + .format("org.apache.spark.sql.execution.datasources.json.JsonFileFormat") + .option("multiline", true) + .load("data/customerData.json"); + } + + private static Dataset combineDataframes(Dataset df1, Dataset df2) { + return df1.unionByName(df2); + } + + private static Dataset normalizeCustomerDataFromEbay(Dataset rawDataset) { + Dataset transformedDF = rawDataset.withColumn("id", concat(rawDataset.col("zoneId"), lit("-"), rawDataset.col("customerId"))) + .drop(column("customerId")) + .withColumn("source", lit("ebay")) + .withColumn("city", rawDataset.col("contact.customer_city")) + .drop(column("contact")) + .drop(column("zoneId")) + .withColumn("year", functions.year(col("transaction_date"))) + .drop("transaction_date") + .withColumn("firstName", functions.split(column("name"), " ") + .getItem(0)) + .withColumn("lastName", functions.split(column("name"), " ") + .getItem(1)) + .drop(column("name")); + + print(transformedDF); + return transformedDF; + } + + private static Dataset normalizeCustomerDataFromAmazon(Dataset rawDataset) { + + Dataset transformedDF = rawDataset.withColumn("id", concat(rawDataset.col("zoneId"), lit("-"), rawDataset.col("id"))) + .withColumn("source", lit("amazon")) + .withColumnRenamed("CITY", "city") + .withColumnRenamed("PHONE_NO", "contactNo") + .withColumnRenamed("POSTCODE", "postCode") + .withColumnRenamed("FIRST_NAME", "firstName") + .drop(column("MIDDLE_NAME")) + .drop(column("zoneId")) + .withColumnRenamed("LAST_NAME", "lastName") + .withColumn("year", functions.year(col("transaction_date"))) + .drop("transaction_date"); + + print(transformedDF); + return transformedDF; + } + + private static Dataset aggregateYearlySalesByGender(Dataset dataset) { + + Dataset aggDF = dataset.groupBy(column("year"), column("source"), column("gender")) + .sum("transaction_amount") + .withColumnRenamed("sum(transaction_amount)", "annual_spending") + .orderBy(col("year").asc(), col("annual_spending").desc()); + + print(aggDF); + return aggDF; + } + + private static void print(Dataset aggDs) { + aggDs.show(); + aggDs.printSchema(); + } + + private void exportData(Dataset dataset) { + String connectionURL = dbProperties.getProperty("connectionURL"); + dataset.write() + .mode(SaveMode.Overwrite) + .jdbc(connectionURL, "customer", dbProperties); + } +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/CustomerToDataFrameConverterApp.java b/apache-spark/src/main/java/com/baeldung/dataframes/CustomerToDataFrameConverterApp.java new file mode 100644 index 0000000000..53799c1079 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/CustomerToDataFrameConverterApp.java @@ -0,0 +1,46 @@ +package com.baeldung.dataframes; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; + +public class CustomerToDataFrameConverterApp { + + private static final List CUSTOMERS = Arrays.asList( + aCustomerWith("01", "jo", "Female", 2000), + aCustomerWith("02", "jack", "Male", 1200) + ); + + public static void main(String[] args) { + Dataset dataFrame = convertAfterMappingRows(CUSTOMERS); + print(dataFrame); + Dataset customerDF = convertToDataFrameWithNoChange(); + print(customerDF); + } + + public static Dataset convertToDataFrameWithNoChange() { + return SparkDriver.getSparkSession().createDataFrame(CUSTOMERS, Customer.class); + } + + public static Dataset convertAfterMappingRows(List customer) { + List rows = customer.stream() + .map(c -> new CustomerToRowMapper().call(c)) + .collect(Collectors.toList()); + + return SparkDriver.getSparkSession() + .createDataFrame(rows, SchemaFactory.minimumCustomerDataSchema()); + } + + private static Customer aCustomerWith(String id, String name, String gender, int amount) { + return new Customer(id, name, gender, amount); + } + + private static void print(Dataset dataFrame) { + dataFrame.printSchema(); + dataFrame.show(); + } + +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/CustomerToRowMapper.java b/apache-spark/src/main/java/com/baeldung/dataframes/CustomerToRowMapper.java new file mode 100644 index 0000000000..e54bceb3ad --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/CustomerToRowMapper.java @@ -0,0 +1,18 @@ +package com.baeldung.dataframes; + +import org.apache.commons.lang3.StringUtils; +import org.apache.spark.api.java.function.MapFunction; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.RowFactory; + +public class CustomerToRowMapper implements MapFunction { + + @Override + public Row call(Customer customer) { + Row row = RowFactory.create( + customer.getId(), customer.getName().toUpperCase(), + StringUtils.substring(customer.getGender(),0, 1), + customer.getTransaction_amount()); + return row; + } +} \ No newline at end of file diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/DataFrameToCustomerConverterApp.java b/apache-spark/src/main/java/com/baeldung/dataframes/DataFrameToCustomerConverterApp.java new file mode 100644 index 0000000000..31ad8de12b --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/DataFrameToCustomerConverterApp.java @@ -0,0 +1,21 @@ +package com.baeldung.dataframes; + +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Encoders; +import org.apache.spark.sql.Row; + +public class DataFrameToCustomerConverterApp { + + public static void main(String[] args) { + Dataset df = SparkDriver.getSparkSession() + .read() + .format("org.apache.spark.sql.execution.datasources.json.JsonFileFormat") + .option("multiline", true) + .load("data/minCustomerData.json"); + df.show(); + df.printSchema(); + Dataset customerDS = df.map(new RowToCustomerMapper(), Encoders.bean(Customer. class)); + customerDS.show(); + customerDS.printSchema(); + } +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/DataSetToDataFrameConverterApp.java b/apache-spark/src/main/java/com/baeldung/dataframes/DataSetToDataFrameConverterApp.java new file mode 100644 index 0000000000..23db18dddf --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/DataSetToDataFrameConverterApp.java @@ -0,0 +1,57 @@ +package com.baeldung.dataframes; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Encoders; +import org.apache.spark.sql.Row; +import org.apache.spark.sql.SparkSession; + +public class DataSetToDataFrameConverterApp { + + private static final SparkSession SPARK_SESSION = SparkDriver.getSparkSession(); + + public static void main(String[] args) { + + Dataset customerDataset = convertToDataSetFromPOJO(); + Dataset customerDataFrame = customerDataset.toDF(); + print(customerDataFrame); + + List names = getNames(); + Dataset namesDataset = convertToDataSetFromStrings(names); + Dataset namesDataFrame = namesDataset.toDF(); + print(namesDataFrame); + } + + private static Dataset convertToDataSetFromStrings(List names) { + return SPARK_SESSION.createDataset(names, Encoders.STRING()); + } + + private static Dataset convertToDataSetFromPOJO() { + return SPARK_SESSION.createDataset(CUSTOMERS, Encoders.bean(Customer.class)); + } + + private static final List CUSTOMERS = Arrays.asList( + aCustomerWith("01", "jo", "Female", 2000), + aCustomerWith("02", "jack", "Female", 1200), + aCustomerWith("03", "ash", "male", 2000), + aCustomerWith("04", "emma", "Female", 2000) + ); + + private static List getNames() { + return CUSTOMERS.stream() + .map(Customer::getName) + .collect(Collectors.toList()); + } + + private static void print(Dataset df) { + df.show(); + df.printSchema(); + } + + private static Customer aCustomerWith(String id, String name, String gender, int amount) { + return new Customer(id, name, gender, amount); + } +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/RowToCustomerMapper.java b/apache-spark/src/main/java/com/baeldung/dataframes/RowToCustomerMapper.java new file mode 100644 index 0000000000..02fde539c8 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/RowToCustomerMapper.java @@ -0,0 +1,19 @@ +package com.baeldung.dataframes; + +import org.apache.spark.api.java.function.MapFunction; +import org.apache.spark.sql.Row; + +class RowToCustomerMapper implements MapFunction { + + @Override + public Customer call(Row row) { + + Customer customer = new Customer(); + customer.setId(row.getAs("id")); + customer.setName(row.getAs("name")); + customer.setGender(row.getAs("gender")); + customer.setTransaction_amount(Math.toIntExact(row.getAs("transaction_amount"))); + + return customer; + } +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/SchemaFactory.java b/apache-spark/src/main/java/com/baeldung/dataframes/SchemaFactory.java new file mode 100644 index 0000000000..6c298e4829 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/SchemaFactory.java @@ -0,0 +1,31 @@ +package com.baeldung.dataframes; + +import org.apache.spark.sql.types.DataTypes; +import org.apache.spark.sql.types.StructField; +import org.apache.spark.sql.types.StructType; + +public class SchemaFactory { + + public static StructType customerSchema() { + return DataTypes.createStructType( + new StructField[] { DataTypes.createStructField("id", DataTypes.IntegerType, false), + DataTypes.createStructField("zoneId", DataTypes.StringType, false), + DataTypes.createStructField("FIRST_NAME", DataTypes.StringType, false), + DataTypes.createStructField("MIDDLE_NAME", DataTypes.StringType, false), + DataTypes.createStructField("LAST_NAME", DataTypes.StringType, false), + DataTypes.createStructField("CITY", DataTypes.StringType, false), + DataTypes.createStructField("gender", DataTypes.StringType, false), + DataTypes.createStructField("transaction_date", DataTypes.DateType, false), + DataTypes.createStructField("transaction_amount", DataTypes.IntegerType, false) + }); + } + + public static StructType minimumCustomerDataSchema() { + return DataTypes.createStructType(new StructField[] { + DataTypes.createStructField("id", DataTypes.StringType, true), + DataTypes.createStructField("name", DataTypes.StringType, true), + DataTypes.createStructField("gender", DataTypes.StringType, true), + DataTypes.createStructField("transaction_amount", DataTypes.IntegerType, true) + }); + } +} diff --git a/apache-spark/src/main/java/com/baeldung/dataframes/SparkDriver.java b/apache-spark/src/main/java/com/baeldung/dataframes/SparkDriver.java new file mode 100644 index 0000000000..adc25170a7 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/dataframes/SparkDriver.java @@ -0,0 +1,16 @@ +package com.baeldung.dataframes; + +import java.io.Serializable; + +import org.apache.spark.sql.SparkSession; + +public class SparkDriver implements Serializable { + + public static SparkSession getSparkSession() { + return SparkSession.builder() + .appName("Customer Aggregation pipeline") + .master("local") + .getOrCreate(); + + } +} diff --git a/apache-spark/src/test/java/com/baeldung/dataframes/CustomerDataAggregationPipelineLiveTest.java b/apache-spark/src/test/java/com/baeldung/dataframes/CustomerDataAggregationPipelineLiveTest.java new file mode 100644 index 0000000000..52a7b1451f --- /dev/null +++ b/apache-spark/src/test/java/com/baeldung/dataframes/CustomerDataAggregationPipelineLiveTest.java @@ -0,0 +1,52 @@ +package com.baeldung.dataframes; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class CustomerDataAggregationPipelineLiveTest { + + private static Connection conn; + + @BeforeAll + static void beforeAll() throws SQLException { + DriverManager.registerDriver(new org.postgresql.Driver()); + String dbURL1 = "jdbc:postgresql://localhost:5432/customerdb"; + conn = DriverManager.getConnection(dbURL1, "postgres", "postgres"); + + String sql = "drop table if exists customer"; + + PreparedStatement statement = conn.prepareStatement(sql); + statement.executeUpdate(); + } + + @Test + void givenCSVAndJSON_whenRun_thenStoresAggregatedDataFrameInDB() throws Exception { + Properties dbProps = new Properties(); + dbProps.setProperty("connectionURL", "jdbc:postgresql://localhost:5432/customerdb"); + dbProps.setProperty("driver", "org.postgresql.Driver"); + dbProps.setProperty("user", "postgres"); + dbProps.setProperty("password", "postgres"); + + CustomerDataAggregationPipeline pipeline = new CustomerDataAggregationPipeline(dbProps); + pipeline.run(); + + String allCustomersSql = "Select count(*) from customer"; + + Statement statement = conn.createStatement(); + ResultSet resultSet = statement.executeQuery(allCustomersSql); + resultSet.next(); + int count = resultSet.getInt(1); + assertEquals(7, count); + } + +} diff --git a/apache-spark/src/test/java/com/baeldung/dataframes/CustomerToDataFrameConverterAppUnitTest.java b/apache-spark/src/test/java/com/baeldung/dataframes/CustomerToDataFrameConverterAppUnitTest.java new file mode 100644 index 0000000000..06c8f66bcd --- /dev/null +++ b/apache-spark/src/test/java/com/baeldung/dataframes/CustomerToDataFrameConverterAppUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.dataframes; + +import static com.baeldung.dataframes.CustomerToDataFrameConverterApp.convertAfterMappingRows; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.apache.spark.sql.Dataset; +import org.apache.spark.sql.Row; +import org.junit.jupiter.api.Test; + +class CustomerToDataFrameConverterAppUnitTest { + + @Test + void givenCustomers_whenConvertAfterMappingRows_thenConvertsToDataSet() { + + List customers = Arrays.asList( + new Customer("01", "jo", "Female", 2000), + new Customer("02", "jack", "Male", 1200) + ); + + Dataset customerDF = convertAfterMappingRows(customers); + List rows = customerDF.collectAsList(); + Row row1 = rows.get(0); + Row row2 = rows.get(1); + + assertEquals("01", row1.get(0)); + assertEquals( "JO", row1.get(1)); + assertEquals( "F", row1.get(2)); + assertEquals( 2000, row1.get(3)); + + assertEquals("02", row2.get(0)); + assertEquals( "JACK", row2.get(1)); + assertEquals( "M", row2.get(2)); + assertEquals( 1200, row2.get(3)); + } + + @Test + void givenCustomers_whenConvertWithNoChange_thenConvertsToDataSet() { + + List customers = Arrays.asList( + new Customer("01", "jo", "Female", 2000), + new Customer("02", "jack", "Male", 1200) + ); + + Dataset customerDF = CustomerToDataFrameConverterApp.convertToDataFrameWithNoChange(); + List rows = customerDF.collectAsList(); + Row row1 = rows.get(0); + Row row2 = rows.get(1); + + assertEquals("01", row1.getAs("id")); + assertEquals( "jo", row1.getAs("name")); + assertEquals( "Female", row1.getAs("gender")); + assertEquals( 2000, (int)row1.getAs("transaction_amount")); + + assertEquals("02", row2.getAs("id")); + assertEquals( "jack", row2.getAs("name")); + assertEquals( "Male", row2.getAs("gender")); + assertEquals( 1200, (int)row2.getAs("transaction_amount")); + } +} diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java index a3e1811e6f..b1083021a9 100644 --- a/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java +++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/ActionsUnitTest.java @@ -12,21 +12,29 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import scala.Tuple2; public class ActionsUnitTest { + + public static final Logger LOG = LoggerFactory.getLogger(ActionsUnitTest.class); + private static JavaRDD tourists; private static JavaSparkContext sc; public static final String COMMA_DELIMITER = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; - + @BeforeClass public static void init() { - SparkConf conf = new SparkConf().setAppName("reduce") - .setMaster("local[*]"); + SparkConf conf = new SparkConf() + .setAppName("reduce") + .setMaster("local[*]") + .set("spark.driver.allowMultipleContexts", "true"); + sc = new JavaSparkContext(conf); tourists = sc.textFile("data/Tourist.csv").filter(line -> !line.startsWith("Region")); } - + @AfterClass public static void cleanup() { sc.close(); @@ -40,11 +48,11 @@ public class ActionsUnitTest { }) .distinct(); Long numberOfCountries = countries.count(); - System.out.println("Count: " + numberOfCountries); - + LOG.debug("Count: {}", numberOfCountries); + assertEquals(Long.valueOf(220), numberOfCountries); } - + @Test public void whenReduceByKeySum_thenTotalValuePerKey() { JavaRDD touristsExpenditure = tourists.filter(line -> line.split(COMMA_DELIMITER)[3].contains("expenditure")); @@ -53,10 +61,12 @@ public class ActionsUnitTest { String[] columns = line.split(COMMA_DELIMITER); return new Tuple2<>(columns[1], Double.valueOf(columns[6])); }); - List> totalByCountry = expenditurePairRdd.reduceByKey((x, y) -> x + y) - .collect(); - System.out.println("Total per Country: " + totalByCountry); - + List> totalByCountry = expenditurePairRdd + .reduceByKey(Double::sum) + .collect(); + + LOG.debug("Total per Country: {}", totalByCountry); + for(Tuple2 tuple : totalByCountry) { if (tuple._1.equals("Mexico")) { assertEquals(Double.valueOf(99164), tuple._2); diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java index f294e5bc66..621e589fb6 100644 --- a/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java +++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/DataFrameUnitTest.java @@ -39,8 +39,10 @@ public class DataFrameUnitTest { @Test public void whenSelectSpecificColumns_thenColumnsFiltered() { Dataset selectedData = data.select(col("country"), col("year"), col("value")); - selectedData.show(); - + + // uncomment to see table + // selectedData.show(); + List resultList = Arrays.asList(selectedData.columns()); assertTrue(resultList.contains("country")); assertTrue(resultList.contains("year")); @@ -52,22 +54,26 @@ public class DataFrameUnitTest { @Test public void whenFilteringByCountry_thenCountryRecordsSelected() { Dataset filteredData = data.filter(col("country").equalTo("Mexico")); - filteredData.show(); - + + // uncomment to see table + // filteredData.show(); + filteredData.foreach(record -> { assertEquals("Mexico", record.get(1)); }); - + } @Test public void whenGroupCountByCountry_thenContryTotalRecords() { Dataset recordsPerCountry = data.groupBy(col("country")) .count(); - recordsPerCountry.show(); - + + // uncomment to see table + // recordsPerCountry.show(); + Dataset filteredData = recordsPerCountry.filter(col("country").equalTo("Sweden")); - assertEquals(new Long(12), filteredData.first() + assertEquals(12L, filteredData.first() .get(1)); } diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java index 1d83505812..4fde933a3b 100644 --- a/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java +++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/DatasetUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.differences.rdd; import static org.apache.spark.sql.functions.col; import static org.apache.spark.sql.functions.sum; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.apache.spark.api.java.function.FilterFunction; import org.apache.spark.sql.DataFrameReader; @@ -29,8 +30,8 @@ public class DatasetUnitTest { DataFrameReader dataFrameReader = session.read(); Dataset data = dataFrameReader.option("header", "true") .csv("data/Tourist.csv"); - Dataset responseWithSelectedColumns = data.select(col("region"), - col("country"), col("year"), col("series"), col("value").cast("double"), + Dataset responseWithSelectedColumns = data.select(col("region"), + col("country"), col("year"), col("series"), col("value").cast("double"), col("footnotes"), col("source")); typedDataset = responseWithSelectedColumns.as(Encoders.bean(TouristData.class)); } @@ -45,7 +46,9 @@ public class DatasetUnitTest { Dataset selectedData = typedDataset .filter((FilterFunction) record -> record.getCountry() .equals("Norway")); - selectedData.show(); + + // uncomment to see output + // selectedData.show(); selectedData.foreach(record -> { assertEquals("Norway", record.getCountry()); @@ -56,28 +59,41 @@ public class DatasetUnitTest { public void whenGroupCountByCountry_thenContryTotalRecords() { Dataset countriesCount = typedDataset.groupBy(typedDataset.col("country")) .count(); - countriesCount.show(); - assertEquals(Long.valueOf(220), Long.valueOf(countriesCount.count())); + // uncomment to see output + // countriesCount.show(); + + assertEquals(220, countriesCount.count()); } @Test public void whenFilteredByPropertyRange_thenRetreiveValidRecords() { // Filter records with existing data for years between 2010 and 2017 - typedDataset.filter((FilterFunction) record -> record.getYear() != null - && (Long.valueOf(record.getYear()) > 2010 && Long.valueOf(record.getYear()) < 2017)) - .show(); + Dataset filteredData = typedDataset.filter( + (FilterFunction) record -> record.getYear() != null + && (Long.parseLong(record.getYear()) > 2010 && Long.parseLong(record.getYear()) < 2017)); + + // uncomment to see output + // filteredData.show(); + + assertEquals(394, filteredData.count()); + filteredData.foreach(record -> { + assertTrue(Integer.parseInt(record.getYear()) > 2010 && Integer.parseInt(record.getYear()) < 2017); + }); } - + @Test public void whenSumValue_thenRetreiveTotalValue() { // Total tourist expenditure by country - typedDataset.filter((FilterFunction) record -> record.getValue() != null - && record.getSeries() - .contains("expenditure")) - .groupBy("country") - .agg(sum("value")) - .show(); + Dataset filteredData = typedDataset.filter((FilterFunction) record -> record.getValue() != null + && record.getSeries().contains("expenditure")) + .groupBy("country") + .agg(sum("value")); + + // uncomment to see output + // filteredData.show(); + + assertEquals(212, filteredData.count()); } } diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java index 01e7d3adfc..6de407f3b4 100644 --- a/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java +++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java @@ -23,8 +23,11 @@ public class TransformationsUnitTest { @BeforeClass public static void init() { - SparkConf conf = new SparkConf().setAppName("uppercaseCountries") - .setMaster("local[*]"); + SparkConf conf = new SparkConf() + .setAppName("uppercaseCountries") + .setMaster("local[*]") + .set("spark.driver.allowMultipleContexts", "true"); + sc = new JavaSparkContext(conf); tourists = sc.textFile("data/Tourist.csv") .filter(line -> !line.startsWith("Region")); //filter header row diff --git a/apache-tapestry/pom.xml b/apache-tapestry/pom.xml index 7a4c2b53b5..201b807d9f 100644 --- a/apache-tapestry/pom.xml +++ b/apache-tapestry/pom.xml @@ -3,12 +3,17 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.baeldung apache-tapestry 0.0.1-SNAPSHOT apache-tapestry war + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + - - org.lucee - jets3t - ${jets3t-version} - - - org.lucee - commons-codec - ${commons-codec-version} - @@ -89,6 +78,25 @@ + + org.apache.maven.plugins + maven-dependency-plugin + ${maven-plugins-version} + + + copy + compile + + copy-dependencies + + + + so,dll,dylib + native-libs + + + + @@ -110,6 +118,7 @@ 1.10.L001 0.9.4.0006L 3.0.0 + 3.1.1 \ No newline at end of file diff --git a/aws/src/main/java/com/baeldung/dynamodb/entity/ProductInfo.java b/aws-modules/aws-miscellaneous/src/main/java/com/baeldung/dynamodb/entity/ProductInfo.java similarity index 100% rename from aws/src/main/java/com/baeldung/dynamodb/entity/ProductInfo.java rename to aws-modules/aws-miscellaneous/src/main/java/com/baeldung/dynamodb/entity/ProductInfo.java diff --git a/aws/src/main/java/com/baeldung/dynamodb/repository/AbstractRepository.java b/aws-modules/aws-miscellaneous/src/main/java/com/baeldung/dynamodb/repository/AbstractRepository.java similarity index 100% rename from aws/src/main/java/com/baeldung/dynamodb/repository/AbstractRepository.java rename to aws-modules/aws-miscellaneous/src/main/java/com/baeldung/dynamodb/repository/AbstractRepository.java diff --git a/aws/src/main/java/com/baeldung/dynamodb/repository/ProductInfoRepository.java b/aws-modules/aws-miscellaneous/src/main/java/com/baeldung/dynamodb/repository/ProductInfoRepository.java similarity index 100% rename from aws/src/main/java/com/baeldung/dynamodb/repository/ProductInfoRepository.java rename to aws-modules/aws-miscellaneous/src/main/java/com/baeldung/dynamodb/repository/ProductInfoRepository.java diff --git a/aws/src/main/java/com/baeldung/ec2/EC2Application.java b/aws-modules/aws-miscellaneous/src/main/java/com/baeldung/ec2/EC2Application.java similarity index 100% rename from aws/src/main/java/com/baeldung/ec2/EC2Application.java rename to aws-modules/aws-miscellaneous/src/main/java/com/baeldung/ec2/EC2Application.java diff --git a/aws/src/main/java/com/baeldung/rds/AWSRDSService.java b/aws-modules/aws-miscellaneous/src/main/java/com/baeldung/rds/AWSRDSService.java similarity index 100% rename from aws/src/main/java/com/baeldung/rds/AWSRDSService.java rename to aws-modules/aws-miscellaneous/src/main/java/com/baeldung/rds/AWSRDSService.java diff --git a/aws/src/main/java/com/baeldung/sqs/SQSApplication.java b/aws-modules/aws-miscellaneous/src/main/java/com/baeldung/sqs/SQSApplication.java similarity index 100% rename from aws/src/main/java/com/baeldung/sqs/SQSApplication.java rename to aws-modules/aws-miscellaneous/src/main/java/com/baeldung/sqs/SQSApplication.java diff --git a/aws/src/main/resources/db.properties b/aws-modules/aws-miscellaneous/src/main/resources/db.properties similarity index 100% rename from aws/src/main/resources/db.properties rename to aws-modules/aws-miscellaneous/src/main/resources/db.properties diff --git a/aws-lambda/lambda/src/main/resources/logback.xml b/aws-modules/aws-miscellaneous/src/main/resources/logback.xml similarity index 100% rename from aws-lambda/lambda/src/main/resources/logback.xml rename to aws-modules/aws-miscellaneous/src/main/resources/logback.xml diff --git a/aws/src/test/java/com/baeldung/dynamodb/ProductInfoRepositoryIntegrationTest.java b/aws-modules/aws-miscellaneous/src/test/java/com/baeldung/dynamodb/ProductInfoRepositoryIntegrationTest.java similarity index 100% rename from aws/src/test/java/com/baeldung/dynamodb/ProductInfoRepositoryIntegrationTest.java rename to aws-modules/aws-miscellaneous/src/test/java/com/baeldung/dynamodb/ProductInfoRepositoryIntegrationTest.java diff --git a/aws/src/test/java/com/baeldung/dynamodb/rule/LocalDbCreationRule.java b/aws-modules/aws-miscellaneous/src/test/java/com/baeldung/dynamodb/rule/LocalDbCreationRule.java similarity index 100% rename from aws/src/test/java/com/baeldung/dynamodb/rule/LocalDbCreationRule.java rename to aws-modules/aws-miscellaneous/src/test/java/com/baeldung/dynamodb/rule/LocalDbCreationRule.java diff --git a/aws/src/test/resources/test.properties b/aws-modules/aws-miscellaneous/src/test/resources/test.properties similarity index 100% rename from aws/src/test/resources/test.properties rename to aws-modules/aws-miscellaneous/src/test/resources/test.properties diff --git a/aws-reactive/README.md b/aws-modules/aws-reactive/README.md similarity index 58% rename from aws-reactive/README.md rename to aws-modules/aws-reactive/README.md index 1abf987b52..9164bd0ea6 100644 --- a/aws-reactive/README.md +++ b/aws-modules/aws-reactive/README.md @@ -1,3 +1,7 @@ +## AWS Reactive + +This module contains articles about reactive support with AWS + ### Relevant Articles: - [AWS S3 with Java – Reactive Support](https://www.baeldung.com/java-aws-s3-reactive) diff --git a/aws-reactive/images/rective-upload.png b/aws-modules/aws-reactive/images/rective-upload.png similarity index 100% rename from aws-reactive/images/rective-upload.png rename to aws-modules/aws-reactive/images/rective-upload.png diff --git a/aws-reactive/images/rective-upload.txt b/aws-modules/aws-reactive/images/rective-upload.txt similarity index 100% rename from aws-reactive/images/rective-upload.txt rename to aws-modules/aws-reactive/images/rective-upload.txt diff --git a/aws-reactive/images/thread-per-client.png b/aws-modules/aws-reactive/images/thread-per-client.png similarity index 100% rename from aws-reactive/images/thread-per-client.png rename to aws-modules/aws-reactive/images/thread-per-client.png diff --git a/aws-reactive/images/thread-per-client.txt b/aws-modules/aws-reactive/images/thread-per-client.txt similarity index 100% rename from aws-reactive/images/thread-per-client.txt rename to aws-modules/aws-reactive/images/thread-per-client.txt diff --git a/aws-reactive/pom.xml b/aws-modules/aws-reactive/pom.xml similarity index 98% rename from aws-reactive/pom.xml rename to aws-modules/aws-reactive/pom.xml index 923e1361ab..7a9cefb9d1 100644 --- a/aws-reactive/pom.xml +++ b/aws-modules/aws-reactive/pom.xml @@ -10,7 +10,7 @@ com.baeldung - parent-modules + aws-modules 1.0.0-SNAPSHOT diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadFailedException.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadFailedException.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadFailedException.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadFailedException.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadResource.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadResource.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadResource.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/DownloadResource.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/ReactiveS3Application.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/ReactiveS3Application.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/ReactiveS3Application.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/ReactiveS3Application.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfigurarionProperties.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfigurarionProperties.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfigurarionProperties.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfigurarionProperties.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfiguration.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfiguration.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfiguration.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/S3ClientConfiguration.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadFailedException.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadFailedException.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadFailedException.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadFailedException.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResource.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResource.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResource.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResource.java diff --git a/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResult.java b/aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResult.java similarity index 100% rename from aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResult.java rename to aws-modules/aws-reactive/src/main/java/com/baeldung/aws/reactive/s3/UploadResult.java diff --git a/aws-reactive/src/main/resources/application-minio.yml b/aws-modules/aws-reactive/src/main/resources/application-minio.yml similarity index 100% rename from aws-reactive/src/main/resources/application-minio.yml rename to aws-modules/aws-reactive/src/main/resources/application-minio.yml diff --git a/aws-reactive/src/main/resources/application.yml b/aws-modules/aws-reactive/src/main/resources/application.yml similarity index 100% rename from aws-reactive/src/main/resources/application.yml rename to aws-modules/aws-reactive/src/main/resources/application.yml diff --git a/aws-reactive/src/test/java/com/baeldung/aws/reactive/s3/ReactiveS3ApplicationLiveTest.java b/aws-modules/aws-reactive/src/test/java/com/baeldung/aws/reactive/s3/ReactiveS3ApplicationLiveTest.java similarity index 100% rename from aws-reactive/src/test/java/com/baeldung/aws/reactive/s3/ReactiveS3ApplicationLiveTest.java rename to aws-modules/aws-reactive/src/test/java/com/baeldung/aws/reactive/s3/ReactiveS3ApplicationLiveTest.java diff --git a/aws-reactive/src/test/resources/testimage1.png b/aws-modules/aws-reactive/src/test/resources/testimage1.png similarity index 100% rename from aws-reactive/src/test/resources/testimage1.png rename to aws-modules/aws-reactive/src/test/resources/testimage1.png diff --git a/aws-reactive/src/test/resources/testimage2.png b/aws-modules/aws-reactive/src/test/resources/testimage2.png similarity index 100% rename from aws-reactive/src/test/resources/testimage2.png rename to aws-modules/aws-reactive/src/test/resources/testimage2.png diff --git a/aws-modules/aws-s3/.gitignore b/aws-modules/aws-s3/.gitignore new file mode 100644 index 0000000000..bf11a4cc38 --- /dev/null +++ b/aws-modules/aws-s3/.gitignore @@ -0,0 +1,2 @@ +/target/ +.idea/ \ No newline at end of file diff --git a/aws-modules/aws-s3/README.md b/aws-modules/aws-s3/README.md new file mode 100644 index 0000000000..efebf7d933 --- /dev/null +++ b/aws-modules/aws-s3/README.md @@ -0,0 +1,9 @@ +## AWS S3 + +This module contains articles about Simple Storage Service (S3) on AWS + +### Relevant articles + +- [AWS S3 with Java](https://www.baeldung.com/aws-s3-java) +- [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload) +- [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) \ No newline at end of file diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml new file mode 100644 index 0000000000..e7e04782b1 --- /dev/null +++ b/aws-modules/aws-s3/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + aws-s3 + 0.1.0-SNAPSHOT + aws-s3 + jar + + + com.baeldung + aws-modules + 1.0.0-SNAPSHOT + + + + + com.amazonaws + aws-java-sdk + ${aws-java-sdk.version} + + + commons-io + commons-io + ${commons-io.version} + + + + org.lucee + jets3t + ${jets3t-version} + + + org.lucee + commons-codec + ${commons-codec-version} + + + + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + false + + + + package + + shade + + + + + + + + + 1.11.290 + 1.10.L001 + 0.9.4.0006L + 3.0.0 + + + \ No newline at end of file diff --git a/aws/src/main/java/com/baeldung/s3/AWSS3Service.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3Service.java similarity index 100% rename from aws/src/main/java/com/baeldung/s3/AWSS3Service.java rename to aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3Service.java diff --git a/aws/src/main/java/com/baeldung/s3/MultipartUpload.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/MultipartUpload.java similarity index 100% rename from aws/src/main/java/com/baeldung/s3/MultipartUpload.java rename to aws-modules/aws-s3/src/main/java/com/baeldung/s3/MultipartUpload.java diff --git a/aws/src/main/java/com/baeldung/s3/S3Application.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3Application.java similarity index 100% rename from aws/src/main/java/com/baeldung/s3/S3Application.java rename to aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3Application.java diff --git a/aws/src/main/resources/logback.xml b/aws-modules/aws-s3/src/main/resources/logback.xml similarity index 100% rename from aws/src/main/resources/logback.xml rename to aws-modules/aws-s3/src/main/resources/logback.xml diff --git a/aws/src/test/java/com/baeldung/jets3t/JetS3tLiveTest.java b/aws-modules/aws-s3/src/test/java/com/baeldung/jets3t/JetS3tLiveTest.java similarity index 100% rename from aws/src/test/java/com/baeldung/jets3t/JetS3tLiveTest.java rename to aws-modules/aws-s3/src/test/java/com/baeldung/jets3t/JetS3tLiveTest.java diff --git a/aws/src/test/java/com/baeldung/s3/AWSS3ServiceIntegrationTest.java b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/AWSS3ServiceIntegrationTest.java similarity index 100% rename from aws/src/test/java/com/baeldung/s3/AWSS3ServiceIntegrationTest.java rename to aws-modules/aws-s3/src/test/java/com/baeldung/s3/AWSS3ServiceIntegrationTest.java diff --git a/aws/src/test/java/com/baeldung/s3/MultipartUploadLiveTest.java b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/MultipartUploadLiveTest.java similarity index 100% rename from aws/src/test/java/com/baeldung/s3/MultipartUploadLiveTest.java rename to aws-modules/aws-s3/src/test/java/com/baeldung/s3/MultipartUploadLiveTest.java diff --git a/aws-modules/pom.xml b/aws-modules/pom.xml new file mode 100644 index 0000000000..3c5459d46c --- /dev/null +++ b/aws-modules/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + aws-modules + aws-modules + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + aws-app-sync + aws-lambda + aws-miscellaneous + aws-reactive + aws-s3 + + + \ No newline at end of file diff --git a/aws/README.md b/aws/README.md deleted file mode 100644 index 9006c2d190..0000000000 --- a/aws/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## AWS - -This module contains articles about Amazon Web Services (AWS) - -### Relevant articles - -- [AWS Lambda Using DynamoDB With Java](https://www.baeldung.com/aws-lambda-dynamodb-java) -- [AWS S3 with Java](https://www.baeldung.com/aws-s3-java) -- [A Basic AWS Lambda Example With Java](https://www.baeldung.com/java-aws-lambda) -- [Managing EC2 Instances in Java](https://www.baeldung.com/ec2-java) -- [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload) -- [Integration Testing with a Local DynamoDB Instance](https://www.baeldung.com/dynamodb-local-integration-tests) -- [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) -- [Managing Amazon SQS Queues in Java](https://www.baeldung.com/aws-queues-java) -- [Guide to AWS Aurora RDS with Java](https://www.baeldung.com/aws-aurora-rds-java) diff --git a/aws/native-libs/libsqlite4java-linux-amd64-1.0.392.so b/aws/native-libs/libsqlite4java-linux-amd64-1.0.392.so deleted file mode 100644 index 884615789b..0000000000 Binary files a/aws/native-libs/libsqlite4java-linux-amd64-1.0.392.so and /dev/null differ diff --git a/aws/native-libs/libsqlite4java-linux-i386-1.0.392.so b/aws/native-libs/libsqlite4java-linux-i386-1.0.392.so deleted file mode 100644 index 15e7469e38..0000000000 Binary files a/aws/native-libs/libsqlite4java-linux-i386-1.0.392.so and /dev/null differ diff --git a/aws/native-libs/sqlite4java-win32-x64-1.0.392.dll b/aws/native-libs/sqlite4java-win32-x64-1.0.392.dll deleted file mode 100644 index 70d258f29b..0000000000 Binary files a/aws/native-libs/sqlite4java-win32-x64-1.0.392.dll and /dev/null differ diff --git a/aws/native-libs/sqlite4java-win32-x86-1.0.392.dll b/aws/native-libs/sqlite4java-win32-x86-1.0.392.dll deleted file mode 100644 index c988e5a697..0000000000 Binary files a/aws/native-libs/sqlite4java-win32-x86-1.0.392.dll and /dev/null differ diff --git a/core-java-modules/README.md b/core-java-modules/README.md index fa77846b45..d07dff8751 100644 --- a/core-java-modules/README.md +++ b/core-java-modules/README.md @@ -4,6 +4,6 @@ This module contains modules about core Java ## Relevant articles: -- [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms) - [Understanding the NumberFormatException in Java](https://www.baeldung.com/java-number-format-exception) -- [Will an Error Be Caught by Catch Block in Java?](https://www.baeldung.com/java-error-catch) + + diff --git a/core-java-modules/core-java-11-2/README.md b/core-java-modules/core-java-11-2/README.md index 2b0eda8d91..ebd857886d 100644 --- a/core-java-modules/core-java-11-2/README.md +++ b/core-java-modules/core-java-11-2/README.md @@ -11,3 +11,5 @@ This module contains articles about Java 11 core features - [Invoking a SOAP Web Service in Java](https://www.baeldung.com/java-soap-web-service) - [Java HTTPS Client Certificate Authentication](https://www.baeldung.com/java-https-client-certificate-authentication) - [Call Methods at Runtime Using Java Reflection](https://www.baeldung.com/java-method-reflection) +- [Java HttpClient Basic Authentication](https://www.baeldung.com/java-httpclient-basic-auth) +- [Java HttpClient With SSL](https://www.baeldung.com/java-httpclient-ssl) diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpclient/basicauthentication/HttpClientBasicAuthentication.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpclient/basicauthentication/HttpClientBasicAuthentication.java new file mode 100644 index 0000000000..3ade3bd553 --- /dev/null +++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/httpclient/basicauthentication/HttpClientBasicAuthentication.java @@ -0,0 +1,67 @@ +package com.baeldung.httpclient.basicauthentication; + +import java.io.IOException; +import java.net.Authenticator; +import java.net.PasswordAuthentication; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.Base64; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HttpClientBasicAuthentication { + + private static final Logger logger = LoggerFactory.getLogger(HttpClientBasicAuthentication.class); + + public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException { + useClientWithAuthenticator(); + useClientWithHeaders(); + } + + private static void useClientWithAuthenticator() throws URISyntaxException, IOException, InterruptedException { + HttpClient client = HttpClient.newBuilder() + .authenticator(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("postman", "password".toCharArray()); + } + }) + .build(); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(new URI("https://postman-echo.com/basic-auth")) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + + logger.info("Status using authenticator {}", response.statusCode()); + } + + private static void useClientWithHeaders() throws IOException, InterruptedException, URISyntaxException { + HttpClient client = HttpClient.newBuilder() + .build(); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(new URI("https://postman-echo.com/basic-auth")) + .header("Authorization", getBasicAuthenticationHeader("postman", "password")) + .build(); + + HttpResponse response = client.send(request, BodyHandlers.ofString()); + + logger.info("Status using headers: {}", response.statusCode()); + } + + private static final String getBasicAuthenticationHeader(String username, String password) { + String valueToEncode = username + ":" + password; + return "Basic " + Base64.getEncoder() + .encodeToString(valueToEncode.getBytes()); + } + +} diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/httpclient/ssl/HttpClientSSLBypassUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/httpclient/ssl/HttpClientSSLBypassUnitTest.java new file mode 100644 index 0000000000..29c1538c85 --- /dev/null +++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/httpclient/ssl/HttpClientSSLBypassUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.httpclient.ssl; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Properties; + +public class HttpClientSSLBypassUnitTest { + + @Test + public void whenHttpsRequest_thenCorrect() throws IOException, InterruptedException { + final Properties props = System.getProperties(); + props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString()); + + HttpClient httpClient = HttpClient.newBuilder() + .build(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("https://www.testingmcafeesites.com/")) + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.FALSE.toString()); + + Assertions.assertEquals(200, response.statusCode()); + } +} diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/httpclient/ssl/HttpClientSSLUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/httpclient/ssl/HttpClientSSLUnitTest.java new file mode 100644 index 0000000000..8eddd2d329 --- /dev/null +++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/httpclient/ssl/HttpClientSSLUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.httpclient.ssl; + +import org.junit.Test; + +import javax.net.ssl.SSLHandshakeException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +import static org.junit.Assert.assertEquals; + +public class HttpClientSSLUnitTest { + + @Test + public void whenValidHttpsRequest_thenCorrect() throws URISyntaxException, IOException, InterruptedException { + HttpClient httpClient = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(new URI("https://www.google.com/")) + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + assertEquals(200, response.statusCode()); + } + + @Test(expected = SSLHandshakeException.class) + public void whenInvalidHttpsRequest_thenInCorrect() throws IOException, InterruptedException { + HttpClient httpClient = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("https://expired.badssl.com/")) + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + assertEquals(200, response.statusCode()); + } + +} diff --git a/core-java-modules/core-java-9-jigsaw/README.md b/core-java-modules/core-java-9-jigsaw/README.md index b1a401d48c..cfffb86588 100644 --- a/core-java-modules/core-java-9-jigsaw/README.md +++ b/core-java-modules/core-java-9-jigsaw/README.md @@ -7,5 +7,6 @@ This module contains articles about Project Jigsaw and the Java Platform Module - [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity) - [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity) - [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api) +- [Java 9 Illegal Reflective Access Warning](https://www.baeldung.com/java-illegal-reflective-access) diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A01-compile-and-package-baeldung-agent.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A01-compile-and-package-baeldung-agent.sh new file mode 100644 index 0000000000..959fa66ec4 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A01-compile-and-package-baeldung-agent.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR=baeldung-agent + +# compile +mkdir -p out/${DIR} +javac -d out/${DIR} $(find ${DIR} -type f -name "*.java") + +# package +mkdir -p mods +jar --create --file=mods/${DIR}.jar --manifest=${DIR}/manifest.txt -C out/${DIR} . diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A02-compile-and-package-baeldung-reflected.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A02-compile-and-package-baeldung-reflected.sh new file mode 100644 index 0000000000..fa922c54df --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A02-compile-and-package-baeldung-reflected.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR=baeldung-reflected + +# compile +mkdir -p out/${DIR} +javac -d out/${DIR} $(find ${DIR} -type f -name "*.java") + +# package +mkdir -p mods +jar --create --file=mods/${DIR}.jar -C out/${DIR} . diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A03-compile-and-package-baeldung-intermedium.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A03-compile-and-package-baeldung-intermedium.sh new file mode 100644 index 0000000000..af76ff5a2e --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A03-compile-and-package-baeldung-intermedium.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR=baeldung-intermedium + +# compile +mkdir -p out/${DIR} +javac -d out/${DIR} $(find ${DIR} -type f -name "*.java") + +# package +mkdir -p mods +jar --create --file=mods/${DIR}.jar -C out/${DIR} . diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A04-compile-and-package-baeldung-reflecting-named.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A04-compile-and-package-baeldung-reflecting-named.sh new file mode 100644 index 0000000000..f3f91c9f04 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A04-compile-and-package-baeldung-reflecting-named.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR=baeldung-reflecting-named + +# compile +mkdir -p out/${DIR} +javac -d out/${DIR} --module-path mods $(find ${DIR} -type f -name "*.java") + +# package +mkdir -p mods +jar --create --file=mods/${DIR}.jar -C out/${DIR} . diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A05-compile-and-package-baeldung-reflecting-unnamed.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A05-compile-and-package-baeldung-reflecting-unnamed.sh new file mode 100644 index 0000000000..deb0a8aaea --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/A05-compile-and-package-baeldung-reflecting-unnamed.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DIR=baeldung-reflecting-unnamed + +# compile +mkdir -p out/${DIR} +javac -d out/${DIR} $(find ${DIR} -type f -name "*.java") + +# package +mkdir -p mods +jar --create --file=mods/${DIR}.jar -C out/${DIR} . diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B01-runtime-baeldung-reflecting-named-using-add-opens.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B01-runtime-baeldung-reflecting-named-using-add-opens.sh new file mode 100644 index 0000000000..720ad69003 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B01-runtime-baeldung-reflecting-named-using-add-opens.sh @@ -0,0 +1,4 @@ +#!/bin/bash +java --module-path mods \ + --add-opens baeldung.reflected/com.baeldung.reflected.internal=baeldung.reflecting.named \ + --module baeldung.reflecting.named/com.baeldung.reflecting.named.Main diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B02-runtime-baeldung-reflecting-named-using-forward-opens.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B02-runtime-baeldung-reflecting-named-using-forward-opens.sh new file mode 100644 index 0000000000..9b5f9cb094 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B02-runtime-baeldung-reflecting-named-using-forward-opens.sh @@ -0,0 +1,4 @@ +#!/bin/bash +java --module-path mods \ + --add-opens baeldung.reflected/com.baeldung.reflected.internal=baeldung.intermedium \ + --module baeldung.reflecting.named/com.baeldung.reflecting.named.MainWithForwardOpen diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B03-runtime-baeldung-reflecting-named-using-java-agent.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B03-runtime-baeldung-reflecting-named-using-java-agent.sh new file mode 100644 index 0000000000..cf66dd778f --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B03-runtime-baeldung-reflecting-named-using-java-agent.sh @@ -0,0 +1,4 @@ +#!/bin/bash +java --module-path mods \ + -javaagent:mods/baeldung-agent.jar=com.baeldung.reflected.internal.InternalNonPublicClass,com.baeldung.reflecting.named.Main \ + --module baeldung.reflecting.named/com.baeldung.reflecting.named.Main diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B04-runtime-baeldung-reflecting-unnamed-with-warning.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B04-runtime-baeldung-reflecting-unnamed-with-warning.sh new file mode 100644 index 0000000000..525b8dc58c --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B04-runtime-baeldung-reflecting-unnamed-with-warning.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -cp "mods/*" com.baeldung.reflecting.unnamed.Main diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B05-runtime-baeldung-reflecting-unnamed-using-add-opens.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B05-runtime-baeldung-reflecting-unnamed-using-add-opens.sh new file mode 100644 index 0000000000..f7f5f16237 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B05-runtime-baeldung-reflecting-unnamed-using-add-opens.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -cp "mods/*" --add-opens java.base/java.lang=ALL-UNNAMED com.baeldung.reflecting.unnamed.Main \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B06-runtime-baeldung-reflecting-unnamed-using-java-agent.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B06-runtime-baeldung-reflecting-unnamed-using-java-agent.sh new file mode 100644 index 0000000000..4b30ae1a5c --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/B06-runtime-baeldung-reflecting-unnamed-using-java-agent.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -cp "mods/*" -javaagent:mods/baeldung-agent.jar com.baeldung.reflecting.unnamed.Main diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/C01-clean.sh b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/C01-clean.sh new file mode 100644 index 0000000000..98707f810f --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/C01-clean.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +rm -rf out +rm -rf mods diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/com/baeldung/agent/LoadTimeAgent.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/com/baeldung/agent/LoadTimeAgent.java new file mode 100644 index 0000000000..33d9a231ea --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/com/baeldung/agent/LoadTimeAgent.java @@ -0,0 +1,69 @@ +package com.baeldung.agent; + +import java.lang.instrument.Instrumentation; +import java.util.*; + +public class LoadTimeAgent { + public static void premain(String agentArgs, Instrumentation inst) { + System.out.println("agentArgs: " + agentArgs); + + if (agentArgs != null) { + addExportsAndOpensByClassName(inst, agentArgs); + } + else { + addExportsAndOpensToUnnamedModule(inst); + } + } + + private static void addExportsAndOpensByClassName(Instrumentation inst, String agentArgs) { + String[] array = agentArgs.split(","); + try { + String className1 = array[0]; + String className2 = array[1]; + Class clazz1 = Class.forName(className1); + Class clazz2 = Class.forName(className2); + + Module srcModule = clazz1.getModule(); + Module targetModule = clazz2.getModule(); + redefineModule(inst, srcModule, targetModule); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + private static void addExportsAndOpensToUnnamedModule(Instrumentation inst) { + Module unnamedModule = ClassLoader.getSystemClassLoader().getUnnamedModule(); + Set modules = ModuleLayer.boot().modules(); + + for (Module m : modules) { + redefineModule(inst, m, unnamedModule); + } + } + + private static void redefineModule(Instrumentation inst, Module src, Module target) { + // prepare extra reads + Set extraReads = Collections.singleton(target); + + // prepare extra exports + Set packages = src.getPackages(); + Map> extraExports = new HashMap<>(); + for (String pkg : packages) { + extraExports.put(pkg, extraReads); + } + + // prepare extra opens + Map> extraOpens = new HashMap<>(); + for (String pkg : packages) { + extraOpens.put(pkg, extraReads); + } + + // prepare extra uses + Set> extraUses = Collections.emptySet(); + + // prepare extra provides + Map, List>> extraProvides = Collections.emptyMap(); + + // redefine module + inst.redefineModule(src, extraReads, extraExports, extraOpens, extraUses, extraProvides); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/manifest.txt b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/manifest.txt new file mode 100644 index 0000000000..3dc9de7ba5 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/manifest.txt @@ -0,0 +1,3 @@ +Premain-Class: com.baeldung.agent.LoadTimeAgent +Can-Redefine-Classes: true +Can-Retransform-Classes: true diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/module-info.java new file mode 100644 index 0000000000..c976de2881 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-agent/module-info.java @@ -0,0 +1,3 @@ +module baeldung.agent { + requires java.instrument; +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-intermedium/com/baeldung/intermedium/ForwardOpen.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-intermedium/com/baeldung/intermedium/ForwardOpen.java new file mode 100644 index 0000000000..db031e2cfc --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-intermedium/com/baeldung/intermedium/ForwardOpen.java @@ -0,0 +1,15 @@ +package com.baeldung.intermedium; + +public class ForwardOpen { + public static void addOpens(Class clazz1, Class clazz2) { + Module currentModule = ForwardOpen.class.getModule(); + Module srcModule = clazz1.getModule(); + Module targetModule = clazz2.getModule(); + + System.out.println("current module: " + currentModule.getName()); + System.out.println("source module: " + srcModule.getName()); + System.out.println("target module: " + targetModule.getName()); + + srcModule.addOpens(clazz1.getPackageName(), targetModule); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-intermedium/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-intermedium/module-info.java new file mode 100644 index 0000000000..9ca6cbce43 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-intermedium/module-info.java @@ -0,0 +1,3 @@ +module baeldung.intermedium { + exports com.baeldung.intermedium; +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/exported/ExportedNonPublicClass.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/exported/ExportedNonPublicClass.java new file mode 100644 index 0000000000..c95e17ec1f --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/exported/ExportedNonPublicClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflected.exported; + +class ExportedNonPublicClass { + public static void testPublicStaticMethod() { + System.out.println("ExportedNonPublicClass.testPublicStaticMethod()"); + } + + private static void testPrivateStaticMethod() { + System.out.println("ExportedNonPublicClass.testPrivateStaticMethod()"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/exported/ExportedPublicClass.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/exported/ExportedPublicClass.java new file mode 100644 index 0000000000..3bbfca209c --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/exported/ExportedPublicClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflected.exported; + +public class ExportedPublicClass { + public static void testPublicStaticMethod() { + System.out.println("ExportedPublicClass.testPublicStaticMethod()"); + } + + private static void testPrivateStaticMethod() { + System.out.println("ExportedPublicClass.testPrivateStaticMethod()"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/internal/InternalNonPublicClass.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/internal/InternalNonPublicClass.java new file mode 100644 index 0000000000..052ecbea9e --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/internal/InternalNonPublicClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflected.internal; + +class InternalNonPublicClass { + public static void testPublicStaticMethod() { + System.out.println("InternalNonPublicClass.testPublicStaticMethod()"); + } + + private static void testPrivateStaticMethod() { + System.out.println("InternalNonPublicClass.testPrivateStaticMethod()"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/internal/InternalPublicClass.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/internal/InternalPublicClass.java new file mode 100644 index 0000000000..8f7a20698f --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/internal/InternalPublicClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflected.internal; + +public class InternalPublicClass { + public static void testPublicStaticMethod() { + System.out.println("InternalPublicClass.testPublicStaticMethod()"); + } + + private static void testPrivateStaticMethod() { + System.out.println("InternalPublicClass.testPrivateStaticMethod()"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/opened/OpenedNonPublicClass.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/opened/OpenedNonPublicClass.java new file mode 100644 index 0000000000..99f9850cc1 --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/opened/OpenedNonPublicClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflected.opened; + +class OpenedNonPublicClass { + public static void testPublicStaticMethod() { + System.out.println("OpenedNonPublicClass.testPublicStaticMethod()"); + } + + private static void testPrivateStaticMethod() { + System.out.println("OpenedNonPublicClass.testPrivateStaticMethod()"); + } +} diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/opened/OpenedPublicClass.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/opened/OpenedPublicClass.java new file mode 100644 index 0000000000..f9a56ca26b --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/com/baeldung/reflected/opened/OpenedPublicClass.java @@ -0,0 +1,11 @@ +package com.baeldung.reflected.opened; + +public class OpenedPublicClass { + public static void testPublicStaticMethod() { + System.out.println("OpenedPublicClass.testPublicStaticMethod()"); + } + + private static void testPrivateStaticMethod() { + System.out.println("OpenedPublicClass.testPrivateStaticMethod()"); + } +} diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/module-info.java new file mode 100644 index 0000000000..e2164415cf --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflected/module-info.java @@ -0,0 +1,4 @@ +module baeldung.reflected { + exports com.baeldung.reflected.exported; + opens com.baeldung.reflected.opened; +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/com/baeldung/reflecting/named/Main.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/com/baeldung/reflecting/named/Main.java new file mode 100644 index 0000000000..c0fa4010ab --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/com/baeldung/reflecting/named/Main.java @@ -0,0 +1,12 @@ +package com.baeldung.reflecting.named; + +import java.lang.reflect.Method; + +public class Main { + public static void main(String[] args) throws Exception { + Class clazz = Class.forName("com.baeldung.reflected.internal.InternalNonPublicClass"); + Method method = clazz.getDeclaredMethod("testPrivateStaticMethod"); + method.setAccessible(true); + method.invoke(null); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/com/baeldung/reflecting/named/MainWithForwardOpen.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/com/baeldung/reflecting/named/MainWithForwardOpen.java new file mode 100644 index 0000000000..fad8a9ddce --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/com/baeldung/reflecting/named/MainWithForwardOpen.java @@ -0,0 +1,18 @@ +package com.baeldung.reflecting.named; + +import com.baeldung.intermedium.ForwardOpen; + +import java.lang.reflect.Method; + +public class MainWithForwardOpen { + public static void main(String[] args) throws Exception { + Class currentClass = Main.class; + Class clazz = Class.forName("com.baeldung.reflected.internal.InternalNonPublicClass"); + + ForwardOpen.addOpens(clazz, currentClass); + + Method method = clazz.getDeclaredMethod("testPrivateStaticMethod"); + method.setAccessible(true); + method.invoke(null); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/module-info.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/module-info.java new file mode 100644 index 0000000000..936f53cd6e --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-named/module-info.java @@ -0,0 +1,4 @@ +module baeldung.reflecting.named { + requires baeldung.intermedium; + requires baeldung.reflected; +} \ No newline at end of file diff --git a/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-unnamed/com/baeldung/reflecting/unnamed/Main.java b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-unnamed/com/baeldung/reflecting/unnamed/Main.java new file mode 100644 index 0000000000..37bdc57eaf --- /dev/null +++ b/core-java-modules/core-java-9-jigsaw/src/modules/com.baeldung.reflective.access/baeldung-reflecting-unnamed/com/baeldung/reflecting/unnamed/Main.java @@ -0,0 +1,13 @@ +package com.baeldung.reflecting.unnamed; + +import java.lang.reflect.Field; + +public class Main { + public static void main(String[] args) throws Exception { + Class clazz = StringBuilder.class; + Field f = clazz.getDeclaredField("serialVersionUID"); + f.setAccessible(true); + Object value = f.get(null); + System.out.println(value); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-9/README.md b/core-java-modules/core-java-9/README.md index 8203755417..0fe2b857a4 100644 --- a/core-java-modules/core-java-9/README.md +++ b/core-java-modules/core-java-9/README.md @@ -11,3 +11,4 @@ This module contains articles about Java 9 core features - [Immutable ArrayList in Java](https://www.baeldung.com/java-immutable-list) - [Easy Ways to Write a Java InputStream to an OutputStream](https://www.baeldung.com/java-inputstream-to-outputstream) - [Private Methods in Java Interfaces](https://www.baeldung.com/java-interface-private-methods) +- [Java Scanner useDelimiter with Examples](https://www.baeldung.com/java-scanner-usedelimiter) diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/delimiters/DelimiterDemo.java b/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/delimiters/DelimiterDemo.java new file mode 100644 index 0000000000..edc0b91d02 --- /dev/null +++ b/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/delimiters/DelimiterDemo.java @@ -0,0 +1,36 @@ +package com.baeldung.java9.delimiters; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.regex.Pattern; + +public class DelimiterDemo { + + public static List scannerWithDelimiter(String input, String delimiter) { + try (Scanner scan = new Scanner(input)) { + scan.useDelimiter(delimiter); + List result = new ArrayList(); + scan.forEachRemaining(result::add); + return result; + } + } + + public static List scannerWithDelimiterUsingPattern(String input, Pattern delimiter) { + try (Scanner scan = new Scanner(input)) { + scan.useDelimiter(delimiter); + List result = new ArrayList(); + scan.forEachRemaining(result::add); + return result; + } + } + + public static List baseScanner(String input) { + try (Scanner scan = new Scanner(input)) { + List result = new ArrayList(); + scan.forEachRemaining(result::add); + return result; + } + } + +} diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/delimiters/DelimiterDemoUnitTest.java b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/delimiters/DelimiterDemoUnitTest.java new file mode 100644 index 0000000000..1c1fffe362 --- /dev/null +++ b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/delimiters/DelimiterDemoUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.java9.delimiters; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +class DelimiterDemoUnitTest { + + @Test + void givenSimpleCharacterDelimiter_whenScannerWithDelimiter_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiter, "Welcome to Baeldung", "\\s", Arrays.asList("Welcome", "to", "Baeldung")); + } + + @Test + void givenStringDelimiter_whenScannerWithDelimiter_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiter, "HelloBaeldungHelloWorld", "Hello", Arrays.asList("Baeldung", "World")); + } + + @Test + void givenVariousPossibleDelimiters_whenScannerWithDelimiter_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiter, "Welcome to Baeldung.\nThank you for reading.\nThe team", "\n|\\s", Arrays.asList("Welcome", "to", "Baeldung.", "Thank", "you", "for", "reading.", "The", "team")); + } + + @Test + void givenWildcardRegexDelimiter_whenScannerWithDelimiter_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiter, "1aaaaaaa2aa3aaa4", "a+", Arrays.asList("1", "2", "3", "4")); + } + + @Test + void givenSimpleCharacterDelimiter_whenScannerWithDelimiterUsingPattern_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiterUsingPattern, "Welcome to Baeldung", Pattern.compile("\\s"), Arrays.asList("Welcome", "to", "Baeldung")); + } + + @Test + void givenStringDelimiter_whenScannerWithDelimiterUsingPattern_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiterUsingPattern, "HelloBaeldungHelloWorld", Pattern.compile("Hello"), Arrays.asList("Baeldung", "World")); + } + + @Test + void givenVariousPossibleDelimiters_whenScannerWithDelimiterUsingPattern_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiterUsingPattern, "Welcome to Baeldung.\nThank you for reading.\nThe team", Pattern.compile("\n|\\s"), Arrays.asList("Welcome", "to", "Baeldung.", "Thank", "you", "for", "reading.", "The", "team")); + } + + @Test + void givenWildcardRegexDelimiters_whenScannerWithDelimiterUsingPattern_ThenInputIsCorrectlyParsed() { + checkOutput(DelimiterDemo::scannerWithDelimiterUsingPattern, "1aaaaaaa2aa3aaa4", Pattern.compile("a*"), Arrays.asList("1", "2", "3", "4")); + } + + void checkOutput(BiFunction> function, String input, String delimiter, List expectedOutput) { + assertEquals(expectedOutput, function.apply(input, delimiter)); + } + + void checkOutput(BiFunction> function, String input, Pattern delimiter, List expectedOutput) { + assertEquals(expectedOutput, function.apply(input, delimiter)); + } + + @Test + void whenBaseScanner_ThenWhitespacesAreUsedAsDelimiters() { + assertEquals(List.of("Welcome", "at", "Baeldung"), DelimiterDemo.baseScanner("Welcome at Baeldung")); + } + +} diff --git a/core-java-modules/core-java-collections-2/README.md b/core-java-modules/core-java-collections-2/README.md index e5f6126811..d482ed7773 100644 --- a/core-java-modules/core-java-collections-2/README.md +++ b/core-java-modules/core-java-collections-2/README.md @@ -12,3 +12,4 @@ - [Sorting in Java](https://www.baeldung.com/java-sorting) - [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size) - [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections) +- [Differences Between Iterator and Iterable and How to Use Them?](https://www.baeldung.com/java-iterator-vs-iterable) diff --git a/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/CustomIterableClient.java b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/CustomIterableClient.java new file mode 100644 index 0000000000..14f7b18014 --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/CustomIterableClient.java @@ -0,0 +1,17 @@ +package com.baeldung.collections.iterable; + +class CustomIterableClient { + + public static void main(String[] args) { + + ShoppingCart shoppingCart = new ShoppingCart<>(); + shoppingCart.add(new Product("Tuna", 42)); + shoppingCart.add(new Product("Eggplant", 65)); + shoppingCart.add(new Product("Salad", 45)); + shoppingCart.add(new Product("Banana", 29)); + + for (Product product : shoppingCart) { + System.out.println(product.getName()); + } + } +} diff --git a/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/IterableExample.java b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/IterableExample.java new file mode 100644 index 0000000000..9110d6a15f --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/IterableExample.java @@ -0,0 +1,32 @@ +package com.baeldung.collections.iterable; + +import java.util.Iterator; +import java.util.List; + +public class IterableExample { + + public void iterateUsingIterator(List numbers) { + Iterator iterator = numbers.iterator(); + while (iterator.hasNext()) { + System.out.println(iterator.next()); + } + } + + public void iterateUsingEnhancedForLoop(List numbers) { + for (Integer number : numbers) { + System.out.println(number); + } + } + + public void iterateUsingForEachLoop(List numbers) { + numbers.forEach(System.out::println); + } + + public void removeElementsUsingIterator(List numbers) { + Iterator iterator = numbers.iterator(); + while (iterator.hasNext()) { + iterator.next(); + iterator.remove(); + } + } +} diff --git a/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/Product.java b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/Product.java new file mode 100644 index 0000000000..b29088f6f0 --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/Product.java @@ -0,0 +1,28 @@ +package com.baeldung.collections.iterable; + +class Product { + + private String name; + private double price; + + public Product(String code, double price) { + this.name = code; + this.price = price; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } +} diff --git a/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/ShoppingCart.java b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/ShoppingCart.java new file mode 100644 index 0000000000..f1b481da08 --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterable/ShoppingCart.java @@ -0,0 +1,72 @@ +package com.baeldung.collections.iterable; + +import java.util.Arrays; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class ShoppingCart implements Iterable { + + private E[] elementData; + private int size; + + public ShoppingCart() { + this.elementData = (E[]) new Object[]{}; + } + + public void add(E element) { + ensureCapacity(size + 1); + elementData[size++] = element; + } + + private void ensureCapacity(int minCapacity) { + int oldCapacity = elementData.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity - minCapacity < 0) { + newCapacity = minCapacity; + } + elementData = Arrays.copyOf(elementData, newCapacity); + } + + @Override + public Iterator iterator() { + return new ShoppingCartIterator(); + } + + public class ShoppingCartIterator implements Iterator { + int cursor; + int lastReturned = -1; + + public boolean hasNext() { + return cursor != size; + } + + public E next() { + return getNextElement(); + } + + private E getNextElement() { + int current = cursor; + exist(current); + + E[] elements = ShoppingCart.this.elementData; + validate(elements, current); + + cursor = current + 1; + lastReturned = current; + return elements[lastReturned]; + } + + private void exist(int current) { + if (current >= size) { + throw new NoSuchElementException(); + } + } + + private void validate(E[] elements, int current) { + if (current >= elements.length) { + throw new ConcurrentModificationException(); + } + } + } +} diff --git a/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterator/CustomIteratorClient.java b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterator/CustomIteratorClient.java new file mode 100644 index 0000000000..30c8f57c0b --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterator/CustomIteratorClient.java @@ -0,0 +1,14 @@ +package com.baeldung.collections.iterator; + +import java.util.Iterator; + +class CustomIteratorClient { + + public static void main(String[] args) { + Iterator iterator = Numbers.iterator(); + + while (iterator.hasNext()) { + System.out.println(iterator.next()); + } + } +} diff --git a/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterator/Numbers.java b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterator/Numbers.java new file mode 100644 index 0000000000..23b3344c08 --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/main/java/com/baeldung/collections/iterator/Numbers.java @@ -0,0 +1,60 @@ +package com.baeldung.collections.iterator; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +class Numbers { + + private static final List NUMBER_LIST = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + private Numbers() { + } + + public static Iterator iterator() { + return new PrimeIterator(); + } + + private static class PrimeIterator implements Iterator { + + private int cursor; + + @Override + public Integer next() { + exist(cursor); + return NUMBER_LIST.get(cursor++); + } + + private void exist(int current) { + if (current >= NUMBER_LIST.size()) { + throw new NoSuchElementException(); + } + } + + @Override + public boolean hasNext() { + if (cursor > NUMBER_LIST.size()) { + return false; + } + + for (int i = cursor; i < NUMBER_LIST.size(); i++) { + if (isPrime(NUMBER_LIST.get(i))) { + cursor = i; + return true; + } + } + + return false; + } + + private boolean isPrime(int number) { + for (int i = 2; i <= number / 2; ++i) { + if (number % i == 0) { + return false; + } + } + return true; + } + } +} diff --git a/core-java-modules/core-java-collections-2/src/test/java/com/baeldung/collections/iterable/IterableUnitTest.java b/core-java-modules/core-java-collections-2/src/test/java/com/baeldung/collections/iterable/IterableUnitTest.java new file mode 100644 index 0000000000..745dcf52b7 --- /dev/null +++ b/core-java-modules/core-java-collections-2/src/test/java/com/baeldung/collections/iterable/IterableUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.collections.iterable; + +import com.baeldung.collections.iterable.IterableExample; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class IterableUnitTest { + + private static List getNumbers() { + List numbers = new ArrayList<>(); + numbers.add(10); + numbers.add(20); + numbers.add(30); + numbers.add(40); + return numbers; + } + + @Test + void givenNumbers_whenUsingIterator_thenCorrectSize() { + List numbers = getNumbers(); + IterableExample iterableExample = new IterableExample(); + iterableExample.iterateUsingIterator(numbers); + assertEquals(4, numbers.size()); + } + + @Test + void givenNumbers_whenRemoveElements_thenEmptyList() { + List numbers = getNumbers(); + IterableExample iterableExample = new IterableExample(); + iterableExample.removeElementsUsingIterator(numbers); + assertEquals(0, numbers.size()); + } + + @Test + void givenNumbers_whenIterateUsingEnhancedForLoop_thenCorrectSize() { + List numbers = getNumbers(); + IterableExample iterableExample = new IterableExample(); + iterableExample.iterateUsingEnhancedForLoop(numbers); + assertEquals(4, numbers.size()); + } + + @Test + void givenNumbers_whenIterateUsingForEachLoop_thenCorrectSize() { + List numbers = getNumbers(); + IterableExample iterableExample = new IterableExample(); + iterableExample.iterateUsingForEachLoop(numbers); + assertEquals(4, numbers.size()); + } +} diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml index 2193b5118a..8060e4f606 100644 --- a/core-java-modules/core-java-collections-4/pom.xml +++ b/core-java-modules/core-java-collections-4/pom.xml @@ -14,4 +14,15 @@ 0.0.1-SNAPSHOT + + + commons-lang + commons-lang + ${commons-lang.version} + + + + + 2.2 + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/sorting/Employee.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/sorting/Employee.java new file mode 100644 index 0000000000..a9e7bc8a38 --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/sorting/Employee.java @@ -0,0 +1,51 @@ +package com.baeldung.collections.sorting; + +import java.util.Date; + +public class Employee implements Comparable{ + + private String name; + private Date joiningDate; + + public Employee(String name, Date joiningDate) { + this.name = name; + this.joiningDate = joiningDate; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getJoiningDate() { + return joiningDate; + } + + public void setJoiningDate(Date joiningDate) { + this.joiningDate = joiningDate; + } + + @Override + public boolean equals(Object obj) { + return ((Employee) obj).getName() + .equals(getName()); + } + + @Override + public String toString() { + return new StringBuffer().append("(") + .append(getName()) + .append(",") + .append(getJoiningDate()) + .append(")") + .toString(); + } + + @Override + public int compareTo(Employee employee) { + return getJoiningDate().compareTo(employee.getJoiningDate()); + } +} diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/sorting/EmployeeSortingByDateUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/sorting/EmployeeSortingByDateUnitTest.java new file mode 100644 index 0000000000..250fb7b62b --- /dev/null +++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/sorting/EmployeeSortingByDateUnitTest.java @@ -0,0 +1,145 @@ +package com.baeldung.collections.sorting; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import org.apache.commons.lang.time.DateUtils; +import org.junit.Before; +import org.junit.Test; + +public class EmployeeSortingByDateUnitTest { + + private List employees = new ArrayList<>(); + private List employeesSortedByDateAsc = new ArrayList<>(); + private List employeesSortedByDateDesc = new ArrayList<>(); + + @Before + public void initVariables() { + + Collections.addAll(employees, + new Employee("Earl", DateUtils.addMonths(new Date(), -2)), + new Employee("Frank", DateUtils.addDays(new Date(), -20)), + new Employee("Steve", DateUtils.addDays(new Date(), -10)), + new Employee("Jessica", DateUtils.addMonths(new Date(), -6)), + new Employee("Pearl", DateUtils.addYears(new Date(), -1)), + new Employee("John", new Date()) + ); + + Collections.addAll(employeesSortedByDateDesc, + new Employee("John", new Date()), + new Employee("Steve", DateUtils.addDays(new Date(), -10)), + new Employee("Frank", DateUtils.addDays(new Date(), -20)), + new Employee("Earl", DateUtils.addMonths(new Date(), -2)), + new Employee("Jessica", DateUtils.addMonths(new Date(), -6)), + new Employee("Pearl", DateUtils.addYears(new Date(), -1)) + ); + + Collections.addAll(employeesSortedByDateAsc, + new Employee("Pearl", DateUtils.addYears(new Date(), -1)), + new Employee("Jessica", DateUtils.addMonths(new Date(), -6)), + new Employee("Earl", DateUtils.addMonths(new Date(), -2)), + new Employee("Frank", DateUtils.addDays(new Date(), -20)), + new Employee("Steve", DateUtils.addDays(new Date(), -10)), + new Employee("John", new Date()) + ); + } + + @Test + public void givenEmpList_SortEmpList_thenSortedListinNaturalOrder() { + Collections.sort(employees); + System.out.println(employees); + + assertEquals(employees, employeesSortedByDateAsc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedList() { + + Collections.sort(employees, new Comparator() { + public int compare(Employee o1, Employee o2) { + return o1.getJoiningDate().compareTo(o2.getJoiningDate()); + } + }); + + assertEquals(employees, employeesSortedByDateAsc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedListV1() { + + Collections.sort(employees, new Comparator() { + public int compare(Employee emp1, Employee emp2) { + if (emp1.getJoiningDate() == null || emp2.getJoiningDate() == null) + return 0; + return emp1.getJoiningDate().compareTo(emp2.getJoiningDate()); + } + }); + + assertEquals(employees, employeesSortedByDateAsc); + } + + @Test + public void givenEmpList_SortEmpList_thenSortedListinDescOrder() { + Collections.sort(employees, Collections.reverseOrder()); + + assertEquals(employees, employeesSortedByDateDesc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedListAsc() { + + Collections.sort(employees, new Comparator() { + public int compare(Employee emp1, Employee emp2) { + return emp2.getJoiningDate().compareTo(emp1.getJoiningDate()); + } + }); + + assertEquals(employees, employeesSortedByDateDesc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedListDescV1() { + + Collections.sort(employees, new Comparator() { + public int compare(Employee emp1, Employee emp2) { + return emp2.getJoiningDate().compareTo(emp1.getJoiningDate()); + } + }); + + assertEquals(employees, employeesSortedByDateDesc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedListDescLambda() { + + Collections.sort(employees, + (emp1, emp2) -> emp2.getJoiningDate().compareTo(emp1.getJoiningDate())); + + assertEquals(employees, employeesSortedByDateDesc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedListDescLambdaV1() { + + Collections.sort(employees, (emp1, emp2) -> { + if (emp1.getJoiningDate() == null || emp2.getJoiningDate() == null) + return 0; + return emp2.getJoiningDate().compareTo(emp1.getJoiningDate()); + }); + + assertEquals(employees, employeesSortedByDateDesc); + } + + @Test + public void givenEmpList_SortEmpList_thenCheckSortedListAscLambda() { + Collections.sort(employees, + Comparator.comparing(Employee::getJoiningDate)); + assertEquals(employees, employeesSortedByDateAsc); + } + +} diff --git a/core-java-modules/core-java-collections-list-3/README.md b/core-java-modules/core-java-collections-list-3/README.md index 967e148a99..6d0a3c7037 100644 --- a/core-java-modules/core-java-collections-list-3/README.md +++ b/core-java-modules/core-java-collections-list-3/README.md @@ -11,4 +11,7 @@ This module contains articles about the Java List collection - [Filtering a Java Collection by a List](https://www.baeldung.com/java-filter-collection-by-list) - [How to Count Duplicate Elements in Arraylist](https://www.baeldung.com/java-count-duplicate-elements-arraylist) - [Finding the Differences Between Two Lists in Java](https://www.baeldung.com/java-lists-difference) +- [List vs. ArrayList in Java](https://www.baeldung.com/java-list-vs-arraylist) +- [How to Store HashMap Inside a List](https://www.baeldung.com/java-hashmap-inside-list) +- [Working With a List of Lists in Java](https://www.baeldung.com/java-list-of-lists) - [[<-- Prev]](/core-java-modules/core-java-collections-list-2) diff --git a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/ArrayListDemo.java b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/ArrayListDemo.java new file mode 100644 index 0000000000..f425f19189 --- /dev/null +++ b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/ArrayListDemo.java @@ -0,0 +1,51 @@ +package com.baeldung.list.listvsarraylist; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Locale; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ArrayListDemo { + + private ArrayList passengers = new ArrayList<>(20); +// private LinkedList passengers = new LinkedList<>(); // compile time error + + public ArrayList addPassenger(Passenger passenger) { + passengers.add(passenger); + return passengers; + } + + public ArrayList removePassenger(Passenger passenger) { + passengers.remove(passenger); + return passengers; + } + + public ArrayList getPassengersBySource(String source) { + return new ArrayList(passengers.stream() + .filter(it -> it.getSource().equals(source)) + .collect(Collectors.toList())); + } + + public ArrayList getPassengersByDestination(String destination) { + return new ArrayList (passengers.stream() + .filter(it -> it.getDestination().equals(destination)) + .collect(Collectors.toList())); + } + + public long getKidsCount(ArrayList passengerList) { + return passengerList.stream() + .filter(it -> (it.getAge() <= 10)) + .count(); + } + + public ArrayList getFinalPassengersList() { + return new ArrayList (Collections.unmodifiableList(passengers)); + } + + public ArrayList getServicedCountries() { + return new ArrayList (Stream.of(Locale.getISOCountries()) + .collect(Collectors.toList())); + } + +} diff --git a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/ListDemo.java b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/ListDemo.java new file mode 100644 index 0000000000..a9a182d21e --- /dev/null +++ b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/ListDemo.java @@ -0,0 +1,53 @@ +package com.baeldung.list.listvsarraylist; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ListDemo { + + private List passengers = new ArrayList<>(20); +// private List passengers = new LinkedList<>(); // No compile time error + + public List addPassenger(Passenger passenger) { + passengers.add(passenger); + return passengers; + } + + public List removePassenger(Passenger passenger) { + passengers.remove(passenger); + return passengers; + } + + public List getPassengersBySource(String source) { + return passengers.stream() + .filter(it -> it.getSource().equals(source)) + .collect(Collectors.toList()); + } + + public List getPassengersByDestination(String destination) { + return passengers.stream() + .filter(it -> it.getDestination().equals(destination)) + .collect(Collectors.toList()); + } + + public long getKidsCount(List passengerList) { + return passengerList.stream() + .filter(it -> (it.getAge() <= 10)) + .count(); + } + + public List getFinalPassengersList() { + return Collections.unmodifiableList(passengers); + } + + public List getServicedCountries() { + return Stream.of(Locale.getISOCountries()) + .collect(Collectors.toList()); + } + +} diff --git a/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/Passenger.java b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/Passenger.java new file mode 100644 index 0000000000..9c61b70aa6 --- /dev/null +++ b/core-java-modules/core-java-collections-list-3/src/main/java/com/baeldung/list/listvsarraylist/Passenger.java @@ -0,0 +1,49 @@ +package com.baeldung.list.listvsarraylist; + +public class Passenger { + + private String name; + private int age; + private String source; + private String destination; + + public Passenger(String name, int age, String source, String destination) { + this.name = name; + this.age = age; + this.source = source; + this.destination = destination; + } + + 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 getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getDestination() { + return destination; + } + + public void setDestination(String destination) { + this.destination = destination; + } + +} diff --git a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listOfHashMaps/ListOfHashMapsUnitTest.java b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listOfHashMaps/ListOfHashMapsUnitTest.java new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listvsarraylist/ArrayListDemoUnitTest.java b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listvsarraylist/ArrayListDemoUnitTest.java new file mode 100644 index 0000000000..59094ab562 --- /dev/null +++ b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listvsarraylist/ArrayListDemoUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.list.listvsarraylist; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.Locale; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ArrayListDemoUnitTest { + + ArrayListDemo application = new ArrayListDemo(); + + Passenger passenger1; + Passenger passenger2; + Passenger passenger3; + + @BeforeEach + protected void setUp() { + passenger1 = new Passenger("Anna", 25, "London", "New York"); + passenger2 = new Passenger("Binny", 35, "New York", "London"); + passenger3 = new Passenger("Chandra", 8, "Paris", "New Delhi"); + application.addPassenger(passenger1); + application.addPassenger(passenger2); + application.addPassenger(passenger3); + } + + @Test + public void givenEmptyList_whenAddedPassenger_thenReturnCurrentPassengerList() { + ArrayList list = application.addPassenger(new Passenger("David", 54, "Milan", "Paris")); + + assertNotNull(list); + assertThat(list).hasSize(4); + } + + @Test + public void givenPassengerList_whenRemovedPassenger_thenReturnCurrentPassengerList() { + ArrayList list = application.removePassenger(passenger3); + + assertNotNull(list); + assertThat(list).hasSize(2); + } + + @Test + public void givenPassengerList_whenPassedWithSourceCity_thenReturnMatchingPassengerList() { + ArrayList list = application.getPassengersBySource("Singapore"); + ArrayList list2 = application.getPassengersBySource("London"); + + assertThat(list).isEmpty(); + assertThat(list2.get(0)).isEqualTo(passenger1); + } + + @Test + public void givenPassengerList_whenPassedWithDestinationCity_thenReturnMatchingPassengerList() { + ArrayList list = application.getPassengersByDestination("Singapore"); + ArrayList list2 = application.getPassengersByDestination("London"); + + assertThat(list).isEmpty(); + assertThat(list2.get(0)).isEqualTo(passenger2); + } + + @Test + public void givenPassengerList_whenFindKidsByAge_thenReturnKidsList() { + ArrayList list = new ArrayList<>(); + list.add(passenger1); + list.add(passenger2); + list.add(passenger3); + long count = application.getKidsCount(list); + + assertThat(count).isEqualTo(1); + } + + @Test + public void givenPassengerList_whenCalledWithCollectionsFunction_thenReturnsListType() { + ArrayList list = application.getFinalPassengersList(); + + assertNotNull(list); + assertThat(list).hasSize(3); + } + + @Test + public void givenCurrentLocale_whenUsingStreams_thenReturnsListType() { + ArrayList servicedCountries = application.getServicedCountries(); + + assertNotNull(servicedCountries); + assertThat(servicedCountries).hasSize(Locale.getISOCountries().length); + } + +} diff --git a/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listvsarraylist/ListDemoUnitTest.java b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listvsarraylist/ListDemoUnitTest.java new file mode 100644 index 0000000000..cf239a79ce --- /dev/null +++ b/core-java-modules/core-java-collections-list-3/src/test/java/com/baeldung/list/listvsarraylist/ListDemoUnitTest.java @@ -0,0 +1,92 @@ +package com.baeldung.list.listvsarraylist; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ListDemoUnitTest { + + ListDemo application = new ListDemo(); + + Passenger passenger1; + Passenger passenger2; + Passenger passenger3; + + @BeforeEach + protected void setUp() { + passenger1 = new Passenger("Anna", 25, "London", "New York"); + passenger2 = new Passenger("Binny", 35, "New York", "London"); + passenger3 = new Passenger("Chandra", 8, "Paris", "New Delhi"); + application.addPassenger(passenger1); + application.addPassenger(passenger2); + application.addPassenger(passenger3); + } + + @Test + public void givenEmptyList_whenAddedPassenger_thenReturnCurrentPassengerList() { + List list = application.addPassenger(new Passenger("David", 54, "Milan", "Paris")); + + assertNotNull(list); + assertThat(list).hasSize(4); + } + + @Test + public void givenPresentList_whenRemovedPassenger_thenReturnCurrentPassengerList() { + List list = application.removePassenger(passenger3); + + assertNotNull(list); + assertThat(list).hasSize(2); + } + + @Test + public void givenPresentList_whenPassedWithSourceCity_thenReturnMatchingPassengerList() { + List list = application.getPassengersBySource("Singapore"); + List list2 = application.getPassengersBySource("London"); + + assertThat(list).isEmpty(); + assertThat(list2.get(0)).isEqualTo(passenger1); + } + + @Test + public void givenPresentList_whenPassedWithDestinationCity_thenReturnMatchingPassengerList() { + List list = application.getPassengersByDestination("Singapore"); + List list2 = application.getPassengersByDestination("London"); + + assertThat(list).isEmpty(); + assertThat(list2.get(0)).isEqualTo(passenger2); + } + + @Test + public void givenPassengerList_whenFindKidsByAge_thenReturnKidsList() { + List list = new ArrayList<>(); + list.add(passenger1); + list.add(passenger2); + list.add(passenger3); + long count = application.getKidsCount(list); + + assertThat(count).isEqualTo(1); + } + + @Test + public void givenPresentList_whenCalledWithCollectionsFunction_thenReturnsListType() { + List list = application.getFinalPassengersList(); + + assertNotNull(list); + assertThat(list).hasSize(3); + } + + @Test + public void givenCurrentLocale_whenUsingStreams_thenReturnsListType() { + List servicedCountries = application.getServicedCountries(); + + assertNotNull(servicedCountries); + assertThat(servicedCountries).hasSize(Locale.getISOCountries().length); + } + +} diff --git a/core-java-modules/core-java-collections-list-4/README.md b/core-java-modules/core-java-collections-list-4/README.md new file mode 100644 index 0000000000..3a90b3d813 --- /dev/null +++ b/core-java-modules/core-java-collections-list-4/README.md @@ -0,0 +1,7 @@ +## Core Java Collections List (Part 4) + +This module contains articles about the Java List collection + +### Relevant Articles: +- [Working With a List of Lists in Java](https://www.baeldung.com/java-list-of-lists) +- [[<-- Prev]](/core-java-modules/core-java-collections-list-3) diff --git a/core-java-modules/core-java-collections-list-4/pom.xml b/core-java-modules/core-java-collections-list-4/pom.xml new file mode 100644 index 0000000000..8c1d3a881e --- /dev/null +++ b/core-java-modules/core-java-collections-list-4/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + core-java-collections-list-4 + 0.1.0-SNAPSHOT + core-java-collections-list-4 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + net.sf.trove4j + trove4j + ${trove4j.version} + + + it.unimi.dsi + fastutil + ${fastutil.version} + + + colt + colt + ${colt.version} + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator.version} + + + + + 3.0.2 + 8.1.0 + 1.2.0 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/listoflists/ListOfListsUnitTest.java b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/listoflists/ListOfListsUnitTest.java new file mode 100644 index 0000000000..321fa475f6 --- /dev/null +++ b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/listoflists/ListOfListsUnitTest.java @@ -0,0 +1,74 @@ +package com.baeldung.list.listoflists; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +public class ListOfListsUnitTest { + + private List> getListOfListsFromCsv() throws URISyntaxException, IOException { + + List lines = Files.readAllLines(Paths.get(getClass().getResource("/listoflists/example.csv") + .toURI())); + List> listOfLists = new ArrayList<>(); + + lines.forEach(line -> { + List innerList = new ArrayList<>(Arrays.asList(line.split(", "))); + listOfLists.add(innerList); + }); + return listOfLists; + } + + private void printListOfLists(List> listOfLists) { + System.out.println("\n List of Lists "); + System.out.println("-------------------------------------"); + listOfLists.forEach(innerList -> { + String line = String.join(", ", innerList); + System.out.println(line); + }); + } + + @Test + void givenCsv_whenInitListOfLists_thenGetExpectedResults() throws URISyntaxException, IOException { + List> listOfLists = getListOfListsFromCsv(); + assertThat(listOfLists).hasSize(3); + assertThat(listOfLists.stream() + .map(List::size) + .collect(Collectors.toSet())).hasSize(1) + .containsExactly(4); + printListOfLists(listOfLists); + } + + @Test + void givenListOfLists_whenRemoveElementFromInnerLists_thenGetExpectedResults() throws URISyntaxException, IOException { + List> listOfLists = getListOfListsFromCsv(); + + listOfLists.forEach(innerList -> innerList.remove("Delete Me")); + assertThat(listOfLists.stream() + .map(List::size) + .collect(Collectors.toSet())).hasSize(1) + .containsExactly(3); + + printListOfLists(listOfLists); + } + + @Test + void givenListOfLists_whenAddNewInnerList_thenGetExpectedResults() throws URISyntaxException, IOException { + List> listOfLists = getListOfListsFromCsv(); + List newList = new ArrayList<>(Arrays.asList("Slack", "Zoom", "Microsoft Teams", "Telegram")); + listOfLists.add(2, newList); + + assertThat(listOfLists).hasSize(4); + assertThat(listOfLists.get(2)).containsExactly("Slack", "Zoom", "Microsoft Teams", "Telegram"); + printListOfLists(listOfLists); + } +} diff --git a/core-java-modules/core-java-collections-list-4/src/test/resources/listoflists/example.csv b/core-java-modules/core-java-collections-list-4/src/test/resources/listoflists/example.csv new file mode 100644 index 0000000000..e275848e19 --- /dev/null +++ b/core-java-modules/core-java-collections-list-4/src/test/resources/listoflists/example.csv @@ -0,0 +1,3 @@ +Linux, Microsoft Windows, Mac OS, Delete Me +Kotlin, Delete Me, Java, Python +Delete Me, Mercurial, Git, Subversion \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/list/listOfHashMaps/ListOfHashMapsUnitTest.java b/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/list/listOfHashMaps/ListOfHashMapsUnitTest.java new file mode 100644 index 0000000000..39110aedd3 --- /dev/null +++ b/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/list/listOfHashMaps/ListOfHashMapsUnitTest.java @@ -0,0 +1,36 @@ +package test.java.com.baeldung.list.listOfHashMaps; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertTrue; + +public class ListOfHashMapsUnitTest { + List>> booksAuthorsMapsList = new ArrayList<>(); + + @Test + public void givenMaps_whenAddToList_thenListContainsMaps() { + HashMap> javaBooksAuthorsMap = new HashMap<>(); + HashMap> phpBooksAuthorsMap = new HashMap<>(); + javaBooksAuthorsMap.put("Head First Java", Arrays.asList("Kathy Sierra", "Bert Bates")); + javaBooksAuthorsMap.put("Effective Java", Arrays.asList("Joshua Bloch")); + javaBooksAuthorsMap.put("OCA Java SE 8", + Arrays.asList("Kathy Sierra", "Bert Bates", "Elisabeth Robson")); + phpBooksAuthorsMap.put("The Joy of PHP", Arrays.asList("Alan Forbes")); + phpBooksAuthorsMap.put("Head First PHP & MySQL", + Arrays.asList("Lynn Beighley", "Michael Morrison")); + + booksAuthorsMapsList.add(javaBooksAuthorsMap); + booksAuthorsMapsList.add(phpBooksAuthorsMap); + + assertTrue(booksAuthorsMapsList.get(0).keySet().containsAll + (javaBooksAuthorsMap.keySet().stream().collect(Collectors.toList()))); + assertTrue(booksAuthorsMapsList.get(1).keySet().containsAll + (phpBooksAuthorsMap.keySet().stream().collect(Collectors.toList()))); + } +} 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 808db89b12..d9207644b3 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/README.md +++ b/core-java-modules/core-java-concurrency-advanced-4/README.md @@ -6,3 +6,4 @@ - [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) +- [Differences Between set() and lazySet() in Java Atomic Variables](https://www.baeldung.com/java-atomic-set-vs-lazyset) diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/setvslazyset/Application.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/setvslazyset/Application.java new file mode 100644 index 0000000000..37424147a7 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/setvslazyset/Application.java @@ -0,0 +1,35 @@ +package com.baeldung.setvslazyset; + +import java.util.concurrent.atomic.AtomicInteger; + +public class Application { + + AtomicInteger atomic = new AtomicInteger(0); + + public static void main(String[] args) { + Application app = new Application(); + new Thread(() -> { + for (int i = 0; i < 10; i++) { + //app.atomic.set(i); + app.atomic.lazySet(i); + System.out.println("Set: " + i); + try { + Thread.sleep(100); + } catch (InterruptedException e) {} + } + }).start(); + + new Thread(() -> { + for (int i = 0; i < 10; i++) { + synchronized (app.atomic) { + int counter = app.atomic.get(); + System.out.println("Get: " + counter); + } + try { + Thread.sleep(100); + } catch (InterruptedException e) {} + } + }).start(); + } + +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/FixedTimeTask.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/FixedTimeTask.java new file mode 100644 index 0000000000..9ac20d73dd --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/FixedTimeTask.java @@ -0,0 +1,28 @@ +package com.baeldung.concurrent.stopexecution; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.TimeUnit; + +public class FixedTimeTask implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(FixedTimeTask.class); + + final int fixedTime; // milliseconds + + public FixedTimeTask(int fixedTime) { + this.fixedTime = fixedTime; + } + + @Override + public void run() { + LOG.info(fixedTime + " milliseconds running task"); + try { + TimeUnit.MILLISECONDS.sleep(fixedTime); + } catch (InterruptedException e) { + LOG.info("interrupted"); + } + LOG.info("finished"); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/LongRunningTask.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/LongRunningTask.java new file mode 100644 index 0000000000..7167859308 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/LongRunningTask.java @@ -0,0 +1,21 @@ +package com.baeldung.concurrent.stopexecution; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LongRunningTask implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(LongRunningTask.class); + + @Override + public void run() { + LOG.info("running"); + for (int i = 0; i < Long.MAX_VALUE; i++) { + if (Thread.interrupted()) { + LOG.info("stopping"); + return; + } + } + LOG.info("finished"); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/Step.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/Step.java new file mode 100644 index 0000000000..d6d8c8c036 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/Step.java @@ -0,0 +1,23 @@ +package com.baeldung.concurrent.stopexecution; + +import java.util.Random; + +public class Step { + + private static int MAX = Integer.MAX_VALUE / 2; + int number; + + public Step(int number) { + this.number = number; + } + + public void perform() throws InterruptedException { + Random rnd = new Random(); + int target = rnd.nextInt(MAX); + while (rnd.nextInt(MAX) != target) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/SteppedTask.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/SteppedTask.java new file mode 100644 index 0000000000..5b2b0c445a --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/SteppedTask.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.stopexecution; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class SteppedTask implements Runnable { + private static final Logger LOG = LoggerFactory.getLogger(SteppedTask.class); + + private List steps; + + public SteppedTask(List steps) { + this.steps = steps; + } + + @Override + public void run() { + LOG.info("running stepped process"); + for (Step step : steps) { + LOG.info("running step " + step.number); + try { + step.perform(); + } catch (InterruptedException e) { + LOG.info("interrupting task"); + return; + } + } + LOG.info("stepped process finished"); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/StoppingExecution.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/StoppingExecution.java new file mode 100644 index 0000000000..ac4af8adc4 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/StoppingExecution.java @@ -0,0 +1,95 @@ +package com.baeldung.concurrent.stopexecution; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Timer; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class StoppingExecution { + + private static final Logger LOG = LoggerFactory.getLogger(StoppingExecution.class); + + public static void main(String[] args) { + StoppingExecution.testUsingLoop(); + StoppingExecution.testUsingTimer(); + StoppingExecution.testUsingFuture(); + StoppingExecution.testScheduledExecutor(); + StoppingExecution.testSteppedProcess(); + } + + public static void testUsingLoop() { + LOG.info("using loop started"); + long start = System.currentTimeMillis(); + long end = start + 30 * 1000; // 30 seconds + while (System.currentTimeMillis() < end) { + LOG.info("running task"); + new FixedTimeTask(7 * 1000).run(); // 7 seconds + } + LOG.info("using loop ended"); + } + + public static void testUsingTimer() { + LOG.info("using timer started"); + Thread thread = new Thread(new LongRunningTask()); + thread.start(); + + Timer timer = new Timer(); + TimeOutTask timeOutTask = new TimeOutTask(thread, timer); + + LOG.info("scheduling timeout in 3 seconds"); + timer.schedule(timeOutTask, 3000); + LOG.info("using timer ended"); + } + + public static void testUsingFuture() { + LOG.info("using future started"); + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(new LongRunningTask()); + try { + LOG.info("future get with 7 seconds timeout"); + future.get(7, TimeUnit.SECONDS); + } catch (TimeoutException e) { + LOG.info("future timeout"); + future.cancel(true); + } catch (Exception e) { + LOG.info("future exception", e); + } finally { + executor.shutdownNow(); + } + LOG.info("using future ended"); + } + + public static void testScheduledExecutor() { + LOG.info("using future schedule executor started"); + + ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); + Future future = executor.submit(new LongRunningTask()); + Runnable cancelTask = () -> future.cancel(true); + + LOG.info("cancel task in 3 seconds"); + executor.schedule(cancelTask, 3000, TimeUnit.MILLISECONDS); + executor.shutdown(); + LOG.info("using future schedule executor ended"); + } + + public static void testSteppedProcess() { + List steps = Stream.of(new Step(1), new Step(2), new Step(3), new Step(4)).collect(Collectors.toList()); + + LOG.info("stepped process started"); + Thread thread = new Thread(new SteppedTask(steps)); + thread.start(); + + Timer timer = new Timer(); + TimeOutTask timeOutTask = new TimeOutTask(thread, timer); + timer.schedule(timeOutTask, 10000); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/TimeOutTask.java b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/TimeOutTask.java new file mode 100644 index 0000000000..e27e64476e --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/stopexecution/TimeOutTask.java @@ -0,0 +1,22 @@ +package com.baeldung.concurrent.stopexecution; + +import java.util.Timer; +import java.util.TimerTask; + +public class TimeOutTask extends TimerTask { + private Thread thread; + private Timer timer; + + public TimeOutTask(Thread thread, Timer timer) { + this.thread = thread; + this.timer = timer; + } + + @Override + public void run() { + if (thread != null && thread.isAlive()) { + thread.interrupt(); + timer.cancel(); + } + } +} diff --git a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/FixedTimeTaskUnitTest.java b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/FixedTimeTaskUnitTest.java new file mode 100644 index 0000000000..bbb8d0571a --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/FixedTimeTaskUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.concurrent.stopexecution; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class FixedTimeTaskUnitTest { + + @Test + public void run() throws InterruptedException { + long start = System.currentTimeMillis(); + Thread thread = new Thread(new FixedTimeTask(10)); + thread.start(); + thread.join(); + long end = System.currentTimeMillis(); + assertTrue(end - start >= 10); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/LongRunningTaskUnitTest.java b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/LongRunningTaskUnitTest.java new file mode 100644 index 0000000000..c9bcb75e6d --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/LongRunningTaskUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.concurrent.stopexecution; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class LongRunningTaskUnitTest { + + @Test + public void run() { + Thread thread = new Thread(new LongRunningTask()); + thread.start(); + assertTrue(thread.isAlive()); + + thread.interrupt(); + assertTrue(thread.isInterrupted()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/SteppedTaskUnitTest.java b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/SteppedTaskUnitTest.java new file mode 100644 index 0000000000..ab9ac2732a --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/SteppedTaskUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.concurrent.stopexecution; + +import org.junit.Test; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.*; + +public class SteppedTaskUnitTest { + + @Test + public void run() throws InterruptedException { + List steps = Stream.of( + new Step(1), + new Step(2), + new Step(3)) + .collect(Collectors.toList()); + + Thread thread = new Thread(new SteppedTask(steps)); + thread.start(); + thread.interrupt(); + thread.join(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/TimeOutTaskUnitTest.java b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/TimeOutTaskUnitTest.java new file mode 100644 index 0000000000..39ec9f7d26 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/stopexecution/TimeOutTaskUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.concurrent.stopexecution; + +import org.junit.Test; + +import java.util.Timer; + +import static org.junit.Assert.assertTrue; + +public class TimeOutTaskUnitTest { + + @Test + public void run() { + Thread thread = new Thread(new LongRunningTask()); + Timer timer = new Timer(); + TimeOutTask timeOutTask = new TimeOutTask(thread, timer); + thread.start(); + timeOutTask.run(); + assertTrue(thread.isInterrupted()); + } +} \ No newline at end of file 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 9afb6e8db0..91cd29cd54 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 @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import java.text.SimpleDateFormat; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -15,7 +16,7 @@ public class SubtractDaysFromDateUnitTest { @Test public void givenLocalDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() { - LocalDate localDateTime = LocalDate.of(2022, 4, 20); + LocalDateTime localDateTime = LocalDateTime.of(2022, 4, 20, 0, 0); localDateTime = localDateTime.minusDays(5); diff --git a/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java b/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java index b0243ae48f..629f15b2dd 100644 --- a/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java +++ b/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java @@ -7,7 +7,7 @@ import java.util.regex.Pattern; public class February29thMatcher implements DateMatcher { private static final Pattern DATE_PATTERN = Pattern.compile( - "^((2000|2400|2800|(19|2[0-9](0[48]|[2468][048]|[13579][26])))-02-29)$"); + "^((2000|2400|2800|(19|2[0-9])(0[48]|[2468][048]|[13579][26]))-02-29)$"); @Override public boolean matches(String date) { diff --git a/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java b/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java index fc8abdb201..13be452910 100644 --- a/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java +++ b/core-java-modules/core-java-datetime-string/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java @@ -7,7 +7,7 @@ import java.util.regex.Pattern; class GregorianDateMatcher implements DateMatcher { private static final Pattern DATE_PATTERN = Pattern.compile( - "^((2000|2400|2800|(19|2[0-9](0[48]|[2468][048]|[13579][26])))-02-29)$" + "^((2000|2400|2800|(19|2[0-9])(0[48]|[2468][048]|[13579][26]))-02-29)$" + "|^(((19|2[0-9])[0-9]{2})-02-(0[1-9]|1[0-9]|2[0-8]))$" + "|^(((19|2[0-9])[0-9]{2})-(0[13578]|10|12)-(0[1-9]|[12][0-9]|3[01]))$" + "|^(((19|2[0-9])[0-9]{2})-(0[469]|11)-(0[1-9]|[12][0-9]|30))$"); diff --git a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java index 6429e4fe2d..b7fb267077 100644 --- a/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java +++ b/core-java-modules/core-java-datetime-string/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java @@ -37,6 +37,8 @@ public class GregorianDateTestHelper { } public void assertFebruary29th() { + Assert.assertTrue(matcher.matches("1904-02-29")); + Assert.assertTrue(matcher.matches("1996-02-29")); Assert.assertTrue(matcher.matches("2000-02-29")); Assert.assertTrue(matcher.matches("2400-02-29")); Assert.assertTrue(matcher.matches("2800-02-29")); @@ -44,6 +46,8 @@ public class GregorianDateTestHelper { Assert.assertTrue(matcher.matches("2024-02-29")); Assert.assertTrue(matcher.matches("2028-02-29")); + Assert.assertFalse(matcher.matches("1900-02-29")); + Assert.assertFalse(matcher.matches("1999-02-29")); Assert.assertFalse(matcher.matches("2017-02-29")); Assert.assertFalse(matcher.matches("2018-02-29")); Assert.assertFalse(matcher.matches("2019-02-29")); diff --git a/core-java-modules/core-java-exceptions-3/pom.xml b/core-java-modules/core-java-exceptions-3/pom.xml index 455f769757..7eaa57edf1 100644 --- a/core-java-modules/core-java-exceptions-3/pom.xml +++ b/core-java-modules/core-java-exceptions-3/pom.xml @@ -32,8 +32,8 @@ 3.8.1 - - + + diff --git a/core-java-modules/core-java-exceptions-4/pom.xml b/core-java-modules/core-java-exceptions-4/pom.xml index cc81fdc40b..e9a2d05180 100644 --- a/core-java-modules/core-java-exceptions-4/pom.xml +++ b/core-java-modules/core-java-exceptions-4/pom.xml @@ -32,8 +32,8 @@ 3.8.1 - - + + diff --git a/core-java-modules/core-java-exceptions/README.md b/core-java-modules/core-java-exceptions/README.md index 5f47aa69fb..b74ede51e8 100644 --- a/core-java-modules/core-java-exceptions/README.md +++ b/core-java-modules/core-java-exceptions/README.md @@ -13,4 +13,5 @@ This module contains articles about core java exceptions - [The StackOverflowError in Java](https://www.baeldung.com/java-stack-overflow-error) - [Checked and Unchecked Exceptions in Java](https://www.baeldung.com/java-checked-unchecked-exceptions) - [Common Java Exceptions](https://www.baeldung.com/java-common-exceptions) +- [Will an Error Be Caught by Catch Block in Java?](https://www.baeldung.com/java-error-catch) - [[Next -->]](/core-java-modules/core-java-exceptions-2) \ No newline at end of file diff --git a/core-java-modules/core-java-httpclient/README.md b/core-java-modules/core-java-httpclient/README.md new file mode 100644 index 0000000000..712328a123 --- /dev/null +++ b/core-java-modules/core-java-httpclient/README.md @@ -0,0 +1,6 @@ +## Java HttpClient + +This module contains articles about Java HttpClient + +### Relevant articles +- [Posting with Java HttpClient](https://www.baeldung.com/java-httpclient-post) diff --git a/core-java-modules/core-java-httpclient/pom.xml b/core-java-modules/core-java-httpclient/pom.xml new file mode 100644 index 0000000000..57b23e96c1 --- /dev/null +++ b/core-java-modules/core-java-httpclient/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + core-java-httpclient + 0.1.0-SNAPSHOT + core-java-httpclient + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../pom.xml + + + + + org.mock-server + mockserver-netty + ${mockserver.version} + + + org.mock-server + mockserver-client-java + ${mockserver.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source.version} + ${maven.compiler.target.version} + + + + + + + 11 + 11 + 3.22.0 + 5.11.2 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientHeader.java b/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientHeader.java new file mode 100644 index 0000000000..43e6587ed4 --- /dev/null +++ b/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientHeader.java @@ -0,0 +1,46 @@ +package com.baeldung.httpclient; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +public class HttpClientHeader { + + public static HttpResponse callWithCustomHeader(String url) throws URISyntaxException, IOException, InterruptedException { + HttpClient httpClient = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .header("X-Our-Header-1", "value1") + .header("X-Our-Header-1", "value2") + .header("X-Our-Header-2", "value2") + .uri(new URI(url)).build(); + + return httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + } + + public static HttpResponse callWithCustomHeaderV2(String url) throws URISyntaxException, IOException, InterruptedException { + HttpClient httpClient = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .headers("X-Our-Header-1", "value1", "X-Our-Header-1", "value2") + .uri(new URI(url)).build(); + + return httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + } + + public static HttpResponse callWithCustomHeaderV3(String url) throws URISyntaxException, IOException, InterruptedException { + HttpClient httpClient = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .setHeader("X-Our-Header-1", "value1") + .setHeader("X-Our-Header-1", "value2") + .uri(new URI(url)).build(); + + return httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + } + + +} diff --git a/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientPost.java b/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientPost.java new file mode 100644 index 0000000000..d08a7bf183 --- /dev/null +++ b/core-java-modules/core-java-httpclient/src/main/java/com/baeldung/httpclient/HttpClientPost.java @@ -0,0 +1,162 @@ +package com.baeldung.httpclient; + +import java.io.IOException; +import java.net.Authenticator; +import java.net.PasswordAuthentication; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +public class HttpClientPost { + + public static HttpResponse sendSynchronousPost(String serviceUrl) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.noBody()) + .build(); + + HttpResponse response = client + .send(request, HttpResponse.BodyHandlers.ofString()); + + return response; + } + + public static CompletableFuture> sendAsynchronousPost(String serviceUrl) { + HttpClient client = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.noBody()) + .build(); + + CompletableFuture> futureResponse = client + .sendAsync(request, HttpResponse.BodyHandlers.ofString()); + + return futureResponse; + } + + public static List>> sendConcurrentPost(List serviceUrls) { + HttpClient client = HttpClient.newHttpClient(); + + List>> completableFutures = serviceUrls.stream() + .map(URI::create) + .map(HttpRequest::newBuilder) + .map(builder -> builder.POST(HttpRequest.BodyPublishers.noBody())) + .map(HttpRequest.Builder::build) + .map(request -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString())) + .collect(Collectors.toList()); + + return completableFutures; + } + + public static HttpResponse sendPostWithAuthHeader(String serviceUrl) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.noBody()) + .header("Authorization", "Basic " + Base64.getEncoder() + .encodeToString(("baeldung:123456").getBytes())) + .build(); + + HttpResponse response = client + .send(request, HttpResponse.BodyHandlers.ofString()); + + return response; + } + + public static HttpResponse sendPostWithAuthClient(String serviceUrl) throws IOException, InterruptedException { + HttpClient client = HttpClient.newBuilder() + .authenticator(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication( + "baeldung", + "123456".toCharArray()); + } + }) + .build(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.noBody()) + .build(); + + HttpResponse response = client + .send(request, HttpResponse.BodyHandlers.ofString()); + + return response; + } + + public static HttpResponse sendPostWithJsonBody(String serviceUrl) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.ofString("{\"action\":\"hello\"}")) + .build(); + + HttpResponse response = client + .send(request, HttpResponse.BodyHandlers.ofString()); + + return response; + } + + public static HttpResponse sendPostWithFormData(String serviceUrl) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + Map formData = new HashMap<>(); + formData.put("username", "baeldung"); + formData.put("message", "hello"); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.ofString(getFormDataAsString(formData))) + .build(); + + HttpResponse response = client + .send(request, HttpResponse.BodyHandlers.ofString()); + + return response; + } + + public static HttpResponse sendPostWithFileData(String serviceUrl, Path file) throws IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(serviceUrl)) + .POST(HttpRequest.BodyPublishers.ofFile(file)) + .build(); + + HttpResponse response = client + .send(request, HttpResponse.BodyHandlers.ofString()); + + return response; + } + + private static String getFormDataAsString(Map formData) { + StringBuilder formBodyBuilder = new StringBuilder(); + for (Map.Entry singleEntry : formData.entrySet()) { + if (formBodyBuilder.length() > 0) { + formBodyBuilder.append("&"); + } + formBodyBuilder.append(URLEncoder.encode(singleEntry.getKey(), StandardCharsets.UTF_8)); + formBodyBuilder.append("="); + formBodyBuilder.append(URLEncoder.encode(singleEntry.getValue(), StandardCharsets.UTF_8)); + } + return formBodyBuilder.toString(); + } + +} diff --git a/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/HttpClientPostUnitTest.java b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/HttpClientPostUnitTest.java new file mode 100644 index 0000000000..b43cf08649 --- /dev/null +++ b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/HttpClientPostUnitTest.java @@ -0,0 +1,99 @@ +package com.baeldung.httpclient; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.*; + +class HttpClientPostUnitTest extends PostRequestMockServer { + + @Test + void givenSyncPostRequest_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException { + HttpResponse response = HttpClientPost.sendSynchronousPost(serviceUrl); + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + + @Test + void givenAsyncPostRequest_whenServerIsAvailable_thenOkStatusIsReceived() throws ExecutionException, InterruptedException { + CompletableFuture> futureResponse = HttpClientPost.sendAsynchronousPost(serviceUrl); + HttpResponse response = futureResponse.get(); + + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + + @Test + void givenConcurrentPostRequests_whenServerIsAvailable_thenOkStatusIsReceived() throws ExecutionException, InterruptedException { + List>> completableFutures = HttpClientPost + .sendConcurrentPost(List.of(serviceUrl, serviceUrl)); + + CompletableFuture>> combinedFutures = CompletableFuture + .allOf(completableFutures.toArray(new CompletableFuture[0])) + .thenApply(future -> + completableFutures.stream() + .map(CompletableFuture::join) + .collect(Collectors.toList())); + + List> responses = combinedFutures.get(); + responses.forEach((response) -> { + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + }); + } + + @Test + void givenPostRequestWithAuthClient_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException { + HttpResponse response = HttpClientPost.sendPostWithAuthClient(serviceUrl); + + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + + @Test + void givenPostRequestWithAuthHeader_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException { + HttpResponse response = HttpClientPost.sendPostWithAuthHeader(serviceUrl); + + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + + @Test + void givenPostRequestWithJsonBody_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException { + HttpResponse response = HttpClientPost.sendPostWithJsonBody(serviceUrl); + + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + + @Test + void givenPostRequestWithFormData_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException { + HttpResponse response = HttpClientPost.sendPostWithFormData(serviceUrl); + + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + + @Test + void givenPostRequestWithFileData_whenServerIsAvailable_thenOkStatusIsReceived(@TempDir Path tempDir) throws IOException, InterruptedException { + Path file = tempDir.resolve("temp.txt"); + List lines = Arrays.asList("1", "2", "3"); + Files.write(file, lines); + + HttpResponse response = HttpClientPost.sendPostWithFileData(serviceUrl, file); + + assertThat(response.statusCode()).isEqualTo(200); + assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}"); + } + +} diff --git a/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/PostRequestMockServer.java b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/PostRequestMockServer.java new file mode 100644 index 0000000000..fa594897a3 --- /dev/null +++ b/core-java-modules/core-java-httpclient/src/test/java/com/baeldung/httpclient/PostRequestMockServer.java @@ -0,0 +1,61 @@ +package com.baeldung.httpclient; + +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.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +public abstract class PostRequestMockServer { + + 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 PATH = "/test1"; + public static final String METHOD = "POST"; + + @BeforeAll + static void startServer() throws IOException, URISyntaxException { + serverPort = getFreePort(); + serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH; + mockServer = startClientAndServer(serverPort); + mockBasicPostRequest(); + } + + @AfterAll + static void stopServer() { + mockServer.stop(); + } + + private static void mockBasicPostRequest() { + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH) + .withMethod(METHOD) + ) + .respond( + response() + .withStatusCode(HttpStatusCode.OK_200.code()) + .withBody("{\"message\":\"ok\"}") + ); + } + + private static int getFreePort () throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } + +} diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md index 65a46eeed3..c05618afbd 100644 --- a/core-java-modules/core-java-io-4/README.md +++ b/core-java-modules/core-java-io-4/README.md @@ -9,4 +9,5 @@ This module contains articles about core Java input and output (IO) - [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) +- [Java Scanner.skip method with examples](https://www.baeldung.com/java-scanner-skip) - [[<-- Prev]](/core-java-modules/core-java-io-3) diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/scanner/ScannerUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/scanner/ScannerUnitTest.java new file mode 100644 index 0000000000..cb6ce5fb2d --- /dev/null +++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/scanner/ScannerUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.scanner; + +import org.junit.Test; + +import java.util.*; +import java.util.regex.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ScannerUnitTest { + @Test public void givenScannerWithPattern_thenSkipUsingPattern() { + String str = "Java scanner skip tutorial"; + // Instantiates Scanner + Scanner sc = new Scanner(str); + // By using skip(Pattern) method is to skip that meets the given pattern + sc.skip(Pattern.compile(".ava")); + + assertEquals(" scanner skip tutorial", sc.nextLine()); + // Scanner closed + sc.close(); + } + + @Test public void givenScannerWithString_thenSkipUsingStringPattern() { + String str = "Java scanner skip tutorial"; + // Instantiates Scanner + Scanner sc = new Scanner(str); + // By using skip(String) method is to skip that meets the given + // pattern constructed from the given String + sc.skip("Java"); + + assertEquals(" scanner skip tutorial", sc.nextLine()); + // Scanner closed + sc.close(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lambdas/README.md b/core-java-modules/core-java-lambdas/README.md index 832d4783f2..53414eb14c 100644 --- a/core-java-modules/core-java-lambdas/README.md +++ b/core-java-modules/core-java-lambdas/README.md @@ -6,4 +6,5 @@ - [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) - [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions) - [Method References in Java](https://www.baeldung.com/java-method-references) -- [The Double Colon Operator in Java 8](https://www.baeldung.com/java-8-double-colon-operator) \ No newline at end of file +- [The Double Colon Operator in Java 8](https://www.baeldung.com/java-8-double-colon-operator) +- [Serialize a Lambda in Java](https://www.baeldung.com/java-serialize-lambda) diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/serialization/NotSerializableLambdaExpression.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/serialization/NotSerializableLambdaExpression.java new file mode 100644 index 0000000000..38f87e4ba9 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/serialization/NotSerializableLambdaExpression.java @@ -0,0 +1,8 @@ +package com.baeldung.java8.lambda.serialization; + +public class NotSerializableLambdaExpression { + public static Object getLambdaExpressionObject() { + Runnable r = () -> System.out.println("please serialize this message"); + return r; + } +} diff --git a/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/serialization/SerializableLambdaExpression.java b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/serialization/SerializableLambdaExpression.java new file mode 100644 index 0000000000..74541013bb --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/main/java/com/baeldung/java8/lambda/serialization/SerializableLambdaExpression.java @@ -0,0 +1,10 @@ +package com.baeldung.java8.lambda.serialization; + +import java.io.Serializable; + +public class SerializableLambdaExpression { + public static Object getLambdaExpressionObject() { + Runnable r = (Runnable & Serializable) () -> System.out.println("please serialize this message"); + return r; + } +} diff --git a/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/serialization/LambdaSerializationUnitTest.java b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/serialization/LambdaSerializationUnitTest.java new file mode 100644 index 0000000000..bb71e3bdb9 --- /dev/null +++ b/core-java-modules/core-java-lambdas/src/test/java/com/baeldung/java8/lambda/serialization/LambdaSerializationUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.java8.lambda.serialization; + +import org.junit.Test; + +import java.io.*; +import java.nio.file.Files; +import java.util.function.Consumer; +import java.util.function.Function; + +import static org.junit.Assert.assertTrue; + +public class LambdaSerializationUnitTest { + @Test(expected = NotSerializableException.class) + public void givenRunnable_whenNoCapturing_thenSerializationFailed() throws IOException, ClassNotFoundException { + Object obj = NotSerializableLambdaExpression.getLambdaExpressionObject(); + writeAndReadObject(obj, Runnable.class); + } + + @Test + public void givenIntersectionType_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + Object obj = SerializableLambdaExpression.getLambdaExpressionObject(); + writeAndReadObject(obj, Runnable.class); + } + + @Test + public void givenSerializableRunnable_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + SerializableRunnable obj = () -> System.out.println("please serialize this message"); + writeAndReadObject(obj, SerializableRunnable.class); + } + + @Test + public void givenSerializableFunction_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + SerializableFunction obj = message -> String.format("Hello %s", message); + writeAndReadObject(obj, SerializableFunction.class); + } + + @Test + public void givenSerializableConsumer_whenNoCapturing_thenSerializationSuccess() throws IOException, ClassNotFoundException { + SerializableConsumer obj = message -> System.out.println(message); + writeAndReadObject(obj, SerializableConsumer.class); + } + + @Test(expected = NotSerializableException.class) + public void givenSerializableConsumer_whenCapturingNotSerializable_thenSerializationFailed() throws IOException, ClassNotFoundException { + SerializableConsumer obj = System.out::println; + writeAndReadObject(obj, SerializableConsumer.class); + } + + private void writeAndReadObject(Object obj, Class clazz) throws IOException, ClassNotFoundException { + File file = Files.createTempFile("lambda", "ser").toFile(); + try ( + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos) + ) { + oos.writeObject(obj); + } + + try ( + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis) + ) { + Object newObj = ois.readObject(); + boolean isInstance = clazz.isInstance(newObj); + + assertTrue(isInstance); + } + } + + interface SerializableRunnable extends Runnable, Serializable { + } + + interface SerializableFunction extends Function, Serializable { + } + + interface SerializableConsumer extends Consumer, Serializable { + } +} diff --git a/core-java-modules/core-java-lang-4/README.md b/core-java-modules/core-java-lang-4/README.md index a145633d2b..befef0b6eb 100644 --- a/core-java-modules/core-java-lang-4/README.md +++ b/core-java-modules/core-java-lang-4/README.md @@ -11,3 +11,4 @@ This module contains articles about core features in the Java language - [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) +- [Implements vs. Extends in Java](https://www.baeldung.com/java-implements-vs-extends) 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 index 7a1775f79d..3d2c61aa3d 100644 --- 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 @@ -28,9 +28,15 @@ public class EmployeeVO { @Override public boolean equals(Object obj) { - return Objects.equals(firstName, this.firstName) - && Objects.equals(lastName, this.lastName) - && Objects.equals(startDate, this.startDate); + + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + EmployeeVO emp = (EmployeeVO) obj; + + return Objects.equals(firstName, emp.firstName) + && Objects.equals(lastName, emp.lastName) + && Objects.equals(startDate, emp.startDate); } @Override diff --git a/core-java-modules/core-java-lang-5/README.md b/core-java-modules/core-java-lang-5/README.md new file mode 100644 index 0000000000..8920e9c231 --- /dev/null +++ b/core-java-modules/core-java-lang-5/README.md @@ -0,0 +1,7 @@ +## Core Java Lang (Part 5) + +This module contains articles about core features in the Java language + +### Relevant Articles: + +- [Difference Between == and equals() in Java](https://www.baeldung.com/java-equals-method-operator-difference) diff --git a/core-java-modules/core-java-lang-5/pom.xml b/core-java-modules/core-java-lang-5/pom.xml new file mode 100644 index 0000000000..6d3771bd31 --- /dev/null +++ b/core-java-modules/core-java-lang-5/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + core-java-lang-5 + 0.1.0-SNAPSHOT + core-java-lang-5 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + core-java-lang-5 + + + src/main/resources + true + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/nullchecks/NullChecksUnitTest.java b/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/nullchecks/NullChecksUnitTest.java new file mode 100644 index 0000000000..12b3db734d --- /dev/null +++ b/core-java-modules/core-java-lang-5/src/test/java/com/baeldung/nullchecks/NullChecksUnitTest.java @@ -0,0 +1,125 @@ +package com.baeldung.nullchecks; + +import org.junit.Test; + +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.*; + +public class NullChecksUnitTest { + + @Test + public void whenReferenceEqualityOnPrimitives_thenCompareValues() { + int a = 10; + int b = 15; + int c = 10; + int d = a; + + // different values check + assertFalse(a == b); + + // same values check + assertTrue(a == c); + + // same references check + assertTrue(a == d); + } + + @Test + public void whenReferenceEqualityOnObjects_thenCompareReferences() { + Person a = new Person("Bob", 20); + Person b = new Person("Mike", 40); + Person c = new Person("Bob", 20); + Person d = a; + Person e = null; + + // different values check + assertFalse(a == b); + + // same values check + assertFalse(a == c); + + // same references check + assertTrue(a == d); + + // same references check - for nulls + assertTrue(e == null); + } + + @Test + public void whenValueEqualityOnPrimitives_thenCompareValues() { + int a = 10; + Integer b = a; + + assertTrue(b.equals(10)); + } + + @Test + public void whenValueEqualityOnObjects_thenCompareValues() { + Person a = new Person("Bob", 20); + Person b = new Person("Mike", 40); + Person c = new Person("Bob", 20); + Person d = a; + Person e = null; + + // different values check + assertFalse(a.equals(b)); + + // same values check + assertTrue(a.equals(c)); + + // same references check + assertTrue(a.equals(d)); + + // null checks + assertFalse(a.equals(e)); + assertThrows(NullPointerException.class, () -> e.equals(a)); + + // null checks fixed + assertFalse(e != null && e.equals(a)); + + // using Objects.equals + assertFalse(Objects.equals(e, a)); + assertTrue(Objects.equals(null, e)); + + } + + private class Person { + private String name; + private int age; + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + 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; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } +} diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index 1dd3a3c7e0..3ddaddae39 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -5,4 +5,5 @@ ### Relevant articles: - [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string) +- [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/swap/SwappingVariablesUnitTest.java b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/swap/SwappingVariablesUnitTest.java new file mode 100644 index 0000000000..bbfa0ee4f1 --- /dev/null +++ b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/swap/SwappingVariablesUnitTest.java @@ -0,0 +1,157 @@ +package com.baeldung.math.swap; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SwappingVariablesUnitTest { + + @Test + public void givenTwoStrings_whenSwappingInMethod_thenFails() { + + String a = "a"; + String b = "b"; + + swap(a, b); + + Assertions.assertFalse(a.equals("b")); + Assertions.assertFalse(b.equals("a")); + } + + @Test + public void givenTwoWrappers_whenSwappingInMethod_thenSuccess() { + + Wrapper a = new Wrapper("a"); + Wrapper b = new Wrapper("b"); + + swap(a, b); + + Assertions.assertTrue(a.string.equals("b")); + Assertions.assertTrue(b.string.equals("a")); + } + + @Test + public void givenTwoIntegers_whenSwappingUsingAdditionSubstraction_thenSuccess() { + + int a = 5; + int b = 10; + + a = a + b; + b = a - b; + a = a - b; + + Assertions.assertTrue(a == 10); + Assertions.assertTrue(b == 5); + } + + @Test + public void givenTwoIntegers_whenSwappingUsingMultiplicationDivision_thenSuccess() { + + int a = 5; + int b = 10; + + a = a * b; + b = a / b; + a = a / b; + + Assertions.assertTrue(a == 10); + Assertions.assertTrue(b == 5); + } + + @Test + public void givenTwoIntegers_whenSwappingWithOverflow_thenFails() { + + int a = Integer.MAX_VALUE; + int b = 10; + + a = a * b; + b = a / b; + a = a / b; + + Assertions.assertTrue(a == 10); + Assertions.assertFalse(b == Integer.MAX_VALUE); + } + + @Test + public void givenTwoChars_whenSwappingWithCast_thenSuccess() { + + char a = 'a'; + char b = 'b'; + + a = (char)(a * b); + b = (char)(a / b); + a = (char)(a / b); + + Assertions.assertTrue(a == 'b'); + Assertions.assertTrue(b == 'a'); + } + + @Test + public void givenTwoIntegers_whenSwappingUsingXor_thenSuccess() { + + int a = 5; + int b = 10; + + a = a ^ b; + b = a ^ b; + a = a ^ b; + + Assertions.assertTrue(a == 10); + Assertions.assertTrue(b == 5); + } + + @Test + public void givenTwoIntegers_whenSwappingUsingSingleLineXor_thenSuccess() { + + int a = 5; + int b = 10; + + a = a ^ b ^ (b = a); + + Assertions.assertTrue(a == 10); + Assertions.assertTrue(b == 5); + } + + @Test + public void givenTwoIntegers_whenSwappingUsingAdditionSubstractionSingleLine_thenSuccess() { + + int a = 5; + int b = 10; + + b = (a + b) - (a = b); + + Assertions.assertTrue(a == 10); + Assertions.assertTrue(b == 5); + } + + /** + * Illustrates that swapping in a method doesn't work + */ + private void swap(String a, String b) { + + String temp = b; + b = a; + a = temp; + } + + /** + * Illustrates swapping in a method with Wrapper class + */ + private void swap(Wrapper a, Wrapper b) { + + String temp = b.string; + b.string = a.string; + a.string = temp; + } + + class Wrapper { + + public String string; + + public Wrapper(String string) { + + this.string = string; + } + + + } +} diff --git a/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/randomenum/Direction.java b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/randomenum/Direction.java new file mode 100644 index 0000000000..05b398371c --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/randomenum/Direction.java @@ -0,0 +1,22 @@ +package com.baeldung.enums.randomenum; + +import java.util.Random; + +/** + * Represents directions. + */ +public enum Direction { + EAST, WEST, SOUTH, NORTH; + + private static final Random PRNG = new Random(); + + /** + * Generate a random direction. + * + * @return a random direction + */ + public static Direction randomDirection() { + Direction[] directions = values(); + return directions[PRNG.nextInt(directions.length)]; + } +} diff --git a/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/randomenum/RandomEnumGenerator.java b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/randomenum/RandomEnumGenerator.java new file mode 100644 index 0000000000..33d793062d --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types-2/src/main/java/com/baeldung/enums/randomenum/RandomEnumGenerator.java @@ -0,0 +1,17 @@ +package com.baeldung.enums.randomenum; + +import java.util.Random; + +public class RandomEnumGenerator> { + + private static final Random PRNG = new Random(); + private final T[] values; + + public RandomEnumGenerator(Class e) { + values = e.getEnumConstants(); + } + + public T randomEnum() { + return values[PRNG.nextInt(values.length)]; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/randomenum/RandomEnumUnitTest.java b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/randomenum/RandomEnumUnitTest.java new file mode 100644 index 0000000000..76b4bf1e74 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/randomenum/RandomEnumUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.enums.randomenum; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RandomEnumUnitTest { + + @Test + public void givenEnumType_whenUsingStaticMethod_valueIsRandomlyGenerated() { + Direction direction = Direction.randomDirection(); + assertThat(direction).isNotNull(); + assertThat(direction instanceof Direction); + } + + @Test + public void givenEnumType_whenGeneratingRandomValue_valueIsOfClassAndNotNull() { + RandomEnumGenerator reg = new RandomEnumGenerator(Direction.class); + Object direction = reg.randomEnum(); + assertThat(direction).isNotNull(); + assertThat(direction instanceof Direction); + } +} diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java index 987a69582f..0aba09a539 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/download/FileDownloadIntegrationTest.java @@ -19,7 +19,7 @@ public class FileDownloadIntegrationTest { static String FILE_URL = "https://s3.amazonaws.com/baeldung.com/Do+JSON+with+Jackson+by+Baeldung.pdf"; static String FILE_NAME = "file.dat"; - static String FILE_MD5_HASH = "c959feb066b37f5c4f0e0f45bbbb4f86"; + static String FILE_MD5_HASH = "753197aa27f162faa3e3c2e48ee5eb07"; @Test public void givenJavaIO_whenDownloadingFile_thenDownloadShouldBeCorrect() throws NoSuchAlgorithmException, IOException { diff --git a/core-java-modules/core-java-networking-3/README.md b/core-java-modules/core-java-networking-3/README.md index 82e75820ba..03c2dcfa89 100644 --- a/core-java-modules/core-java-networking-3/README.md +++ b/core-java-modules/core-java-networking-3/README.md @@ -10,4 +10,6 @@ This module contains articles about networking in Java - [Find Whether an IP Address Is in the Specified Range or Not in Java](https://www.baeldung.com/java-check-ip-address-range) - [Find the IP Address of a Client Connected to a Server](https://www.baeldung.com/java-client-get-ip-address) - [Unix Domain Socket in Java 16](https://www.baeldung.com/java-unix-domain-socket) +- [Get the IP Address of the Current Machine Using Java](https://www.baeldung.com/java-get-ip-address) +- [Get Domain Name From Given URL in Java](https://www.baeldung.com/java-domain-name-from-url) - [[<-- Prev]](/core-java-modules/core-java-networking-2) diff --git a/core-java-modules/core-java-networking-3/pom.xml b/core-java-modules/core-java-networking-3/pom.xml index 297d665544..63385c2334 100644 --- a/core-java-modules/core-java-networking-3/pom.xml +++ b/core-java-modules/core-java-networking-3/pom.xml @@ -52,6 +52,12 @@ java-ipv6 ${googlecode.ipv6.version} + + + com.google.guava + guava + ${guava.version} + @@ -84,6 +90,7 @@ 1.32 0.17 1.6.2 + 31.0-jre \ No newline at end of file diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/domain_name/DomainNameClient.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/domain_name/DomainNameClient.java new file mode 100644 index 0000000000..1b2cb636fe --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/domain_name/DomainNameClient.java @@ -0,0 +1,34 @@ +package com.baeldung.domain_name; + +import com.google.common.net.InternetDomainName; + +import java.net.URI; +import java.net.URISyntaxException; + +public class DomainNameClient { + + public String getHost(String url) throws URISyntaxException { + URI uri = new URI(url); + return uri.getHost(); + } + + public String getTopPrivateDomain(String url) { + InternetDomainName internetDomainName = InternetDomainName.from(url) + .topPrivateDomain(); + return internetDomainName.toString(); + } + + public String getName(String url) { + InternetDomainName internetDomainName = InternetDomainName.from(url) + .topPrivateDomain(); + String publicSuffix = internetDomainName.publicSuffix() + .toString(); + String domainName = internetDomainName.toString(); + return domainName.substring(0, domainName.lastIndexOf("." + publicSuffix)); + } + + public String getDomainName(String url) { + String regex = "http(s)?://|www\\.|/.*"; + return url.replaceAll(regex, ""); + } +} diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/http/JavaHttpClientTimeout.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/http/JavaHttpClientTimeout.java new file mode 100644 index 0000000000..d7ab002e77 --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/http/JavaHttpClientTimeout.java @@ -0,0 +1,12 @@ +package com.baeldung.http; + +import java.net.http.HttpClient; +import java.time.Duration; + +public class JavaHttpClientTimeout { + static HttpClient getHttpClientWithTimeout(int seconds) { + return HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(seconds)) + .build(); + } +} diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/iplookup/IPAddressLookup.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/iplookup/IPAddressLookup.java new file mode 100644 index 0000000000..30ad5a503d --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/iplookup/IPAddressLookup.java @@ -0,0 +1,50 @@ +package com.baeldung.iplookup; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketException; +import java.net.URL; +import java.net.UnknownHostException; + +public class IPAddressLookup { + public static void main(String[] args) { + System.out.println("UDP connection IP lookup: " + getLocalIpAddressUdp()); + System.out.println("Socket connection IP lookup: " + getLocalIpAddressSocket()); + System.out.println("AWS connection IP lookup: " + getPublicIpAddressAws()); + } + + public static String getLocalIpAddressUdp() { + try (final DatagramSocket datagramSocket = new DatagramSocket()) { + datagramSocket.connect(InetAddress.getByName("8.8.8.8"), 12345); + return datagramSocket.getLocalAddress().getHostAddress(); + } catch (SocketException | UnknownHostException exception) { + throw new RuntimeException(exception); + } + } + + public static String getLocalIpAddressSocket() { + try (Socket socket = new Socket()) { + socket.connect(new InetSocketAddress("google.com", 80)); + return socket.getLocalAddress().getHostAddress(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static String getPublicIpAddressAws() { + try { + String urlString = "http://checkip.amazonaws.com/"; + URL url = new URL(urlString); + try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + return br.readLine(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/domain_name/DomainNameClientUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/domain_name/DomainNameClientUnitTest.java new file mode 100644 index 0000000000..d69e7c0333 --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/domain_name/DomainNameClientUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.domain_name; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class DomainNameClientUnitTest { + + DomainNameClient domainNameClient = new DomainNameClient(); + + @Test + void givenUrl_whenGetHost_thenReturnSubdomainAndDomainName() { + Assertions.assertAll(() -> { + assertEquals("www.baeldung.com", domainNameClient.getHost("https://www.baeldung.com/domain")); + assertEquals("www.google.co.uk", domainNameClient.getHost("https://www.google.co.uk/domain")); + assertEquals("jira.baeldung.com", domainNameClient.getHost("https://jira.baeldung.com/secure")); + }); + } + + @Test + void givenUrl_whenGetTopPrivateDomain_thenReturnDomainName() { + assertEquals("baeldung.com", domainNameClient.getTopPrivateDomain("www.baeldung.com")); + } + + @Test + void givenUrlWithPublicSuffix_whenGetTopPrivateDomain_thenReturnDomainName() { + assertEquals("google.co.uk", domainNameClient.getTopPrivateDomain("www.google.co.uk")); + assertEquals("baeldung.blogspot.com", domainNameClient.getTopPrivateDomain("www.baeldung.blogspot.com")); + } + + @Test + void givenUrlWithPublicSuffix_whenGetName_thenReturnSecondLevelDomain() { + assertEquals("baeldung", domainNameClient.getName("jira.baeldung.com")); + } + + @Test + void givenUrlWithPublicSuffix_whenGetName_thenReturnThirdLevelDomain() { + assertEquals("baeldung", domainNameClient.getName("www.baeldung.co.uk")); + assertEquals("google", domainNameClient.getName("www.google.co.uk")); + } + + @Test + void givenUrl_whenGetDomainNameRegex_thenReturnDomainName() { + assertEquals("google.com", domainNameClient.getDomainName("www.google.com")); + assertEquals("google.co.uk", domainNameClient.getDomainName("www.google.co.uk")); + assertEquals("jira.baeldung.com", domainNameClient.getDomainName("jira.baeldung.com")); + assertEquals("baeldung.com", domainNameClient.getDomainName("www.baeldung.com/test")); + } + +} diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutIntegrationTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutIntegrationTest.java new file mode 100644 index 0000000000..df635621ad --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutIntegrationTest.java @@ -0,0 +1,54 @@ +package com.baeldung.http; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static com.baeldung.http.JavaHttpClientTimeout.getHttpClientWithTimeout; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class JavaHttpClientTimeoutIntegrationTest { + + private HttpClient httpClient; + private HttpRequest httpRequest; + + @BeforeEach + public void setUp() { + httpClient = getHttpClientWithTimeout(3); + httpClient.connectTimeout().map(Duration::toSeconds) + .ifPresent(sec -> System.out.println("Timeout in seconds: " + sec)); + + httpRequest = HttpRequest.newBuilder().uri(URI.create("http://10.255.255.1")).GET().build(); + } + + @Test + void shouldThrowExceptionWhenMakingSyncCall() { + HttpConnectTimeoutException thrown = assertThrows( + HttpConnectTimeoutException.class, + () -> httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()), + "Expected doThing() to throw, but it didn't" + ); + assertTrue(thrown.getMessage().contains("timed out")); + } + + @Test + void shouldThrowExceptionWhenMakingASyncCall() throws ExecutionException, InterruptedException, TimeoutException { + CompletableFuture completableFuture = + httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString()) + .thenApply(HttpResponse::body) + .exceptionally(Throwable::getMessage); + String response = completableFuture.get(5, TimeUnit.SECONDS); + assertTrue(response.contains("timed out")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutOnRequestIntegrationTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutOnRequestIntegrationTest.java new file mode 100644 index 0000000000..d693b9075c --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/http/JavaHttpClientTimeoutOnRequestIntegrationTest.java @@ -0,0 +1,51 @@ +package com.baeldung.http; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpConnectTimeoutException; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.time.LocalTime; + +import static com.baeldung.http.JavaHttpClientTimeout.getHttpClientWithTimeout; +import static java.time.LocalTime.now; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class JavaHttpClientTimeoutOnRequestIntegrationTest { + + private HttpClient httpClient; + private HttpRequest httpRequest; + + @BeforeEach + public void setUp() { + httpClient = getHttpClientWithTimeout(3); + httpClient.connectTimeout().map(Duration::toSeconds) + .ifPresent(sec -> System.out.println("Timeout in seconds: " + sec)); + + httpRequest = HttpRequest.newBuilder() + .uri(URI.create("http://10.255.255.1")) + .timeout(Duration.ofSeconds(1)) + .GET() + .build(); + } + + @Test + void shouldThrowExceptionWhithin1SecondWhenMakingSyncCall() { + LocalTime beforeHttpCall = now(); + HttpConnectTimeoutException thrown = assertThrows( + HttpConnectTimeoutException.class, + () -> httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()), + "Expected doThing() to throw, but it didn't" + ); + LocalTime afterHttpCall = now(); + assertTrue(thrown.getMessage().contains("timed out")); + assertEquals(1, Duration.between(beforeHttpCall, afterHttpCall).getSeconds()); + } + +} diff --git a/core-java-modules/core-java-nio-2/README.md b/core-java-modules/core-java-nio-2/README.md index c405cb7c77..527600779a 100644 --- a/core-java-modules/core-java-nio-2/README.md +++ b/core-java-modules/core-java-nio-2/README.md @@ -13,4 +13,5 @@ This module contains articles about core Java non-blocking input and output (IO) - [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) +- [Find Files that Match Wildcard Strings in Java](https://www.baeldung.com/java-files-match-wildcard-strings) - [[<-- Prev]](/core-java-modules/core-java-nio) diff --git a/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcard.java b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcard.java new file mode 100644 index 0000000000..2deaa60ec6 --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/main/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcard.java @@ -0,0 +1,37 @@ +package com.baeldung.searchfilesbywildcards; + +import java.io.IOException; + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +import java.util.ArrayList; +import java.util.List; + +public class SearchFileByWildcard { + public static List matchesList = new ArrayList(); + public List searchWithWc(Path rootDir, String pattern) throws IOException { + matchesList.clear(); + FileVisitor matcherVisitor = new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) throws IOException { + FileSystem fs = FileSystems.getDefault(); + PathMatcher matcher = fs.getPathMatcher(pattern); + Path name = file.getFileName(); + if (matcher.matches(name)) { + matchesList.add(name.toString()); + } + return FileVisitResult.CONTINUE; + } + }; + Files.walkFileTree(rootDir, matcherVisitor); + return matchesList; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcardUnitTest.java b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcardUnitTest.java new file mode 100644 index 0000000000..71cee036ec --- /dev/null +++ b/core-java-modules/core-java-nio-2/src/test/java/com/baeldung/searchfilesbywildcards/SearchFileByWildcardUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.searchfilesbywildcards; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.IOException; + +import java.nio.file.Paths; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class SearchFileByWildcardUnitTest { + @Test + public void whenFourFilenameMatch_thenListOfFour() throws IOException { + SearchFileByWildcard sfbw = new SearchFileByWildcard(); + List actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:*.{txt,docx}"); + + assertEquals(new HashSet<>(Arrays.asList("six.txt", "three.txt", "two.docx", "one.txt")), new HashSet<>(actual)); + } + @Test + public void whenOneFilenameMatch_thenListOfOne() throws IOException { + SearchFileByWildcard sfbw = new SearchFileByWildcard(); + List actual = sfbw.searchWithWc(Paths.get("src/test/resources/sfbw"), "glob:????.{csv}"); + + assertEquals(new HashSet<>(Arrays.asList("five.csv")), new HashSet<>(actual)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/five.csv b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/five.csv new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/four.xlsx b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/four.xlsx new file mode 100644 index 0000000000..1091dafe75 Binary files /dev/null and b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/four.xlsx differ diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/one.txt b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/one.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/test2/six.txt b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/test2/six.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/three.txt b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/three.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/two.docx b/core-java-modules/core-java-nio-2/src/test/resources/sfbw/test/two.docx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/core-java-modules/core-java-reflection-2/README.md b/core-java-modules/core-java-reflection-2/README.md index c1966dd63d..a3c9d00b0a 100644 --- a/core-java-modules/core-java-reflection-2/README.md +++ b/core-java-modules/core-java-reflection-2/README.md @@ -7,3 +7,4 @@ - [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method) - [Finding All Classes in a Java Package](https://www.baeldung.com/java-find-all-classes-in-package) - [Invoke a Static Method Using Java Reflection API](https://www.baeldung.com/java-invoke-static-method-reflection) +- [What Is the JDK com.sun.proxy.$Proxy Class?](https://www.baeldung.com/jdk-com-sun-proxy) diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/AdvancedOperation.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/AdvancedOperation.java new file mode 100644 index 0000000000..b3f0dc8ec0 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/AdvancedOperation.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.proxy; + +public interface AdvancedOperation { + int multiply(int a, int b); + + int divide(int a, int b); +} \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/BasicOperation.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/BasicOperation.java new file mode 100644 index 0000000000..168367b690 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/proxy/BasicOperation.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.proxy; + +public interface BasicOperation { + int add(int a, int b); + + int subtract(int a, int b); +} \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/proxy/DollarProxyUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/proxy/DollarProxyUnitTest.java new file mode 100644 index 0000000000..ef6c481778 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/proxy/DollarProxyUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.reflection.proxy; + +import org.junit.Test; + +import java.lang.reflect.Proxy; +import java.util.function.Consumer; + +import static org.junit.Assert.assertTrue; + +public class DollarProxyUnitTest { + @Test + public void givenProxy_whenInvokingGetProxyClass_thenGeneratingProxyClass() { + // Java 8: -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true + // Java 9 or later: -Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true + // Note: System.setProperty() doesn't work here + // because ProxyGenerator.saveGeneratedFiles read its property only once. + // The @Test annotation in this method will generate a $Proxy class. + + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + Class[] interfaces = {BasicOperation.class, AdvancedOperation.class}; + Class proxyClass = Proxy.getProxyClass(classLoader, interfaces); + + boolean isProxyClass = Proxy.isProxyClass(proxyClass); + assertTrue(isProxyClass); + } + + @Test + public void givenReflection_whenReadingAnnotation_thenGeneratingProxyClass() { + FunctionalInterface instance = Consumer.class.getDeclaredAnnotation(FunctionalInterface.class); + Class clazz = instance.getClass(); + + boolean isProxyClass = Proxy.isProxyClass(clazz); + assertTrue(isProxyClass); + } +} diff --git a/core-java-modules/core-java-regex-2/README.md b/core-java-modules/core-java-regex-2/README.md index 6dafc74d41..453e2cc419 100644 --- a/core-java-modules/core-java-regex-2/README.md +++ b/core-java-modules/core-java-regex-2/README.md @@ -4,4 +4,5 @@ - [Lookahead and Lookbehind in Java Regex](https://www.baeldung.com/java-regex-lookahead-lookbehind) - [Converting Camel Case and Title Case to Words in Java](https://www.baeldung.com/java-camel-case-title-case-to-words) - [How to Use Regular Expressions to Replace Tokens in Strings in Java](https://www.baeldung.com/java-regex-token-replacement) -- More articles: [[<-- prev]](/core-java-modules/core-java-regex) \ No newline at end of file +- [Creating a Java Array from Regular Expression Matches](https://www.baeldung.com/java-array-regex-matches) +- More articles: [[<-- prev]](/core-java-modules/core-java-regex) diff --git a/core-java-modules/core-java-regex-2/regexMatchToArray/src/regex/array/RegexMatches.java b/core-java-modules/core-java-regex-2/regexMatchToArray/src/regex/array/RegexMatches.java new file mode 100644 index 0000000000..d7b50d95ca --- /dev/null +++ b/core-java-modules/core-java-regex-2/regexMatchToArray/src/regex/array/RegexMatches.java @@ -0,0 +1,24 @@ +package regex.array; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.*; + +class RegexMatches { + + String[] regexMatch(String strSearch) + { + List matchesList = new ArrayList(); + String stringToSearch = strSearch; + Pattern p1 = Pattern.compile("780{1}\\d{7}"); + Matcher m1 = p1.matcher(stringToSearch); + while (m1.find()) + { + matchesList.add(m1.group()); + } + int sizeOfNewArray = matchesList.size(); + String newArrayOfMatches[] = new String[sizeOfNewArray]; + matchesList.toArray(newArrayOfMatches); + return newArrayOfMatches; + } +} diff --git a/core-java-modules/core-java-regex-2/regexMatchToArray/test/regex/array/RegexMatchesUnitTest.java b/core-java-modules/core-java-regex-2/regexMatchToArray/test/regex/array/RegexMatchesUnitTest.java new file mode 100644 index 0000000000..3e8f23c4bb --- /dev/null +++ b/core-java-modules/core-java-regex-2/regexMatchToArray/test/regex/array/RegexMatchesUnitTest.java @@ -0,0 +1,33 @@ +package regex.array; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +import regex.array.RegexMatches; + +class RegexMatchesUnitTest { + + @Test + void whenFourNums_thenFourMatches() { + RegexMatches rm = new RegexMatches(); + String actual[] = rm.regexMatch("7801111211fsdafasdfa 7802222222 sadfsadfsda7803333333 sadfdasfasd 7804444444"); + + assertArrayEquals(new String[] {"7801111211", "7802222222", "7803333333", "7804444444"}, actual, "success"); + } + + @Test + void whenThreeNums_thenThreeMatches() { + RegexMatches rm = new RegexMatches(); + String actual[] = rm.regexMatch("7801111211fsdafasdfa 780222222 sadfsadfsda7803333333 sadfdasfasd 7804444444"); + + assertArrayEquals(new String[] {"7801111211", "7803333333", "7804444444"}, actual, "success"); + } + + @Test + void whenZeroNums_thenZeroMatches() { + RegexMatches rm = new RegexMatches(); + String actual[] = rm.regexMatch("78011111fsdafasdfa 780222222 sadfsadfsda78033333 sadfdasfasd 7804444"); + + assertArrayEquals(new String[] {}, actual, "success"); + } +} diff --git a/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/RegexUnitTest.java b/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/RegexUnitTest.java index 77052b79ac..f6c5f35f37 100644 --- a/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/RegexUnitTest.java +++ b/core-java-modules/core-java-regex/src/test/java/com/baeldung/regex/RegexUnitTest.java @@ -104,7 +104,7 @@ public class RegexUnitTest { @Test public void givenNumberRange_whenMatchesAccurately_thenCorrect2() { - int matches = runTest("[30-35]", "Two Uppercase alphabets 34 overall"); + int matches = runTest("3[0-5]", "Two Uppercase alphabets 34 overall"); assertTrue(matches > 0); assertEquals(matches, 1); } diff --git a/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java index fa38aca272..5653f47734 100644 --- a/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java +++ b/core-java-modules/core-java-security-algorithms/src/test/java/com/baeldung/cipher/AvailableCiphersUnitTest.java @@ -17,7 +17,7 @@ public class AvailableCiphersUnitTest { public void whenGetServices_thenGetAllCipherAlgorithms() { for (Provider provider : Security.getProviders()) { for (Provider.Service service : provider.getServices()) { - logger.info(service.getAlgorithm()); + logger.debug(service.getAlgorithm()); } } } @@ -30,6 +30,6 @@ public class AvailableCiphersUnitTest { .map(Provider.Service::getAlgorithm) .collect(Collectors.toList()); - algorithms.forEach(logger::info); + algorithms.forEach(logger::debug); } } diff --git a/immutables/src/main/resources/logback.xml b/core-java-modules/core-java-security-algorithms/src/test/resources/logback.xml similarity index 100% rename from immutables/src/main/resources/logback.xml rename to core-java-modules/core-java-security-algorithms/src/test/resources/logback.xml diff --git a/core-java-modules/core-java-string-operations-4/README.md b/core-java-modules/core-java-string-operations-4/README.md index 0e6c9e7e2c..ff6d887154 100644 --- a/core-java-modules/core-java-string-operations-4/README.md +++ b/core-java-modules/core-java-string-operations-4/README.md @@ -6,4 +6,5 @@ - [Split a String Every n Characters in Java](https://www.baeldung.com/java-string-split-every-n-characters) - [String equals() Vs contentEquals() in Java](https://www.baeldung.com/java-string-equals-vs-contentequals) - [Check if a String Ends with a Certain Pattern in Java](https://www.baeldung.com/java-string-ends-pattern) +- [Check if a Character is a Vowel in Java](https://www.baeldung.com/java-check-character-vowel) diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml index 7f71ea8da5..0f1e377d18 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -30,6 +30,12 @@ commons-lang3 ${apache-commons-lang3.version} + + org.assertj + assertj-core + ${assertj.version} + test + diff --git a/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/checkvowels/CheckVowels.java b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/checkvowels/CheckVowels.java new file mode 100644 index 0000000000..fd60427a4e --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/main/java/com/baeldung/checkvowels/CheckVowels.java @@ -0,0 +1,38 @@ +package com.baeldung.checkvowels; + +import java.util.regex.Pattern; + +public class CheckVowels { + private static final String VOWELS = "aeiouAEIOU"; + private static final Pattern VOWELS_PATTERN = Pattern.compile("[aeiou]", Pattern.CASE_INSENSITIVE); + + public static boolean isInVowelsString(char c) { + return VOWELS.indexOf(c) != -1; + } + + public static boolean isInVowelsString(String c) { + return VOWELS.contains(c); + } + + public static boolean isVowelBySwitch(char c) { + switch (c) { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + case 'A': + case 'E': + case 'I': + case 'O': + case 'U': + return true; + default: + return false; + } + } + + public static boolean isVowelByRegex(String c) { + return VOWELS_PATTERN.matcher(c).matches(); + } +} diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/checkvowels/CheckVowelsUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/checkvowels/CheckVowelsUnitTest.java new file mode 100644 index 0000000000..52b0e55692 --- /dev/null +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/checkvowels/CheckVowelsUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.checkvowels; + +import org.junit.jupiter.api.Test; + +import static com.baeldung.checkvowels.CheckVowels.*; +import static org.assertj.core.api.Assertions.*; + +class CheckVowelsUnitTest { + + @Test + void givenAVowelCharacter_thenInVowelString() { + assertThat(isInVowelsString('e')).isTrue(); + } + + @Test + void givenAConsonantCharacter_thenNotInVowelString() { + assertThat(isInVowelsString('z')).isFalse(); + } + + @Test + void givenAVowelString_thenInVowelString() { + assertThat(isInVowelsString("e")).isTrue(); + } + + @Test + void givenAConsonantString_thenNotInVowelString() { + assertThat(isInVowelsString("z")).isFalse(); + } + + @Test + void givenAVowelCharacter_thenInVowelSwitch() { + assertThat(isVowelBySwitch('e')).isTrue(); + } + + @Test + void givenAConsonantCharacter_thenNotInVowelSwitch() { + assertThat(isVowelBySwitch('z')).isFalse(); + } + + @Test + void givenAVowelString_thenInVowelPattern() { + assertThat(isVowelByRegex("e")).isTrue(); + assertThat(isVowelByRegex("E")).isTrue(); + } + + @Test + void givenAVowelCharacter_thenInVowelPattern() { + assertThat(isVowelByRegex(Character.toString('e'))).isTrue(); + assertThat(isVowelByRegex("E")).isTrue(); + } +} diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java index 8e9d3afdde..90335b4aba 100644 --- a/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringperformance/StringPerformance.java @@ -125,6 +125,8 @@ public class StringPerformance { stringSplit.add(longString.substring(pos, end)); pos = end + 1; } + //Add last token of string + stringSplit.add(longString.substring(pos)); return stringSplit; } diff --git a/core-java-modules/core-java-uuid/pom.xml b/core-java-modules/core-java-uuid/pom.xml index 28519a1a68..7d851292f5 100644 --- a/core-java-modules/core-java-uuid/pom.xml +++ b/core-java-modules/core-java-uuid/pom.xml @@ -35,7 +35,6 @@ true - org.apache.maven.plugins diff --git a/core-java-modules/core-java/README.md b/core-java-modules/core-java/README.md index a75805e0c2..087c5d356e 100644 --- a/core-java-modules/core-java/README.md +++ b/core-java-modules/core-java/README.md @@ -1,9 +1,11 @@ ## Core Java Cookbooks and Examples ### Relevant Articles: + - [Getting Started with Java Properties](http://www.baeldung.com/java-properties) - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) - [Compiling Java *.class Files with javac](http://www.baeldung.com/javac) - [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle) - [Merging java.util.Properties Objects](https://www.baeldung.com/java-merging-properties) +- [Illegal Character Compilation Error](https://www.baeldung.com/java-illegal-character-error) diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index bb19b525d0..87abe6c007 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -59,6 +59,16 @@ spring-core ${spring.core.version} + + commons-io + commons-io + ${commons-io.version} + + + com.google.gdata + core + ${gdata.version} + @@ -183,6 +193,7 @@ 1.8 1.8 4.3.20.RELEASE + 1.47.1 \ No newline at end of file diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java new file mode 100644 index 0000000000..4a08daa271 --- /dev/null +++ b/core-java-modules/core-java/src/test/java/com/baeldung/illegalcharacter/IllegalCharacterUnitTest.java @@ -0,0 +1,79 @@ +package com.baeldung.illegalcharacter; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Objects; + +import org.apache.commons.io.ByteOrderMark; +import org.apache.commons.io.input.BOMInputStream; +import org.junit.Test; + +import com.google.gdata.util.io.base.UnicodeReader; + +public class IllegalCharacterUnitTest { + + final String RESOURCE_FILE_NAME = "bom-file.txt"; + final InputStream ioStream = this.getClass() + .getClassLoader() + .getResourceAsStream(RESOURCE_FILE_NAME); + final String expected = "Hello world with BOM."; + + @Test + public void whenInputFileHasBOM_thenUseInputStream() throws IOException { + String line; + String actual = ""; + + try (BufferedReader br = new BufferedReader(new InputStreamReader(ioStream))) { + while ((line = br.readLine()) != null) { + actual += line; + } + } + + assertNotEquals(expected, actual); + } + + @Test + public void whenInputFileHasBOM_thenUseInputStreamWithReplace() throws IOException { + String line; + String actual = ""; + + try (BufferedReader br = new BufferedReader(new InputStreamReader(Objects.requireNonNull(ioStream)))) { + while ((line = br.readLine()) != null) { + actual += line.replace("\uFEFF", ""); + } + } + + assertEquals(expected, actual); + } + + @Test + public void whenInputFileHasBOM_thenUseBOMInputStream() throws IOException { + String line; + String actual = ""; + + try (BufferedReader br = new BufferedReader(new InputStreamReader(new BOMInputStream(ioStream, false, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE)))) { + while ((line = br.readLine()) != null) { + actual += line; + } + } + + assertEquals(expected, actual); + } + + @Test + public void whenInputFileHasBOM_thenUseGoogleGdata() throws IOException { + char[] actual = new char[21]; + + try (Reader r = new UnicodeReader(ioStream, null)) { + r.read(actual); + } + + assertEquals(expected, String.valueOf(actual)); + } +} diff --git a/core-java-modules/core-java/src/test/resources/bom-file.txt b/core-java-modules/core-java/src/test/resources/bom-file.txt new file mode 100644 index 0000000000..b2037fded6 --- /dev/null +++ b/core-java-modules/core-java/src/test/resources/bom-file.txt @@ -0,0 +1 @@ +Hello world with BOM. \ No newline at end of file diff --git a/java-collections-conversions-2/README.md b/core-java-modules/java-collections-conversions-2/README.md similarity index 100% rename from java-collections-conversions-2/README.md rename to core-java-modules/java-collections-conversions-2/README.md diff --git a/java-collections-conversions-2/pom.xml b/core-java-modules/java-collections-conversions-2/pom.xml similarity index 84% rename from java-collections-conversions-2/pom.xml rename to core-java-modules/java-collections-conversions-2/pom.xml index 9f8ef7addc..510921c35e 100644 --- a/java-collections-conversions-2/pom.xml +++ b/core-java-modules/java-collections-conversions-2/pom.xml @@ -9,10 +9,9 @@ jar - com.baeldung - parent-java + com.baeldung.core-java-modules + core-java-modules 0.0.1-SNAPSHOT - ../parent-java @@ -29,7 +28,7 @@ io.vavr vavr - 0.10.3 + ${vavr.version} @@ -43,4 +42,8 @@ + + 0.10.3 + + \ No newline at end of file diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/convertlisttomap/ListToMapConverter.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/convertlisttomap/ListToMapConverter.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/convertlisttomap/ListToMapConverter.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/convertlisttomap/ListToMapConverter.java diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/MapperUtil.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/MapperUtil.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/MapperUtil.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/MapperUtil.java diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/User.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/User.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/User.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/User.java diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserDTO.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserDTO.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserDTO.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserDTO.java diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserList.java diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserListDTO.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserListDTO.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserListDTO.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UserListDTO.java diff --git a/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UsersListConverter.java b/core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UsersListConverter.java similarity index 100% rename from java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UsersListConverter.java rename to core-java-modules/java-collections-conversions-2/src/main/java/com/baeldung/modelmapper/UsersListConverter.java diff --git a/java-collections-conversions-2/src/test/java/com/baeldung/arrayconversion/ArrayToListConversionUnitTest.java b/core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/arrayconversion/ArrayToListConversionUnitTest.java similarity index 100% rename from java-collections-conversions-2/src/test/java/com/baeldung/arrayconversion/ArrayToListConversionUnitTest.java rename to core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/arrayconversion/ArrayToListConversionUnitTest.java diff --git a/java-collections-conversions-2/src/test/java/com/baeldung/convertarraytostring/ArrayToStringUnitTest.java b/core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/convertarraytostring/ArrayToStringUnitTest.java similarity index 100% rename from java-collections-conversions-2/src/test/java/com/baeldung/convertarraytostring/ArrayToStringUnitTest.java rename to core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/convertarraytostring/ArrayToStringUnitTest.java diff --git a/java-collections-conversions-2/src/test/java/com/baeldung/convertlisttomap/ListToMapUnitTest.java b/core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/convertlisttomap/ListToMapUnitTest.java similarity index 100% rename from java-collections-conversions-2/src/test/java/com/baeldung/convertlisttomap/ListToMapUnitTest.java rename to core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/convertlisttomap/ListToMapUnitTest.java diff --git a/java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java b/core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java similarity index 100% rename from java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java rename to core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/modelmapper/UsersListMappingUnitTest.java diff --git a/java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java b/core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java similarity index 100% rename from java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java rename to core-java-modules/java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java diff --git a/java-collections-conversions/README.md b/core-java-modules/java-collections-conversions/README.md similarity index 100% rename from java-collections-conversions/README.md rename to core-java-modules/java-collections-conversions/README.md diff --git a/java-collections-conversions/pom.xml b/core-java-modules/java-collections-conversions/pom.xml similarity index 89% rename from java-collections-conversions/pom.xml rename to core-java-modules/java-collections-conversions/pom.xml index 7f5ba38e3e..2751e0100a 100644 --- a/java-collections-conversions/pom.xml +++ b/core-java-modules/java-collections-conversions/pom.xml @@ -9,10 +9,9 @@ jar - com.baeldung - parent-java + com.baeldung.core-java-modules + core-java-modules 0.0.1-SNAPSHOT - ../parent-java diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java b/core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java similarity index 100% rename from java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java rename to core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java b/core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java similarity index 100% rename from java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java rename to core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java b/core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java similarity index 100% rename from java-collections-conversions/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java rename to core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/Animal.java b/core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/Animal.java similarity index 100% rename from java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/Animal.java rename to core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/Animal.java diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java b/core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java similarity index 100% rename from java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java rename to core-java-modules/java-collections-conversions/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java diff --git a/java-collections-conversions/src/main/resources/logback.xml b/core-java-modules/java-collections-conversions/src/main/resources/logback.xml similarity index 100% rename from java-collections-conversions/src/main/resources/logback.xml rename to core-java-modules/java-collections-conversions/src/main/resources/logback.xml diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertcollectiontoarraylist/CollectionToArrayListUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertcollectiontoarraylist/CollectionToArrayListUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/convertcollectiontoarraylist/CollectionToArrayListUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertcollectiontoarraylist/CollectionToArrayListUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDuplicatedIdToMapServiceUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDuplicatedIdToMapServiceUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDuplicatedIdToMapServiceUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDuplicatedIdToMapServiceUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/java/collections/IterableToCollectionUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/java/collections/IterableToCollectionUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/java/collections/IterableToCollectionUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/java/collections/IterableToCollectionUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/java/collections/JavaCollectionConversionUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/java/collections/JavaCollectionConversionUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/java/collections/JavaCollectionConversionUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/java/collections/JavaCollectionConversionUnitTest.java diff --git a/java-collections-conversions/src/test/java/com/baeldung/java/lists/ListToStringUnitTest.java b/core-java-modules/java-collections-conversions/src/test/java/com/baeldung/java/lists/ListToStringUnitTest.java similarity index 100% rename from java-collections-conversions/src/test/java/com/baeldung/java/lists/ListToStringUnitTest.java rename to core-java-modules/java-collections-conversions/src/test/java/com/baeldung/java/lists/ListToStringUnitTest.java diff --git a/java-collections-maps-3/README.md b/core-java-modules/java-collections-maps-3/README.md similarity index 100% rename from java-collections-maps-3/README.md rename to core-java-modules/java-collections-maps-3/README.md diff --git a/java-collections-maps-3/pom.xml b/core-java-modules/java-collections-maps-3/pom.xml similarity index 87% rename from java-collections-maps-3/pom.xml rename to core-java-modules/java-collections-maps-3/pom.xml index 729b357b76..ab80a9e2fd 100644 --- a/java-collections-maps-3/pom.xml +++ b/core-java-modules/java-collections-maps-3/pom.xml @@ -9,10 +9,9 @@ jar - com.baeldung - parent-java + com.baeldung.core-java-modules + core-java-modules 0.0.1-SNAPSHOT - ../parent-java @@ -20,7 +19,7 @@ org.junit.jupiter junit-jupiter-api - 5.8.1 + ${junit-jupiter.version} org.springframework diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/bytearrays/BytesKey.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/bytearrays/BytesKey.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/bytearrays/BytesKey.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/bytearrays/BytesKey.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/Member.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithBadHashing.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithGuavaHashing.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithId.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithIdAndName.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/hashing/MemberWithObjects.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/identity/IdentityHashMapDemonstrator.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/identity/IdentityHashMapDemonstrator.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/identity/IdentityHashMapDemonstrator.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/identity/IdentityHashMapDemonstrator.java diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java b/core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java similarity index 100% rename from java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java rename to core-java-modules/java-collections-maps-3/src/main/java/com/baeldung/map/invert/InvertHashMapExample.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/bytearrays/ByteArrayKeyUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/bytearrays/ByteArrayKeyUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/bytearrays/ByteArrayKeyUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/bytearrays/ByteArrayKeyUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/caseinsensitivekeys/CaseInsensitiveMapUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/caseinsensitivekeys/CaseInsensitiveMapUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/caseinsensitivekeys/CaseInsensitiveMapUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/caseinsensitivekeys/CaseInsensitiveMapUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashMapUpdateUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashMapUpdateUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashMapUpdateUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashMapUpdateUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/hashing/HashingUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/identity/IdentityHashMapDemonstratorUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/identity/IdentityHashMapDemonstratorUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/identity/IdentityHashMapDemonstratorUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/identity/IdentityHashMapDemonstratorUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/invert/InvertHashMapUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/EntrySetExampleUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/EntrySetExampleUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/EntrySetExampleUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/EntrySetExampleUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/KeySetExampleUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/KeySetExampleUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/KeySetExampleUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/KeySetExampleUnitTest.java diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/ValuesExampleUnitTest.java b/core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/ValuesExampleUnitTest.java similarity index 100% rename from java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/ValuesExampleUnitTest.java rename to core-java-modules/java-collections-maps-3/src/test/java/com/baeldung/map/keysetValuesEntrySet/ValuesExampleUnitTest.java diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 2f684beea0..15347d0fe9 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -35,6 +35,7 @@ core-java-collections-list core-java-collections-list-2 core-java-collections-list-3 + core-java-collections-list-4 core-java-collections-maps core-java-collections-maps-2 core-java-collections-maps-3 @@ -73,6 +74,7 @@ core-java-lang-2 core-java-lang-3 core-java-lang-4 + core-java-lang-5 core-java-lang-math core-java-lang-math-2 core-java-lang-math-3 @@ -117,6 +119,9 @@ core-java-regex core-java-regex-2 core-java-uuid + java-collections-conversions + java-collections-conversions-2 + java-collections-maps-3 pre-jpms diff --git a/ddd-modules/README.md b/ddd-contexts/README.md similarity index 100% rename from ddd-modules/README.md rename to ddd-contexts/README.md diff --git a/ddd-modules/infrastructure/pom.xml b/ddd-contexts/infrastructure/pom.xml similarity index 79% rename from ddd-modules/infrastructure/pom.xml rename to ddd-contexts/infrastructure/pom.xml index 232e5ff4b4..6107991ceb 100644 --- a/ddd-modules/infrastructure/pom.xml +++ b/ddd-contexts/infrastructure/pom.xml @@ -3,31 +3,31 @@ 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.dddmodules.infrastructure + com.baeldung.dddcontexts.infrastructure infrastructure 1.0 jar - com.baeldung.dddmodules - ddd-modules + com.baeldung.dddcontexts + ddd-contexts 1.0 ../ - com.baeldung.dddmodules.shippingcontext + com.baeldung.dddcontexts.shippingcontext shippingcontext ${appmodules.version} - com.baeldung.dddmodules.ordercontext + com.baeldung.dddcontexts.ordercontext ordercontext ${appmodules.version} - com.baeldung.dddmodules.sharedkernel + com.baeldung.dddcontexts.sharedkernel sharedkernel ${appmodules.version} diff --git a/ddd-modules/infrastructure/src/main/java/com/baeldung/dddmodules/infrastructure/db/InMemoryOrderStore.java b/ddd-contexts/infrastructure/src/main/java/com/baeldung/dddcontexts/infrastructure/db/InMemoryOrderStore.java similarity index 85% rename from ddd-modules/infrastructure/src/main/java/com/baeldung/dddmodules/infrastructure/db/InMemoryOrderStore.java rename to ddd-contexts/infrastructure/src/main/java/com/baeldung/dddcontexts/infrastructure/db/InMemoryOrderStore.java index 13deb2471e..8424afff79 100644 --- a/ddd-modules/infrastructure/src/main/java/com/baeldung/dddmodules/infrastructure/db/InMemoryOrderStore.java +++ b/ddd-contexts/infrastructure/src/main/java/com/baeldung/dddcontexts/infrastructure/db/InMemoryOrderStore.java @@ -1,10 +1,10 @@ -package com.baeldung.dddmodules.infrastructure.db; +package com.baeldung.dddcontexts.infrastructure.db; -import com.baeldung.dddmodules.ordercontext.model.CustomerOrder; -import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository; -import com.baeldung.dddmodules.shippingcontext.model.PackageItem; -import com.baeldung.dddmodules.shippingcontext.model.ShippableOrder; -import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository; +import com.baeldung.dddcontexts.ordercontext.model.CustomerOrder; +import com.baeldung.dddcontexts.ordercontext.repository.CustomerOrderRepository; +import com.baeldung.dddcontexts.shippingcontext.model.PackageItem; +import com.baeldung.dddcontexts.shippingcontext.model.ShippableOrder; +import com.baeldung.dddcontexts.shippingcontext.repository.ShippingOrderRepository; import java.util.HashMap; import java.util.List; diff --git a/ddd-modules/infrastructure/src/main/java/com/baeldung/dddmodules/infrastructure/events/SimpleEventBus.java b/ddd-contexts/infrastructure/src/main/java/com/baeldung/dddcontexts/infrastructure/events/SimpleEventBus.java similarity index 82% rename from ddd-modules/infrastructure/src/main/java/com/baeldung/dddmodules/infrastructure/events/SimpleEventBus.java rename to ddd-contexts/infrastructure/src/main/java/com/baeldung/dddcontexts/infrastructure/events/SimpleEventBus.java index 6aea7ff6e9..1cbcf13749 100644 --- a/ddd-modules/infrastructure/src/main/java/com/baeldung/dddmodules/infrastructure/events/SimpleEventBus.java +++ b/ddd-contexts/infrastructure/src/main/java/com/baeldung/dddcontexts/infrastructure/events/SimpleEventBus.java @@ -1,8 +1,8 @@ -package com.baeldung.dddmodules.infrastructure.events; +package com.baeldung.dddcontexts.infrastructure.events; -import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent; -import com.baeldung.dddmodules.sharedkernel.events.EventBus; -import com.baeldung.dddmodules.sharedkernel.events.EventSubscriber; +import com.baeldung.dddcontexts.sharedkernel.events.ApplicationEvent; +import com.baeldung.dddcontexts.sharedkernel.events.EventBus; +import com.baeldung.dddcontexts.sharedkernel.events.EventSubscriber; import java.util.Map; import java.util.Set; diff --git a/ddd-contexts/infrastructure/src/main/java/module-info.java b/ddd-contexts/infrastructure/src/main/java/module-info.java new file mode 100644 index 0000000000..1387de16c2 --- /dev/null +++ b/ddd-contexts/infrastructure/src/main/java/module-info.java @@ -0,0 +1,14 @@ +import com.baeldung.dddcontexts.infrastructure.db.InMemoryOrderStore; +import com.baeldung.dddcontexts.infrastructure.events.SimpleEventBus; + +module com.baeldung.dddcontexts.infrastructure { + requires transitive com.baeldung.dddcontexts.sharedkernel; + requires transitive com.baeldung.dddcontexts.ordercontext; + requires transitive com.baeldung.dddcontexts.shippingcontext; + provides com.baeldung.dddcontexts.sharedkernel.events.EventBus + with SimpleEventBus; + provides com.baeldung.dddcontexts.ordercontext.repository.CustomerOrderRepository + with InMemoryOrderStore; + provides com.baeldung.dddcontexts.shippingcontext.repository.ShippingOrderRepository + with InMemoryOrderStore; +} diff --git a/ddd-modules/mainapp/pom.xml b/ddd-contexts/mainapp/pom.xml similarity index 86% rename from ddd-modules/mainapp/pom.xml rename to ddd-contexts/mainapp/pom.xml index a2d3b8f3ea..8046ae4e7d 100644 --- a/ddd-modules/mainapp/pom.xml +++ b/ddd-contexts/mainapp/pom.xml @@ -3,21 +3,21 @@ 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.dddmodules.mainapp + com.baeldung.dddcontexts.mainapp mainapp 1.0 jar - com.baeldung.dddmodules - ddd-modules + com.baeldung.dddcontexts + ddd-contexts 1.0 ../ - com.baeldung.dddmodules.infrastructure + com.baeldung.dddcontexts.infrastructure infrastructure ${appmodules.version} diff --git a/ddd-modules/mainapp/src/main/java/com/baeldung/dddmodules/mainapp/Application.java b/ddd-contexts/mainapp/src/main/java/com/baeldung/dddcontexts/mainapp/Application.java similarity index 80% rename from ddd-modules/mainapp/src/main/java/com/baeldung/dddmodules/mainapp/Application.java rename to ddd-contexts/mainapp/src/main/java/com/baeldung/dddcontexts/mainapp/Application.java index 05e27abe30..ff866e49dd 100644 --- a/ddd-modules/mainapp/src/main/java/com/baeldung/dddmodules/mainapp/Application.java +++ b/ddd-contexts/mainapp/src/main/java/com/baeldung/dddcontexts/mainapp/Application.java @@ -1,12 +1,12 @@ -package com.baeldung.dddmodules.mainapp; +package com.baeldung.dddcontexts.mainapp; -import com.baeldung.dddmodules.ordercontext.model.CustomerOrder; -import com.baeldung.dddmodules.ordercontext.model.OrderItem; -import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository; -import com.baeldung.dddmodules.ordercontext.service.OrderService; -import com.baeldung.dddmodules.sharedkernel.events.EventBus; -import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository; -import com.baeldung.dddmodules.shippingcontext.service.ShippingService; +import com.baeldung.dddcontexts.ordercontext.model.CustomerOrder; +import com.baeldung.dddcontexts.ordercontext.model.OrderItem; +import com.baeldung.dddcontexts.ordercontext.repository.CustomerOrderRepository; +import com.baeldung.dddcontexts.ordercontext.service.OrderService; +import com.baeldung.dddcontexts.sharedkernel.events.EventBus; +import com.baeldung.dddcontexts.shippingcontext.repository.ShippingOrderRepository; +import com.baeldung.dddcontexts.shippingcontext.service.ShippingService; import java.util.*; diff --git a/ddd-contexts/mainapp/src/main/java/module-info.java b/ddd-contexts/mainapp/src/main/java/module-info.java new file mode 100644 index 0000000000..b71e474111 --- /dev/null +++ b/ddd-contexts/mainapp/src/main/java/module-info.java @@ -0,0 +1,8 @@ +module com.baeldung.dddcontexts.mainapp { + uses com.baeldung.dddcontexts.sharedkernel.events.EventBus; + uses com.baeldung.dddcontexts.ordercontext.service.OrderService; + uses com.baeldung.dddcontexts.ordercontext.repository.CustomerOrderRepository; + uses com.baeldung.dddcontexts.shippingcontext.repository.ShippingOrderRepository; + uses com.baeldung.dddcontexts.shippingcontext.service.ShippingService; + requires transitive com.baeldung.dddcontexts.infrastructure; +} \ No newline at end of file diff --git a/ddd-modules/ordercontext/pom.xml b/ddd-contexts/ordercontext/pom.xml similarity index 84% rename from ddd-modules/ordercontext/pom.xml rename to ddd-contexts/ordercontext/pom.xml index eaf44badd3..e29f109b71 100644 --- a/ddd-modules/ordercontext/pom.xml +++ b/ddd-contexts/ordercontext/pom.xml @@ -3,20 +3,20 @@ 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.dddmodules.ordercontext + com.baeldung.dddcontexts.ordercontext ordercontext 1.0 jar - com.baeldung.dddmodules - ddd-modules + com.baeldung.dddcontexts + ddd-contexts 1.0 - com.baeldung.dddmodules.sharedkernel + com.baeldung.dddcontexts.sharedkernel sharedkernel ${appmodules.version} diff --git a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/model/CustomerOrder.java b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/model/CustomerOrder.java similarity index 95% rename from ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/model/CustomerOrder.java rename to ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/model/CustomerOrder.java index ee87de56bd..8a69e8b805 100644 --- a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/model/CustomerOrder.java +++ b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/model/CustomerOrder.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.ordercontext.model; +package com.baeldung.dddcontexts.ordercontext.model; import java.util.List; diff --git a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/model/OrderItem.java b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/model/OrderItem.java similarity index 95% rename from ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/model/OrderItem.java rename to ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/model/OrderItem.java index aaad0777e4..87b8fea260 100644 --- a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/model/OrderItem.java +++ b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/model/OrderItem.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.ordercontext.model; +package com.baeldung.dddcontexts.ordercontext.model; public class OrderItem { private int productId; diff --git a/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/repository/CustomerOrderRepository.java b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/repository/CustomerOrderRepository.java new file mode 100644 index 0000000000..15d1e70981 --- /dev/null +++ b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/repository/CustomerOrderRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.dddcontexts.ordercontext.repository; + +import com.baeldung.dddcontexts.ordercontext.model.CustomerOrder; + +public interface CustomerOrderRepository { + void saveCustomerOrder(CustomerOrder order); +} diff --git a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/service/CustomerOrderService.java b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/service/CustomerOrderService.java similarity index 76% rename from ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/service/CustomerOrderService.java rename to ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/service/CustomerOrderService.java index b9d26e6212..c017f36ca5 100644 --- a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/service/CustomerOrderService.java +++ b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/service/CustomerOrderService.java @@ -1,9 +1,9 @@ -package com.baeldung.dddmodules.ordercontext.service; +package com.baeldung.dddcontexts.ordercontext.service; -import com.baeldung.dddmodules.ordercontext.model.CustomerOrder; -import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository; -import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent; -import com.baeldung.dddmodules.sharedkernel.events.EventBus; +import com.baeldung.dddcontexts.ordercontext.model.CustomerOrder; +import com.baeldung.dddcontexts.ordercontext.repository.CustomerOrderRepository; +import com.baeldung.dddcontexts.sharedkernel.events.ApplicationEvent; +import com.baeldung.dddcontexts.sharedkernel.events.EventBus; import java.util.HashMap; import java.util.Map; diff --git a/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/service/OrderService.java b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/service/OrderService.java new file mode 100644 index 0000000000..94e9dcc7fc --- /dev/null +++ b/ddd-contexts/ordercontext/src/main/java/com/baeldung/dddcontexts/ordercontext/service/OrderService.java @@ -0,0 +1,11 @@ +package com.baeldung.dddcontexts.ordercontext.service; + +import com.baeldung.dddcontexts.ordercontext.model.CustomerOrder; +import com.baeldung.dddcontexts.ordercontext.repository.CustomerOrderRepository; +import com.baeldung.dddcontexts.sharedkernel.service.ApplicationService; + +public interface OrderService extends ApplicationService { + void placeOrder(CustomerOrder order); + + void setOrderRepository(CustomerOrderRepository orderRepository); +} diff --git a/ddd-contexts/ordercontext/src/main/java/module-info.java b/ddd-contexts/ordercontext/src/main/java/module-info.java new file mode 100644 index 0000000000..681565ab4d --- /dev/null +++ b/ddd-contexts/ordercontext/src/main/java/module-info.java @@ -0,0 +1,8 @@ +module com.baeldung.dddcontexts.ordercontext { + requires com.baeldung.dddcontexts.sharedkernel; + exports com.baeldung.dddcontexts.ordercontext.service; + exports com.baeldung.dddcontexts.ordercontext.model; + exports com.baeldung.dddcontexts.ordercontext.repository; + provides com.baeldung.dddcontexts.ordercontext.service.OrderService + with com.baeldung.dddcontexts.ordercontext.service.CustomerOrderService; +} \ No newline at end of file diff --git a/ddd-modules/pom.xml b/ddd-contexts/pom.xml similarity index 94% rename from ddd-modules/pom.xml rename to ddd-contexts/pom.xml index d2932ee515..1a764a65b9 100644 --- a/ddd-modules/pom.xml +++ b/ddd-contexts/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.dddmodules - ddd-modules + com.baeldung.dddcontexts + ddd-contexts 1.0 - ddd-modules + ddd-contexts pom diff --git a/ddd-modules/sharedkernel/pom.xml b/ddd-contexts/sharedkernel/pom.xml similarity index 85% rename from ddd-modules/sharedkernel/pom.xml rename to ddd-contexts/sharedkernel/pom.xml index 3966e1c26e..5d31973c92 100644 --- a/ddd-modules/sharedkernel/pom.xml +++ b/ddd-contexts/sharedkernel/pom.xml @@ -3,14 +3,14 @@ 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.dddmodules.sharedkernel + com.baeldung.dddcontexts.sharedkernel sharedkernel 1.0 jar - com.baeldung.dddmodules - ddd-modules + com.baeldung.dddcontexts + ddd-contexts 1.0 diff --git a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/ApplicationEvent.java b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/ApplicationEvent.java similarity index 88% rename from ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/ApplicationEvent.java rename to ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/ApplicationEvent.java index e3c3ebaf0e..7db89e36e0 100644 --- a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/ApplicationEvent.java +++ b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/ApplicationEvent.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.sharedkernel.events; +package com.baeldung.dddcontexts.sharedkernel.events; import java.util.Map; diff --git a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/EventBus.java b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/EventBus.java similarity index 83% rename from ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/EventBus.java rename to ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/EventBus.java index b128b959e9..be95de674d 100644 --- a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/EventBus.java +++ b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/EventBus.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.sharedkernel.events; +package com.baeldung.dddcontexts.sharedkernel.events; public interface EventBus { void publish(E event); diff --git a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/EventSubscriber.java b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/EventSubscriber.java similarity index 63% rename from ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/EventSubscriber.java rename to ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/EventSubscriber.java index 0d6d48cc33..f941514024 100644 --- a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/events/EventSubscriber.java +++ b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/events/EventSubscriber.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.sharedkernel.events; +package com.baeldung.dddcontexts.sharedkernel.events; public interface EventSubscriber { void onEvent(E event); diff --git a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/service/ApplicationService.java b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/service/ApplicationService.java similarity index 76% rename from ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/service/ApplicationService.java rename to ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/service/ApplicationService.java index 5ef57ae269..a9f4488d90 100644 --- a/ddd-modules/sharedkernel/src/main/java/com/baeldung/dddmodules/sharedkernel/service/ApplicationService.java +++ b/ddd-contexts/sharedkernel/src/main/java/com/baeldung/dddcontexts/sharedkernel/service/ApplicationService.java @@ -1,8 +1,8 @@ -package com.baeldung.dddmodules.sharedkernel.service; +package com.baeldung.dddcontexts.sharedkernel.service; -import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent; -import com.baeldung.dddmodules.sharedkernel.events.EventBus; -import com.baeldung.dddmodules.sharedkernel.events.EventSubscriber; +import com.baeldung.dddcontexts.sharedkernel.events.ApplicationEvent; +import com.baeldung.dddcontexts.sharedkernel.events.EventBus; +import com.baeldung.dddcontexts.sharedkernel.events.EventSubscriber; public interface ApplicationService { diff --git a/ddd-contexts/sharedkernel/src/main/java/module-info.java b/ddd-contexts/sharedkernel/src/main/java/module-info.java new file mode 100644 index 0000000000..f093924aed --- /dev/null +++ b/ddd-contexts/sharedkernel/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module com.baeldung.dddcontexts.sharedkernel { + exports com.baeldung.dddcontexts.sharedkernel.events; + exports com.baeldung.dddcontexts.sharedkernel.service; +} diff --git a/ddd-modules/shippingcontext/pom.xml b/ddd-contexts/shippingcontext/pom.xml similarity index 82% rename from ddd-modules/shippingcontext/pom.xml rename to ddd-contexts/shippingcontext/pom.xml index a6e6167b69..2fb9e83645 100644 --- a/ddd-modules/shippingcontext/pom.xml +++ b/ddd-contexts/shippingcontext/pom.xml @@ -3,20 +3,20 @@ 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.dddmodules.shippingcontext + com.baeldung.dddcontexts.shippingcontext shippingcontext 1.0 jar - com.baeldung.dddmodules - ddd-modules + com.baeldung.dddcontexts + ddd-contexts 1.0 - com.baeldung.dddmodules.sharedkernel + com.baeldung.dddcontexts.sharedkernel sharedkernel ${appmodules.version} diff --git a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/PackageItem.java b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/PackageItem.java similarity index 93% rename from ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/PackageItem.java rename to ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/PackageItem.java index ed09a0f2a2..0e4da42cec 100644 --- a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/PackageItem.java +++ b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/PackageItem.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.shippingcontext.model; +package com.baeldung.dddcontexts.shippingcontext.model; public class PackageItem { private int productId; diff --git a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/Parcel.java b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/Parcel.java similarity index 95% rename from ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/Parcel.java rename to ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/Parcel.java index 70c4f06ac6..ee24818fb0 100644 --- a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/Parcel.java +++ b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/Parcel.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.shippingcontext.model; +package com.baeldung.dddcontexts.shippingcontext.model; import java.util.List; diff --git a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/ShippableOrder.java b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/ShippableOrder.java similarity index 93% rename from ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/ShippableOrder.java rename to ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/ShippableOrder.java index afeea2f472..97daaf681e 100644 --- a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/model/ShippableOrder.java +++ b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/model/ShippableOrder.java @@ -1,4 +1,4 @@ -package com.baeldung.dddmodules.shippingcontext.model; +package com.baeldung.dddcontexts.shippingcontext.model; import java.util.List; diff --git a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/repository/ShippingOrderRepository.java b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/repository/ShippingOrderRepository.java similarity index 51% rename from ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/repository/ShippingOrderRepository.java rename to ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/repository/ShippingOrderRepository.java index b1a643f989..ba01d8e39c 100644 --- a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/repository/ShippingOrderRepository.java +++ b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/repository/ShippingOrderRepository.java @@ -1,6 +1,6 @@ -package com.baeldung.dddmodules.shippingcontext.repository; +package com.baeldung.dddcontexts.shippingcontext.repository; -import com.baeldung.dddmodules.shippingcontext.model.ShippableOrder; +import com.baeldung.dddcontexts.shippingcontext.model.ShippableOrder; import java.util.Optional; diff --git a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/service/ParcelShippingService.java b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/service/ParcelShippingService.java similarity index 78% rename from ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/service/ParcelShippingService.java rename to ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/service/ParcelShippingService.java index 05f261612e..70c0970e8b 100644 --- a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/service/ParcelShippingService.java +++ b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/service/ParcelShippingService.java @@ -1,11 +1,11 @@ -package com.baeldung.dddmodules.shippingcontext.service; +package com.baeldung.dddcontexts.shippingcontext.service; -import com.baeldung.dddmodules.sharedkernel.events.ApplicationEvent; -import com.baeldung.dddmodules.sharedkernel.events.EventBus; -import com.baeldung.dddmodules.sharedkernel.events.EventSubscriber; -import com.baeldung.dddmodules.shippingcontext.model.Parcel; -import com.baeldung.dddmodules.shippingcontext.model.ShippableOrder; -import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository; +import com.baeldung.dddcontexts.sharedkernel.events.ApplicationEvent; +import com.baeldung.dddcontexts.sharedkernel.events.EventBus; +import com.baeldung.dddcontexts.sharedkernel.events.EventSubscriber; +import com.baeldung.dddcontexts.shippingcontext.model.Parcel; +import com.baeldung.dddcontexts.shippingcontext.model.ShippableOrder; +import com.baeldung.dddcontexts.shippingcontext.repository.ShippingOrderRepository; import java.util.HashMap; import java.util.Map; diff --git a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/service/ShippingService.java b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/service/ShippingService.java similarity index 50% rename from ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/service/ShippingService.java rename to ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/service/ShippingService.java index a2f0095c43..b78a0f9fb2 100644 --- a/ddd-modules/shippingcontext/src/main/java/com/baeldung/dddmodules/shippingcontext/service/ShippingService.java +++ b/ddd-contexts/shippingcontext/src/main/java/com/baeldung/dddcontexts/shippingcontext/service/ShippingService.java @@ -1,8 +1,8 @@ -package com.baeldung.dddmodules.shippingcontext.service; +package com.baeldung.dddcontexts.shippingcontext.service; -import com.baeldung.dddmodules.sharedkernel.service.ApplicationService; -import com.baeldung.dddmodules.shippingcontext.model.Parcel; -import com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository; +import com.baeldung.dddcontexts.sharedkernel.service.ApplicationService; +import com.baeldung.dddcontexts.shippingcontext.model.Parcel; +import com.baeldung.dddcontexts.shippingcontext.repository.ShippingOrderRepository; import java.util.Optional; diff --git a/ddd-contexts/shippingcontext/src/main/java/module-info.java b/ddd-contexts/shippingcontext/src/main/java/module-info.java new file mode 100644 index 0000000000..c53cbedf8a --- /dev/null +++ b/ddd-contexts/shippingcontext/src/main/java/module-info.java @@ -0,0 +1,8 @@ +module com.baeldung.dddcontexts.shippingcontext { + requires com.baeldung.dddcontexts.sharedkernel; + exports com.baeldung.dddcontexts.shippingcontext.service; + exports com.baeldung.dddcontexts.shippingcontext.model; + exports com.baeldung.dddcontexts.shippingcontext.repository; + provides com.baeldung.dddcontexts.shippingcontext.service.ShippingService + with com.baeldung.dddcontexts.shippingcontext.service.ParcelShippingService; +} diff --git a/ddd-modules/infrastructure/src/main/java/module-info.java b/ddd-modules/infrastructure/src/main/java/module-info.java deleted file mode 100644 index 19f7b36548..0000000000 --- a/ddd-modules/infrastructure/src/main/java/module-info.java +++ /dev/null @@ -1,11 +0,0 @@ -module com.baeldung.dddmodules.infrastructure { - requires transitive com.baeldung.dddmodules.sharedkernel; - requires transitive com.baeldung.dddmodules.ordercontext; - requires transitive com.baeldung.dddmodules.shippingcontext; - provides com.baeldung.dddmodules.sharedkernel.events.EventBus - with com.baeldung.dddmodules.infrastructure.events.SimpleEventBus; - provides com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository - with com.baeldung.dddmodules.infrastructure.db.InMemoryOrderStore; - provides com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository - with com.baeldung.dddmodules.infrastructure.db.InMemoryOrderStore; -} diff --git a/ddd-modules/mainapp/src/main/java/module-info.java b/ddd-modules/mainapp/src/main/java/module-info.java deleted file mode 100644 index 356b03731c..0000000000 --- a/ddd-modules/mainapp/src/main/java/module-info.java +++ /dev/null @@ -1,8 +0,0 @@ -module com.baeldung.dddmodules.mainapp { - uses com.baeldung.dddmodules.sharedkernel.events.EventBus; - uses com.baeldung.dddmodules.ordercontext.service.OrderService; - uses com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository; - uses com.baeldung.dddmodules.shippingcontext.repository.ShippingOrderRepository; - uses com.baeldung.dddmodules.shippingcontext.service.ShippingService; - requires transitive com.baeldung.dddmodules.infrastructure; -} \ No newline at end of file diff --git a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/repository/CustomerOrderRepository.java b/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/repository/CustomerOrderRepository.java deleted file mode 100644 index 771bbf3301..0000000000 --- a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/repository/CustomerOrderRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.baeldung.dddmodules.ordercontext.repository; - -import com.baeldung.dddmodules.ordercontext.model.CustomerOrder; - -public interface CustomerOrderRepository { - void saveCustomerOrder(CustomerOrder order); -} diff --git a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/service/OrderService.java b/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/service/OrderService.java deleted file mode 100644 index 1bbb8b8398..0000000000 --- a/ddd-modules/ordercontext/src/main/java/com/baeldung/dddmodules/ordercontext/service/OrderService.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.dddmodules.ordercontext.service; - -import com.baeldung.dddmodules.ordercontext.model.CustomerOrder; -import com.baeldung.dddmodules.ordercontext.repository.CustomerOrderRepository; -import com.baeldung.dddmodules.sharedkernel.service.ApplicationService; - -public interface OrderService extends ApplicationService { - void placeOrder(CustomerOrder order); - - void setOrderRepository(CustomerOrderRepository orderRepository); -} diff --git a/ddd-modules/ordercontext/src/main/java/module-info.java b/ddd-modules/ordercontext/src/main/java/module-info.java deleted file mode 100644 index e9b7cf9535..0000000000 --- a/ddd-modules/ordercontext/src/main/java/module-info.java +++ /dev/null @@ -1,8 +0,0 @@ -module com.baeldung.dddmodules.ordercontext { - requires com.baeldung.dddmodules.sharedkernel; - exports com.baeldung.dddmodules.ordercontext.service; - exports com.baeldung.dddmodules.ordercontext.model; - exports com.baeldung.dddmodules.ordercontext.repository; - provides com.baeldung.dddmodules.ordercontext.service.OrderService - with com.baeldung.dddmodules.ordercontext.service.CustomerOrderService; -} \ No newline at end of file diff --git a/ddd-modules/sharedkernel/src/main/java/module-info.java b/ddd-modules/sharedkernel/src/main/java/module-info.java deleted file mode 100644 index aeb64f52c9..0000000000 --- a/ddd-modules/sharedkernel/src/main/java/module-info.java +++ /dev/null @@ -1,4 +0,0 @@ -module com.baeldung.dddmodules.sharedkernel { - exports com.baeldung.dddmodules.sharedkernel.events; - exports com.baeldung.dddmodules.sharedkernel.service; -} diff --git a/ddd-modules/shippingcontext/src/main/java/module-info.java b/ddd-modules/shippingcontext/src/main/java/module-info.java deleted file mode 100644 index a5ec1ca435..0000000000 --- a/ddd-modules/shippingcontext/src/main/java/module-info.java +++ /dev/null @@ -1,8 +0,0 @@ -module com.baeldung.dddmodules.shippingcontext { - requires com.baeldung.dddmodules.sharedkernel; - exports com.baeldung.dddmodules.shippingcontext.service; - exports com.baeldung.dddmodules.shippingcontext.model; - exports com.baeldung.dddmodules.shippingcontext.repository; - provides com.baeldung.dddmodules.shippingcontext.service.ShippingService - with com.baeldung.dddmodules.shippingcontext.service.ParcelShippingService; -} diff --git a/docker/docker-caching/multi-module-caching/core/pom.xml b/docker/docker-caching/multi-module-caching/core/pom.xml index eeeb5a6e5b..bcfc4b5783 100644 --- a/docker/docker-caching/multi-module-caching/core/pom.xml +++ b/docker/docker-caching/multi-module-caching/core/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 core @@ -22,4 +22,5 @@ 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 7968114385..7e279dc334 100644 --- a/docker/docker-caching/multi-module-caching/pom.xml +++ b/docker/docker-caching/multi-module-caching/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 com.baeldung multi-module-caching @@ -8,22 +9,24 @@ Multi-module Maven caching example pom + + runner + core + + com.google.guava guava - 31.0.1-jre + ${guava.version} 1.8 + 31.0.1-jre - - runner - core - - + \ No newline at end of file diff --git a/docker/docker-caching/multi-module-caching/runner/pom.xml b/docker/docker-caching/multi-module-caching/runner/pom.xml index e3654bff17..e3f234bac0 100644 --- a/docker/docker-caching/multi-module-caching/runner/pom.xml +++ b/docker/docker-caching/multi-module-caching/runner/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 runner @@ -53,4 +53,5 @@ 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 386b040138..d7f96e1e7e 100644 --- a/docker/docker-caching/single-module-caching/pom.xml +++ b/docker/docker-caching/single-module-caching/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 - com.baeldung single-module-caching 1.0-SNAPSHOT @@ -12,7 +11,7 @@ com.google.guava guava - 31.0.1-jre + ${guava.version} @@ -49,5 +48,7 @@ 8 8 + 31.0.1-jre + \ No newline at end of file diff --git a/docker/docker-internal-dto/pom.xml b/docker/docker-internal-dto/pom.xml index 55cef257fe..09013d2fc3 100644 --- a/docker/docker-internal-dto/pom.xml +++ b/docker/docker-internal-dto/pom.xml @@ -3,13 +3,13 @@ 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 + docker-internal-dto + docker-internal-dto + com.baeldung.docker docker 0.0.1 - docker-internal-dto - docker-internal-dto - diff --git a/docker/docker-push-to-private-repo/.gitignore b/docker/docker-push-to-private-repo/.gitignore new file mode 100644 index 0000000000..549e00a2a9 --- /dev/null +++ b/docker/docker-push-to-private-repo/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/docker/docker-push-to-private-repo/Dockerfile b/docker/docker-push-to-private-repo/Dockerfile new file mode 100644 index 0000000000..42a13e2a93 --- /dev/null +++ b/docker/docker-push-to-private-repo/Dockerfile @@ -0,0 +1,4 @@ +FROM openjdk:11 +ARG JAR_FILE=target/*.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/docker/docker-push-to-private-repo/README.md b/docker/docker-push-to-private-repo/README.md new file mode 100644 index 0000000000..61fe00e016 --- /dev/null +++ b/docker/docker-push-to-private-repo/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Pushing a Docker Image to a Private Repository](https://www.baeldung.com/ops/docker-push-image-to-private-repository) diff --git a/docker/docker-push-to-private-repo/pom.xml b/docker/docker-push-to-private-repo/pom.xml new file mode 100644 index 0000000000..19be098794 --- /dev/null +++ b/docker/docker-push-to-private-repo/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + docker-push-to-private-repo + 0.0.1-SNAPSHOT + docker-push-to-private-repo + Example application to showcase how to push a docker image to a private repository + + + com.baeldung.docker + docker + 0.0.1 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 11 + + + \ No newline at end of file diff --git a/docker/docker-push-to-private-repo/src/main/java/com/baeldung/docker/push/HelloWorldController.java b/docker/docker-push-to-private-repo/src/main/java/com/baeldung/docker/push/HelloWorldController.java new file mode 100644 index 0000000000..58486c3086 --- /dev/null +++ b/docker/docker-push-to-private-repo/src/main/java/com/baeldung/docker/push/HelloWorldController.java @@ -0,0 +1,12 @@ +package com.baeldung.docker.push; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloWorldController { + @GetMapping("/helloworld") + String helloWorld() { + return "Hello World!"; + } +} \ No newline at end of file diff --git a/docker/docker-push-to-private-repo/src/main/java/com/baeldung/docker/push/PushToPrivateRepoApplication.java b/docker/docker-push-to-private-repo/src/main/java/com/baeldung/docker/push/PushToPrivateRepoApplication.java new file mode 100644 index 0000000000..7f516b3158 --- /dev/null +++ b/docker/docker-push-to-private-repo/src/main/java/com/baeldung/docker/push/PushToPrivateRepoApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.docker.push; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PushToPrivateRepoApplication { + + public static void main(String[] args) { + SpringApplication.run(PushToPrivateRepoApplication.class, args); + } + +} diff --git a/docker/docker-push-to-private-repo/src/main/resources/application.properties b/docker/docker-push-to-private-repo/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/docker/docker-push-to-private-repo/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml index 6841fabcee..24fede56fd 100644 --- a/docker/docker-sample-app/pom.xml +++ b/docker/docker-sample-app/pom.xml @@ -1,21 +1,18 @@ - + 4.0.0 + docker-sample-app + docker-sample-app + Demo project for Spring Boot and Docker + com.baeldung.docker docker 0.0.1 - docker-sample-app - docker-sample-app - Demo project for Spring Boot and Docker - - - 11 - - org.springframework.boot @@ -42,4 +39,8 @@ - + + 11 + + + \ No newline at end of file diff --git a/docker/docker-spring-boot-postgres/pom.xml b/docker/docker-spring-boot-postgres/pom.xml index d08ae130db..7a4ed1db3c 100644 --- a/docker/docker-spring-boot-postgres/pom.xml +++ b/docker/docker-spring-boot-postgres/pom.xml @@ -1,13 +1,14 @@ - - 4.0.0 - com.baeldung.docker - docker-spring-boot-postgres - 0.0.1-SNAPSHOT - docker-spring-boot-postgres - Demo project showing Spring Boot, PostgreSQL, and Docker - + + 4.0.0 + com.baeldung.docker + docker-spring-boot-postgres + 0.0.1-SNAPSHOT + docker-spring-boot-postgres + Demo project showing Spring Boot, PostgreSQL, and Docker + com.baeldung parent-boot-2 @@ -15,33 +16,32 @@ ../../parent-boot-2 - - - org.springframework.boot - spring-boot-starter-data-jpa - + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.postgresql + postgresql + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + - - org.postgresql - postgresql - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - - 11 diff --git a/docker/docker-spring-boot/README.md b/docker/docker-spring-boot/README.md index 4af9378290..0fc9d2b6b5 100644 --- a/docker/docker-spring-boot/README.md +++ b/docker/docker-spring-boot/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Creating Docker Images with Spring Boot](https://www.baeldung.com/spring-boot-docker-images) +- [Starting Spring Boot Application in Docker With Profile](https://www.baeldung.com/spring-boot-docker-start-with-profile) diff --git a/docker/docker-spring-boot/mvnw b/docker/docker-spring-boot/mvnw deleted file mode 100755 index a16b5431b4..0000000000 --- a/docker/docker-spring-boot/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/docker/docker-spring-boot/mvnw.cmd b/docker/docker-spring-boot/mvnw.cmd deleted file mode 100644 index c8d43372c9..0000000000 --- a/docker/docker-spring-boot/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% diff --git a/docker/docker-spring-boot/pom.xml b/docker/docker-spring-boot/pom.xml index 74bd1561cf..69d25e374b 100644 --- a/docker/docker-spring-boot/pom.xml +++ b/docker/docker-spring-boot/pom.xml @@ -3,33 +3,21 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + docker-spring-boot + docker-spring-boot + Demo project showing Spring Boot and Docker + com.baeldung.docker docker 0.0.1 - docker-spring-boot - - docker-spring-boot - Demo project showing Spring Boot and Docker - - - 11 - - org.springframework.boot spring-boot-starter-web - - - com.baeldung.docker - docker-internal-dto - 0.0.1 - - org.springframework.boot spring-boot-starter-test @@ -54,8 +42,19 @@ ${project.basedir}/src/layers.xml + + + + repackage + + + - + + 11 + + + \ No newline at end of file diff --git a/docker/docker-spring-boot/src/main/docker/springprofile/Dockerfile b/docker/docker-spring-boot/src/main/docker/springprofile/Dockerfile new file mode 100644 index 0000000000..f06f08cff6 --- /dev/null +++ b/docker/docker-spring-boot/src/main/docker/springprofile/Dockerfile @@ -0,0 +1,11 @@ +# To build and run docker-with-spring-profile: +# +# docker build -f src/main/docker/springprofile/Dockerfile --tag=docker-with-spring-profile:latest . +# docker run docker-with-spring-profile:latest +# +# To run with profiles: +# docker run -e "SPRING_PROFILES_ACTIVE=test1,test2,test3" docker-with-spring-profile:latest + +FROM openjdk:11 +COPY target/*.jar app.jar +ENTRYPOINT ["java", "-jar", "/app.jar"] diff --git a/docker/docker-spring-boot/src/main/docker/springprofile/docker-compose-prod.yml b/docker/docker-spring-boot/src/main/docker/springprofile/docker-compose-prod.yml new file mode 100644 index 0000000000..1892a38ae6 --- /dev/null +++ b/docker/docker-spring-boot/src/main/docker/springprofile/docker-compose-prod.yml @@ -0,0 +1,6 @@ +version: "3.5" +services: + docker-with-spring-profile: + image: docker-with-spring-profile:latest + environment: + - "SPRING_PROFILES_ACTIVE=prod" diff --git a/docker/docker-spring-boot/src/main/docker/springprofile/docker-compose-test.yml b/docker/docker-spring-boot/src/main/docker/springprofile/docker-compose-test.yml new file mode 100644 index 0000000000..780ebcb63f --- /dev/null +++ b/docker/docker-spring-boot/src/main/docker/springprofile/docker-compose-test.yml @@ -0,0 +1,6 @@ +version: "3.5" +services: + docker-with-spring-profile: + image: docker-with-spring-profile:latest + environment: + - "SPRING_PROFILES_ACTIVE=test" diff --git a/docker/heap-sizing/pom.xml b/docker/heap-sizing/pom.xml index 2cc354f6cf..32c200c1c0 100644 --- a/docker/heap-sizing/pom.xml +++ b/docker/heap-sizing/pom.xml @@ -48,7 +48,6 @@ com.google.cloud.tools jib-maven-plugin 2.7.1 - heapsizing-demo-jib @@ -62,4 +61,4 @@ 11 - + \ No newline at end of file diff --git a/docker/pom.xml b/docker/pom.xml index 5c6267c6dd..f46ceac963 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -3,14 +3,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.docker docker 0.0.1 docker Demo project showing Spring Boot and Docker pom - + com.baeldung parent-boot-2 @@ -18,16 +17,17 @@ ../parent-boot-2 - - 11 - - docker-internal-dto docker-spring-boot docker-sample-app docker-caching/single-module-caching docker-caching/multi-module-caching + docker-push-to-private-repo - + + 11 + + + \ No newline at end of file diff --git a/feign/pom.xml b/feign/pom.xml index 026afdfc7a..8fa864fa46 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 com.baeldung.feign feign @@ -69,6 +71,7 @@ test + @@ -92,10 +95,8 @@ src/main/resources/users.xsd - - org.jvnet.jaxb2.maven2 maven-jaxb2-plugin @@ -111,7 +112,6 @@ *.xsd - com.baeldung.feign.soap target/generated-sources/jaxb @@ -119,6 +119,6 @@ - + \ No newline at end of file diff --git a/feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java b/feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java new file mode 100644 index 0000000000..70a574ed81 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/builder/BookFeignClientBuilder.java @@ -0,0 +1,34 @@ +package com.baeldung.feign.clients.builder; + +import com.baeldung.feign.header.authorisation.ApiAuthorisationService; +import com.baeldung.feign.header.interceptor.AuthRequestInterceptor; + + +import feign.Feign; +import feign.Logger; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.slf4j.Slf4jLogger; + + +public class BookFeignClientBuilder { + + public static T createClient(Class type, String uri) { + return Feign.builder() + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logger(new Slf4jLogger(type)) + .logLevel(Logger.Level.HEADERS) + .target(type, uri); + } + + public static T createClientWithInterceptor(Class type, String uri) { + return Feign.builder() + .requestInterceptor(new AuthRequestInterceptor(new ApiAuthorisationService())) + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logger(new Slf4jLogger(type)) + .logLevel(Logger.Level.HEADERS) + .target(type, uri); + } +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java new file mode 100644 index 0000000000..2148a90120 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/header/dynamicheader/BookClient.java @@ -0,0 +1,17 @@ +package com.baeldung.feign.clients.header.dynamicheader; + +import com.baeldung.feign.models.Book; + +import feign.HeaderMap; +import feign.Headers; +import feign.RequestLine; + +import java.util.Map; + +@Headers("Content-Type: application/json") +public interface BookClient { + + @RequestLine("POST") + void create(@HeaderMap Map headers, Book book); + +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java new file mode 100644 index 0000000000..cbd2622f9b --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/BookClient.java @@ -0,0 +1,18 @@ +package com.baeldung.feign.clients.header.staticheader; + +import com.baeldung.feign.models.Book; +import com.baeldung.feign.models.BookResource; +import feign.Headers; +import feign.Param; +import feign.RequestLine; + +@Headers("Accept-Language: en-US") +public interface BookClient { + + @RequestLine("GET /{isbn}") + BookResource findByIsbn(@Param("isbn") String isbn); + + @RequestLine("POST") + @Headers("Content-Type: application/json") + void create(Book book); +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java new file mode 100644 index 0000000000..83a273893c --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClient.java @@ -0,0 +1,16 @@ +package com.baeldung.feign.clients.header.staticheader.parameterized; + +import com.baeldung.feign.models.BookResource; + +import feign.Headers; +import feign.Param; +import feign.RequestLine; + + +@Headers("x-requester-id: {requester}") +public interface BookClient { + + @RequestLine("GET /{isbn}") + BookResource findByIsbn(@Param("requester") String requestorId, @Param("isbn") String isbn); + +} diff --git a/feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java b/feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java new file mode 100644 index 0000000000..1a23f968ac --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/header/authorisation/ApiAuthorisationService.java @@ -0,0 +1,11 @@ +package com.baeldung.feign.header.authorisation; + +import java.util.UUID; + +public class ApiAuthorisationService implements AuthorisationService { + + @Override + public String getAuthToken() { + return "Bearer " + UUID.randomUUID(); + } +} diff --git a/feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java b/feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java new file mode 100644 index 0000000000..12e6d59bcc --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/header/authorisation/AuthorisationService.java @@ -0,0 +1,7 @@ +package com.baeldung.feign.header.authorisation; + +public interface AuthorisationService { + + String getAuthToken(); + +} diff --git a/feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java b/feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java new file mode 100644 index 0000000000..eda428de1a --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/header/interceptor/AuthRequestInterceptor.java @@ -0,0 +1,22 @@ +package com.baeldung.feign.header.interceptor; + +import com.baeldung.feign.header.authorisation.AuthorisationService; +import feign.RequestInterceptor; +import feign.RequestTemplate; + + +public class AuthRequestInterceptor implements RequestInterceptor { + + private AuthorisationService authTokenService; + + public AuthRequestInterceptor(AuthorisationService authTokenService) { + this.authTokenService = authTokenService; + } + + @Override + public void apply(RequestTemplate template) { + template.header("Authorisation", authTokenService.getAuthToken()); + } +} + + \ No newline at end of file diff --git a/feign/src/main/resources/logback.xml b/feign/src/main/resources/logback.xml index 7d900d8ea8..e5e962c8e0 100644 --- a/feign/src/main/resources/logback.xml +++ b/feign/src/main/resources/logback.xml @@ -5,9 +5,10 @@ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + - + \ No newline at end of file diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java new file mode 100644 index 0000000000..6e78ba03a6 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/dynamicheader/BookClientLiveTest.java @@ -0,0 +1,38 @@ +package com.baeldung.feign.clients.header.dynamicheader; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClient(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldPostBook() throws Exception { + String isbn = UUID.randomUUID() + .toString(); + + Book book = new Book(isbn, "Me", "It's me!", null, null); + + Map headerMap = new HashMap<>(); + + headerMap.put("metadata-key1", "metadata-value1"); + headerMap.put("metadata-key2", "metadata-value2"); + + bookClient.create(headerMap, book); + } +} diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java new file mode 100644 index 0000000000..2062b86791 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/interceptor/BookClientLiveTest.java @@ -0,0 +1,52 @@ +package com.baeldung.feign.clients.header.interceptor; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.clients.header.staticheader.BookClient; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClientWithInterceptor(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } + + @Test + public void givenBookClient2_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } + + @Test + public 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(); + assertThat(book.getAuthor(), is("Me")); + } +} diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java new file mode 100644 index 0000000000..08b8461fb5 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/BookClientLiveTest.java @@ -0,0 +1,45 @@ +package com.baeldung.feign.clients.header.staticheader; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClient(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } + + @Test + public 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(); + assertThat(book.getAuthor(), is("Me")); + } +} diff --git a/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java new file mode 100644 index 0000000000..94e91b539c --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/header/staticheader/parameterized/BookClientLiveTest.java @@ -0,0 +1,31 @@ +package com.baeldung.feign.clients.header.staticheader.parameterized; + +import com.baeldung.feign.clients.builder.BookFeignClientBuilder; +import com.baeldung.feign.models.Book; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Consumes https://github.com/Baeldung/spring-hypermedia-api + */ +public class BookClientLiveTest { + + private BookClient bookClient; + + private String requester = "test"; + + @Before + public void setup() { + bookClient = BookFeignClientBuilder.createClient(BookClient.class, "http://localhost:8081/api/books"); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn(requester, "0151072558") + .getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + } +} diff --git a/graphql/graphql-dgs/pom.xml b/graphql/graphql-dgs/pom.xml index 6165ae839f..56e261f14d 100644 --- a/graphql/graphql-dgs/pom.xml +++ b/graphql/graphql-dgs/pom.xml @@ -3,16 +3,14 @@ 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.graphql-dgs graphql-dgs 1.0 graphql-dgs - com.baeldung - parent-modules + com.baeldung.graphql + graphql 1.0.0-SNAPSHOT - ../.. @@ -30,39 +28,22 @@ org.springframework.boot - spring-boot-starter - 2.6.2 - - - org.springframework.boot - spring-boot-starter-test - 2.6.2 - test + spring-boot-starter-web com.netflix.graphql.dgs.codegen graphql-dgs-codegen-client-core - 5.1.14 - - - org.springframework.boot - spring-boot-starter-web - 2.6.2 + ${graphql-dgs-codegen-client-core.version} com.netflix.graphql.dgs graphql-dgs-spring-boot-starter - 4.9.15 + ${graphql-dgs-spring-boot-starter.version} - - org.springframework.boot - spring-boot-maven-plugin - 2.6.2 - io.github.deweyjose graphqlcodegen-maven-plugin @@ -84,4 +65,9 @@ + + 5.1.14 + 4.9.15 + + \ No newline at end of file diff --git a/graphql/graphql-error-handling/README.md b/graphql/graphql-error-handling/README.md new file mode 100644 index 0000000000..06a2957ac1 --- /dev/null +++ b/graphql/graphql-error-handling/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Error Handling in GraphQL With Spring Boot](https://www.baeldung.com/spring-graphql-error-handling) diff --git a/graphql/graphql-error-handling/pom.xml b/graphql/graphql-error-handling/pom.xml new file mode 100644 index 0000000000..92696d8ed7 --- /dev/null +++ b/graphql/graphql-error-handling/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + graphql-error-handling + 1.0 + graphql-error-handling + jar + + + com.baeldung.graphql + graphql + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + com.graphql-java + graphql-spring-boot-starter + ${graphql-spring-boot-starter.version} + + + com.graphql-java + graphql-java-tools + ${graphql-java-tools.version} + + + org.projectlombok + lombok + ${lombok.version} + + + com.h2database + h2 + ${h2.version} + + + org.springframework.boot + spring-boot-test + test + + + com.graphql-java + graphql-spring-boot-starter-test + test + ${graphql-spring-boot-starter.version} + + + org.skyscreamer + jsonassert + ${jsonassert.version} + test + + + + + 5.0.2 + 5.2.4 + 1.5.0 + + + \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/GraphQLErrorHandlerApplication.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/GraphQLErrorHandlerApplication.java new file mode 100644 index 0000000000..565c9e0a15 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/GraphQLErrorHandlerApplication.java @@ -0,0 +1,46 @@ +package com.baeldung.graphql.error.handling; + +import com.baeldung.graphql.error.handling.exception.GraphQLErrorAdapter; +import graphql.ExceptionWhileDataFetching; +import graphql.GraphQLError; +import graphql.servlet.GraphQLErrorHandler; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@SpringBootApplication +public class GraphQLErrorHandlerApplication { + public static void main(String[] args) { + SpringApplication.run(GraphQLErrorHandlerApplication.class, args); + } + + @Bean + public GraphQLErrorHandler errorHandler() { + return new GraphQLErrorHandler() { + @Override + public List processErrors(List errors) { + List clientErrors = errors.stream() + .filter(this::isClientError) + .collect(Collectors.toList()); + + List serverErrors = errors.stream() + .filter(e -> !isClientError(e)) + .map(GraphQLErrorAdapter::new) + .collect(Collectors.toList()); + + List e = new ArrayList<>(); + e.addAll(clientErrors); + e.addAll(serverErrors); + return e; + } + + private boolean isClientError(GraphQLError error) { + return !(error instanceof ExceptionWhileDataFetching || error instanceof Throwable); + } + }; + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/domain/Location.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/domain/Location.java new file mode 100644 index 0000000000..815bf3a26a --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/domain/Location.java @@ -0,0 +1,29 @@ +package com.baeldung.graphql.error.handling.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import java.util.ArrayList; +import java.util.List; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Location { + @Id + private String zipcode; + + private String city; + private String state; + + @OneToMany(mappedBy = "location", fetch = FetchType.EAGER) + private List vehicles = new ArrayList<>(); +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/domain/Vehicle.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/domain/Vehicle.java new file mode 100644 index 0000000000..e206bdb009 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/domain/Vehicle.java @@ -0,0 +1,26 @@ +package com.baeldung.graphql.error.handling.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Vehicle { + @Id + private String vin; + private Integer year; + private String make; + private String model; + private String trim; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_location") + private Location location; +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/AbstractGraphQLException.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/AbstractGraphQLException.java new file mode 100644 index 0000000000..4e7be50ae4 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/AbstractGraphQLException.java @@ -0,0 +1,44 @@ +package com.baeldung.graphql.error.handling.exception; + +import graphql.ErrorType; +import graphql.GraphQLError; +import graphql.language.SourceLocation; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AbstractGraphQLException extends RuntimeException implements GraphQLError { + private Map parameters = new HashMap(); + + public AbstractGraphQLException(String message) { + super(message); + } + + public AbstractGraphQLException(String message, Map additionParams) { + this(message); + if (additionParams != null) { + parameters = additionParams; + } + } + + @Override + public String getMessage() { + return super.getMessage(); + } + + @Override + public List getLocations() { + return null; + } + + @Override + public ErrorType getErrorType() { + return null; + } + + @Override + public Map getExtensions() { + return this.parameters; + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/GraphQLErrorAdapter.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/GraphQLErrorAdapter.java new file mode 100644 index 0000000000..d982f98db3 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/GraphQLErrorAdapter.java @@ -0,0 +1,48 @@ +package com.baeldung.graphql.error.handling.exception; + +import graphql.ErrorType; +import graphql.ExceptionWhileDataFetching; +import graphql.GraphQLError; +import graphql.language.SourceLocation; + +import java.util.List; +import java.util.Map; + +public class GraphQLErrorAdapter implements GraphQLError { + + private GraphQLError error; + + public GraphQLErrorAdapter(GraphQLError error) { + this.error = error; + } + + @Override + public Map getExtensions() { + return error.getExtensions(); + } + + @Override + public List getLocations() { + return error.getLocations(); + } + + @Override + public ErrorType getErrorType() { + return error.getErrorType(); + } + + @Override + public List getPath() { + return error.getPath(); + } + + @Override + public Map toSpecification() { + return error.toSpecification(); + } + + @Override + public String getMessage() { + return (error instanceof ExceptionWhileDataFetching) ? ((ExceptionWhileDataFetching) error).getException().getMessage() : error.getMessage(); + } +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/InvalidInputException.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/InvalidInputException.java new file mode 100644 index 0000000000..78c8e83e27 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/InvalidInputException.java @@ -0,0 +1,7 @@ +package com.baeldung.graphql.error.handling.exception; + +public class InvalidInputException extends RuntimeException { + public InvalidInputException(String message) { + super(message); + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/VehicleAlreadyPresentException.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/VehicleAlreadyPresentException.java new file mode 100644 index 0000000000..8f6f0ce615 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/VehicleAlreadyPresentException.java @@ -0,0 +1,14 @@ +package com.baeldung.graphql.error.handling.exception; + +import java.util.Map; + +public class VehicleAlreadyPresentException extends AbstractGraphQLException { + + public VehicleAlreadyPresentException(String message) { + super(message); + } + + public VehicleAlreadyPresentException(String message, Map additionParams) { + super(message, additionParams); + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/VehicleNotFoundException.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/VehicleNotFoundException.java new file mode 100644 index 0000000000..0d2ad8c597 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/exception/VehicleNotFoundException.java @@ -0,0 +1,14 @@ +package com.baeldung.graphql.error.handling.exception; + +import java.util.Map; + +public class VehicleNotFoundException extends AbstractGraphQLException { + + public VehicleNotFoundException(String message) { + super(message); + } + + public VehicleNotFoundException(String message, Map params) { + super(message, params); + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/repository/InventoryRepository.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/repository/InventoryRepository.java new file mode 100644 index 0000000000..f4a0043408 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/repository/InventoryRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.graphql.error.handling.repository; + +import com.baeldung.graphql.error.handling.domain.Vehicle; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface InventoryRepository extends JpaRepository { +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/repository/LocationRepository.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/repository/LocationRepository.java new file mode 100644 index 0000000000..716b8d3ef3 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/repository/LocationRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.graphql.error.handling.repository; + +import com.baeldung.graphql.error.handling.domain.Location; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface LocationRepository extends JpaRepository { +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/resolver/Mutation.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/resolver/Mutation.java new file mode 100644 index 0000000000..8463ebf8eb --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/resolver/Mutation.java @@ -0,0 +1,20 @@ +package com.baeldung.graphql.error.handling.resolver; + +import com.baeldung.graphql.error.handling.domain.Location; +import com.baeldung.graphql.error.handling.domain.Vehicle; +import com.baeldung.graphql.error.handling.service.InventoryService; +import com.coxautodev.graphql.tools.GraphQLMutationResolver; +import org.springframework.stereotype.Component; + +@Component +public class Mutation implements GraphQLMutationResolver { + private InventoryService inventoryService; + + public Mutation(InventoryService inventoryService) { + this.inventoryService = inventoryService; + } + + public Vehicle addVehicle(String vin, Integer year, String make, String model, String trim, Location location) { + return this.inventoryService.addVehicle(vin, year, make, model, trim, location); + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/resolver/Query.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/resolver/Query.java new file mode 100644 index 0000000000..ece018464a --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/resolver/Query.java @@ -0,0 +1,29 @@ +package com.baeldung.graphql.error.handling.resolver; + +import com.baeldung.graphql.error.handling.domain.Vehicle; +import com.baeldung.graphql.error.handling.service.InventoryService; +import com.coxautodev.graphql.tools.GraphQLQueryResolver; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class Query implements GraphQLQueryResolver { + private final InventoryService inventoryService; + + public Query(InventoryService inventoryService) { + this.inventoryService = inventoryService; + } + + public List searchAll() { + return this.inventoryService.searchAll(); + } + + public List searchByLocation(String zipcode) { + return this.inventoryService.searchByLocation(zipcode); + } + + public Vehicle searchByVin(String vin) { + return this.inventoryService.searchByVin(vin); + } +} diff --git a/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/service/InventoryService.java b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/service/InventoryService.java new file mode 100644 index 0000000000..7064b08760 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/java/com/baeldung/graphql/error/handling/service/InventoryService.java @@ -0,0 +1,67 @@ +package com.baeldung.graphql.error.handling.service; + +import com.baeldung.graphql.error.handling.domain.Location; +import com.baeldung.graphql.error.handling.domain.Vehicle; +import com.baeldung.graphql.error.handling.exception.InvalidInputException; +import com.baeldung.graphql.error.handling.exception.VehicleAlreadyPresentException; +import com.baeldung.graphql.error.handling.exception.VehicleNotFoundException; +import com.baeldung.graphql.error.handling.repository.InventoryRepository; +import com.baeldung.graphql.error.handling.repository.LocationRepository; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.*; + +@Service +public class InventoryService { + private InventoryRepository inventoryRepository; + private LocationRepository locationRepository; + + public InventoryService(InventoryRepository inventoryRepository, LocationRepository locationRepository) { + this.inventoryRepository = inventoryRepository; + this.locationRepository = locationRepository; + } + + @Transactional + public Vehicle addVehicle(String vin, Integer year, String make, String model, String trim, Location location) { + Optional existingVehicle = this.inventoryRepository.findById(vin); + if (existingVehicle.isPresent()) { + Map params = new HashMap<>(); + params.put("vin", vin); + throw new VehicleAlreadyPresentException("Failed to add vehicle. Vehicle with vin " + vin + " already present.", params); + } + Vehicle vehicle = Vehicle.builder() + .vin(vin) + .year(year) + .make(make) + .model(model) + .location(location) + .trim(trim) + .build(); + + this.locationRepository.save(location); + return this.inventoryRepository.save(vehicle); + } + + public List searchAll() { + return this.inventoryRepository.findAll(); + } + + public List searchByLocation(String zipcode) { + if (StringUtils.isEmpty(zipcode) || zipcode.length() != 5) { + throw new InvalidInputException("Invalid zipcode " + zipcode + " provided."); + } + return this.locationRepository.findById(zipcode) + .map(Location::getVehicles) + .orElse(new ArrayList<>()); + } + + public Vehicle searchByVin(String vin) { + return this.inventoryRepository.findById(vin).orElseThrow(() -> { + Map params = new HashMap<>(); + params.put("vin", vin); + return new VehicleNotFoundException("Vehicle with vin " + vin + " not found.", params); + }); + } +} diff --git a/graphql/graphql-error-handling/src/main/resources/application.yml b/graphql/graphql-error-handling/src/main/resources/application.yml new file mode 100644 index 0000000000..155e133a62 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/resources/application.yml @@ -0,0 +1,23 @@ +graphql: + servlet: + mapping: /graphql + +spring: + datasource: + url: "jdbc:h2:mem:graphqldb" + driverClassName: "org.h2.Driver" + username: sa + password: + + initialization-mode: always + platform: h2 + + jpa: + show-sql: true + properties: + hibernate: + dialect: org.hibernate.dialect.H2Dialect + ddl-auto: none + + h2: + console.enabled: true \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/main/resources/graphql/inventory.graphqls b/graphql/graphql-error-handling/src/main/resources/graphql/inventory.graphqls new file mode 100644 index 0000000000..7dcb5403c1 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/resources/graphql/inventory.graphqls @@ -0,0 +1,23 @@ +type Vehicle { + vin: ID! + year: Int! + make: String! + model: String! + trim: String! +} + +input Location { + city: String + state: String + zipcode: String! +} + +type Query { + searchAll: [Vehicle]! + searchByLocation(zipcode: String!): [Vehicle]! + searchByVin(vin: String!): Vehicle +} + +type Mutation { + addVehicle(vin: ID!, year: Int!, make: String!, model: String!, trim: String, location: Location): Vehicle! +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/main/resources/import.sql b/graphql/graphql-error-handling/src/main/resources/import.sql new file mode 100644 index 0000000000..62907a86c3 --- /dev/null +++ b/graphql/graphql-error-handling/src/main/resources/import.sql @@ -0,0 +1,7 @@ +insert into LOCATION values('07092', 'Mountainside', 'NJ'); +insert into LOCATION values ('94118', 'San Francisco', 'CA'); +insert into LOCATION values ('10002', 'New York', 'NY'); + +insert into VEHICLE (vin, year, make, model, trim, fk_location) values('KM8JN72DX7U587496', 2007, 'Hyundai', 'Tucson', null, '07092'); +insert into VEHICLE (vin, year, make, model, trim, fk_location) values('JTKKU4B41C1023346', 2012, 'Toyota', 'Scion', 'Xd', '94118'); +insert into VEHICLE (vin, year, make, model, trim, fk_location) values('1G1JC1444PZ215071', 2000, 'Chevrolet', 'CAVALIER VL', 'RS', '07092'); \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/java/com/baeldung/graphql/error/handling/GraphQLErrorHandlerApplicationIntegrationTest.java b/graphql/graphql-error-handling/src/test/java/com/baeldung/graphql/error/handling/GraphQLErrorHandlerApplicationIntegrationTest.java new file mode 100644 index 0000000000..069a08ce02 --- /dev/null +++ b/graphql/graphql-error-handling/src/test/java/com/baeldung/graphql/error/handling/GraphQLErrorHandlerApplicationIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.graphql.error.handling; + +import com.graphql.spring.boot.test.GraphQLResponse; +import com.graphql.spring.boot.test.GraphQLTestTemplate; +import org.json.JSONException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.skyscreamer.jsonassert.JSONAssert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; + +import static com.baeldung.graphql.error.handling.TestUtils.readFile; +import static java.lang.String.format; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = GraphQLErrorHandlerApplication.class) +public class GraphQLErrorHandlerApplicationIntegrationTest { + + @Autowired + private GraphQLTestTemplate graphQLTestTemplate; + + private static final String GRAPHQL_TEST_REQUEST_PATH = "graphql/request/%s.graphql"; + private static final String GRAPHQL_TEST_RESPONSE_PATH = "graphql/response/%s.json"; + + @Test + public void whenUnknownOperation_thenRespondWithRequestError() throws IOException, JSONException { + String graphqlName = "request_error_unknown_operation"; + GraphQLResponse actualResponse = graphQLTestTemplate.postForResource(format(GRAPHQL_TEST_REQUEST_PATH, graphqlName)); + String expectedResponse = readFile(format(GRAPHQL_TEST_RESPONSE_PATH, graphqlName)); + + JSONAssert.assertEquals(expectedResponse, actualResponse.getRawResponse().getBody(), true); + } + + @Test + public void whenInvalidSyntaxRequest_thenRespondWithRequestError() throws IOException, JSONException { + String graphqlName = "request_error_invalid_request_syntax"; + GraphQLResponse actualResponse = graphQLTestTemplate.postForResource(format(GRAPHQL_TEST_REQUEST_PATH, graphqlName)); + String expectedResponse = readFile(format(GRAPHQL_TEST_RESPONSE_PATH, graphqlName)); + + JSONAssert.assertEquals(expectedResponse, actualResponse.getRawResponse().getBody(), true); + } + + @Test + public void whenRequestAllNonNullField_thenRespondPartialDataWithFieldError() throws IOException, JSONException { + String graphqlName = "field_error_request_non_null_fields_partial_response"; + GraphQLResponse actualResponse = graphQLTestTemplate.postForResource(format(GRAPHQL_TEST_REQUEST_PATH, graphqlName)); + String expectedResponse = readFile(format(GRAPHQL_TEST_RESPONSE_PATH, graphqlName)); + + JSONAssert.assertEquals(expectedResponse, actualResponse.getRawResponse().getBody(), true); + } +} diff --git a/graphql/graphql-error-handling/src/test/java/com/baeldung/graphql/error/handling/TestUtils.java b/graphql/graphql-error-handling/src/test/java/com/baeldung/graphql/error/handling/TestUtils.java new file mode 100644 index 0000000000..557f1d9c91 --- /dev/null +++ b/graphql/graphql-error-handling/src/test/java/com/baeldung/graphql/error/handling/TestUtils.java @@ -0,0 +1,15 @@ +package com.baeldung.graphql.error.handling; + +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.ClassPathResource; + +import java.io.IOException; +import java.nio.charset.Charset; + +public class TestUtils { + public static String readFile(String path) throws IOException { + return IOUtils.toString( + new ClassPathResource(path).getInputStream(), Charset.defaultCharset() + ); + } +} diff --git a/graphql/graphql-error-handling/src/test/resources/graphql/request/field_error_request_non_null_fields_partial_response.graphql b/graphql/graphql-error-handling/src/test/resources/graphql/request/field_error_request_non_null_fields_partial_response.graphql new file mode 100644 index 0000000000..17affc50cb --- /dev/null +++ b/graphql/graphql-error-handling/src/test/resources/graphql/request/field_error_request_non_null_fields_partial_response.graphql @@ -0,0 +1,10 @@ +# trim is non null but one of the record has null value for trim +query { + searchAll { + vin + year + make + model + trim + } +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/resources/graphql/request/request_error_invalid_request_syntax.graphql b/graphql/graphql-error-handling/src/test/resources/graphql/request/request_error_invalid_request_syntax.graphql new file mode 100644 index 0000000000..98920eb17a --- /dev/null +++ b/graphql/graphql-error-handling/src/test/resources/graphql/request/request_error_invalid_request_syntax.graphql @@ -0,0 +1,9 @@ +query { + searchByVin(vin: "error) { + vin + year + make + model + trim + } +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/resources/graphql/request/request_error_unknown_operation.graphql b/graphql/graphql-error-handling/src/test/resources/graphql/request/request_error_unknown_operation.graphql new file mode 100644 index 0000000000..fb6c3d1039 --- /dev/null +++ b/graphql/graphql-error-handling/src/test/resources/graphql/request/request_error_unknown_operation.graphql @@ -0,0 +1,9 @@ +subscription { + searchByVin(vin: "75024") { + vin + year + make + model + trim + } +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/resources/graphql/response/field_error_request_non_null_fields_partial_response.json b/graphql/graphql-error-handling/src/test/resources/graphql/response/field_error_request_non_null_fields_partial_response.json new file mode 100644 index 0000000000..760190128e --- /dev/null +++ b/graphql/graphql-error-handling/src/test/resources/graphql/response/field_error_request_non_null_fields_partial_response.json @@ -0,0 +1,34 @@ +{ + "data": { + "searchAll": [ + null, + { + "vin": "JTKKU4B41C1023346", + "year": 2012, + "make": "Toyota", + "model": "Scion", + "trim": "Xd" + }, + { + "vin": "1G1JC1444PZ215071", + "year": 2000, + "make": "Chevrolet", + "model": "CAVALIER VL", + "trim": "RS" + } + ] + }, + "errors": [ + { + "message": "Cannot return null for non-nullable type: 'String' within parent 'Vehicle' (/searchAll[0]/trim)", + "path": [ + "searchAll", + 0, + "trim" + ], + "errorType": "DataFetchingException", + "locations": null, + "extensions": null + } + ] +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/resources/graphql/response/request_error_invalid_request_syntax.json b/graphql/graphql-error-handling/src/test/resources/graphql/response/request_error_invalid_request_syntax.json new file mode 100644 index 0000000000..2835b42133 --- /dev/null +++ b/graphql/graphql-error-handling/src/test/resources/graphql/response/request_error_invalid_request_syntax.json @@ -0,0 +1,18 @@ +{ + "data": null, + "errors": [ + { + "message": "Invalid Syntax", + "locations": [ + { + "line": 5, + "column": 8, + "sourceName": null + } + ], + "errorType": "InvalidSyntax", + "path": null, + "extensions": null + } + ] +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/resources/graphql/response/request_error_unknown_operation.json b/graphql/graphql-error-handling/src/test/resources/graphql/response/request_error_unknown_operation.json new file mode 100644 index 0000000000..b5872fc80f --- /dev/null +++ b/graphql/graphql-error-handling/src/test/resources/graphql/response/request_error_unknown_operation.json @@ -0,0 +1,18 @@ +{ + "data": null, + "errors": [ + { + "errorType": "OperationNotSupported", + "locations": [ + { + "line": 1, + "column": 1, + "sourceName": null + } + ], + "extensions": null, + "message": "Schema is not configured for subscriptions.", + "path": null + } + ] +} \ No newline at end of file diff --git a/graphql/graphql-error-handling/src/test/resources/init_script.sql b/graphql/graphql-error-handling/src/test/resources/init_script.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/graphql/graphql-java/README.md b/graphql/graphql-java/README.md index f37506a9fd..85c1497169 100644 --- a/graphql/graphql-java/README.md +++ b/graphql/graphql-java/README.md @@ -6,3 +6,4 @@ This module contains articles about GraphQL with Java - [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) +- [Return Map from GraphQL](https://www.baeldung.com/java-graphql-return-map) diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml index f2733bf671..b0b2c15359 100644 --- a/graphql/graphql-java/pom.xml +++ b/graphql/graphql-java/pom.xml @@ -3,16 +3,14 @@ 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.graphql graphql-java 1.0 graphql-java - com.baeldung - parent-modules + com.baeldung.graphql + graphql 1.0.0-SNAPSHOT - ../../ @@ -44,43 +42,22 @@ com.github.americanexpress.nodes nodes - 0.5.0 + ${nodes.version} com.graphql-java graphql-java - 9.2 + ${graphql-java.version} com.graphql-java graphql-java-tools - 5.2.4 + ${graphql-java-tools.version} 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 + ${graphql-java-servlet.version} com.graphql-java-generator @@ -88,38 +65,55 @@ ${graphql.java.generator.version} - org.junit.jupiter - junit-jupiter-engine - 5.8.2 + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + provided + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + org.mock-server + mockserver-netty + ${mockserver-netty.version} test - org.assertj - assertj-core - 3.22.0 + org.mock-server + mockserver-client-java + ${mockserver-client-java.version} test + + com.graphql-java + graphql-java-extended-scalars + ${graphql-java-extended-scalars.version} + - - 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 + ${jetty-maven-plugin.version} maven-war-plugin - 3.1.0 + ${maven-war-plugin.version} com.graphql-java-generator @@ -137,18 +131,32 @@ false false true + + + JSON + java.util.Map + com.baeldung.graphqlreturnmap.ExtendedGraphQLScalarType + + + 11.0 + 5.2.4 + 6.1.3 3.0.3 - 1.4.6 - 3.1 - 1.8 - 1.8 1.18 + 1.9.0 + 0.5.0 + 4.5.13 + 5.13.2 + 5.13.2 + 10.0.7 + 1.18 + 2022-04-06T00-10-27-a70541e \ No newline at end of file diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java b/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java index a6d474a70d..eb7cf021c6 100644 --- a/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphql/handler/UserHandler.java @@ -19,24 +19,27 @@ import com.baeldung.graphql.utils.SchemaUtils; import static ratpack.jackson.Jackson.json; public class UserHandler implements Handler { + private static final Logger LOGGER = Logger.getLogger(UserHandler.class.getSimpleName()); - private GraphQL graphql; - private static List users = new ArrayList<>(); + + private static final List USERS = new ArrayList<>(); + + private final GraphQL graphql; public UserHandler() throws Exception { - graphql = new GraphQL(new UserSchema().getSchema()); + graphql = GraphQL.newGraphQL(new UserSchema().getSchema()).build(); } @Override - public void handle(Context context) throws Exception { + public void handle(Context context) { context.parse(Map.class) .then(payload -> { Map parameters = (Map) payload.get("parameters"); ExecutionResult executionResult = graphql.execute(payload.get(SchemaUtils.QUERY) .toString(), null, this, parameters); + Map result = new LinkedHashMap<>(); - if (executionResult.getErrors() - .isEmpty()) { + if (executionResult.getErrors().isEmpty()) { result.put(SchemaUtils.DATA, executionResult.getData()); } else { result.put(SchemaUtils.ERRORS, executionResult.getErrors()); @@ -46,8 +49,8 @@ public class UserHandler implements Handler { }); } - public static List getUsers() { - return users; + public List getUsers() { + return USERS; } public static List getUsers(DataFetchingEnvironment env) { 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 index 8ba9fa25c5..f2ac792e80 100644 --- 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 @@ -2,6 +2,7 @@ package com.baeldung.graphql.server; import com.baeldung.graphql.data.Book; import com.baeldung.graphql.data.BookRepository; +import com.baeldung.graphqlreturnmap.entity.Product; import com.coxautodev.graphql.tools.GraphQLQueryResolver; import java.util.List; @@ -18,4 +19,12 @@ public class GraphQLQuery implements GraphQLQueryResolver { return repository.getAllBooks(); } + public List getProducts(int pageSize, int pageNumber) { + return null; + } + + public Product getProduct(int id) { + return null; + } + } diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/AppHandler.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/AppHandler.java new file mode 100644 index 0000000000..26ad0eef2c --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/AppHandler.java @@ -0,0 +1,52 @@ +package com.baeldung.graphqlreturnmap; + +import com.baeldung.graphql.utils.SchemaUtils; +import com.baeldung.graphqlreturnmap.resolver.ProductResolver; +import com.baeldung.graphqlreturnmap.resolver.Query; +import com.coxautodev.graphql.tools.SchemaParser; +import graphql.ExecutionResult; +import graphql.GraphQL; +import graphql.scalars.ExtendedScalars; +import graphql.schema.GraphQLSchema; +import ratpack.handling.Context; +import ratpack.handling.Handler; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.logging.Logger; + +import static ratpack.jackson.Jackson.json; + +public class AppHandler implements Handler { + private static final Logger LOGGER = Logger.getLogger(AppHandler.class.getSimpleName()); + private GraphQL graphql; + + public AppHandler() throws Exception { + GraphQLSchema schema = SchemaParser.newParser() + .resolvers(new Query(), new ProductResolver()) + .scalars(ExtendedScalars.Json) + .file("schema.graphqls") + .build() + .makeExecutableSchema(); + graphql = GraphQL.newGraphQL(schema).build(); + } + + @Override + public void handle(Context context) throws Exception { + context.parse(Map.class) + .then(payload -> { + ExecutionResult executionResult = graphql.execute(payload.get(SchemaUtils.QUERY) + .toString(), null, this, Collections.emptyMap()); + Map result = new LinkedHashMap<>(); + if (executionResult.getErrors() + .isEmpty()) { + result.put(SchemaUtils.DATA, executionResult.getData()); + } else { + result.put(SchemaUtils.ERRORS, executionResult.getErrors()); + LOGGER.warning("Errors: " + executionResult.getErrors()); + } + context.render(json(result)); + }); + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/ExtendedGraphQLScalarType.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/ExtendedGraphQLScalarType.java new file mode 100644 index 0000000000..5cdc72b13d --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/ExtendedGraphQLScalarType.java @@ -0,0 +1,24 @@ +package com.baeldung.graphqlreturnmap; + +import graphql.language.ScalarTypeDefinition; +import graphql.schema.Coercing; +import graphql.schema.GraphQLDirective; +import graphql.schema.GraphQLScalarType; + +import java.util.List; + +public class ExtendedGraphQLScalarType extends GraphQLScalarType { + + public ExtendedGraphQLScalarType(){ + super("","",null); + + } + + public ExtendedGraphQLScalarType(String name, String description, Coercing coercing) { + super(name, description, coercing); + } + + public ExtendedGraphQLScalarType(String name, String description, Coercing coercing, List directives, ScalarTypeDefinition definition) { + super(name, description, coercing, directives, definition); + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/GraphqlReturnMap.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/GraphqlReturnMap.java new file mode 100644 index 0000000000..8717fcb722 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/GraphqlReturnMap.java @@ -0,0 +1,12 @@ +package com.baeldung.graphqlreturnmap; + +import ratpack.server.RatpackServer; + +public class GraphqlReturnMap { + + public static void main(String[] args) throws Exception { + final RatpackServer server = RatpackServer.of(s -> s.handlers(chain -> chain.post("product", new AppHandler()))); + server.start(); + } + +} \ No newline at end of file diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Attribute.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Attribute.java new file mode 100644 index 0000000000..dd2766afa5 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Attribute.java @@ -0,0 +1,46 @@ +package com.baeldung.graphqlreturnmap.entity; + +public class Attribute { + private String name; + private String description; + private String unit; + + public Attribute(String name, String description, String unit){ + this.name = name; + this.description = description; + this.unit = unit; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + @Override + public String toString() { + return "Attribute{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", unit='" + unit + '\'' + + '}'; + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Product.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Product.java new file mode 100644 index 0000000000..db39d763de --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/entity/Product.java @@ -0,0 +1,48 @@ +package com.baeldung.graphqlreturnmap.entity; + + +import java.util.Map; + +public class Product { + private Integer id; + private String name; + private String description; + private Map attributes; + + + public Product(){ + + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/model/AttributeKeyValueModel.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/model/AttributeKeyValueModel.java new file mode 100644 index 0000000000..bb7641143b --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/model/AttributeKeyValueModel.java @@ -0,0 +1,30 @@ +package com.baeldung.graphqlreturnmap.model; + + +import com.baeldung.graphqlreturnmap.entity.Attribute; + +public class AttributeKeyValueModel { + private String key; + private Attribute value; + + public AttributeKeyValueModel(String key, Attribute value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Attribute getValue() { + return value; + } + + public void setValue(Attribute value) { + this.value = value; + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/ProductRepository.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/ProductRepository.java new file mode 100644 index 0000000000..c751efc183 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/ProductRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.graphqlreturnmap.repository; + + +import com.baeldung.graphqlreturnmap.entity.Product; + +import java.util.List; + +public interface ProductRepository { + List getProducts(Integer pageSize, Integer pageNumber); + Product getProduct(Integer id); + +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/impl/ProductRepositoryImpl.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/impl/ProductRepositoryImpl.java new file mode 100644 index 0000000000..466a2149f4 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/repository/impl/ProductRepositoryImpl.java @@ -0,0 +1,43 @@ +package com.baeldung.graphqlreturnmap.repository.impl; + +import com.baeldung.graphqlreturnmap.entity.Attribute; +import com.baeldung.graphqlreturnmap.entity.Product; +import com.baeldung.graphqlreturnmap.repository.ProductRepository; +import org.springframework.stereotype.Repository; + +import java.util.*; +import java.util.stream.Collectors; + +@Repository +public class ProductRepositoryImpl implements ProductRepository { + + private static List productList = new ArrayList<>(); + + public ProductRepositoryImpl() { + for (int i = 1; i <= 10; i++){ + Product product = new Product(); + product.setId(i); + product.setName(String.format("Product %d", i)); + product.setDescription(String.format("Product %d description", i)); + product.setAttributes(createAttributes(i)); + productList.add(product); + } + } + + private Map createAttributes(int i) { + Map attributeMap = new HashMap<>(); + attributeMap.put(String.format("attribute_%d",i), new Attribute(String.format("Attribute%d name",i),"This is custom attribute description","This is custom attribute unit")); + attributeMap.put("size", new Attribute((i & 1) == 0 ? "Small" : "Large","This is custom attribute description","This is custom attribute unit")); + return attributeMap; + } + + @Override + public List getProducts(Integer pageSize, Integer pageNumber) { + return productList.stream().skip(pageSize*pageNumber).limit(pageSize).collect(Collectors.toList()); + } + + @Override + public Product getProduct(Integer id) { + return productList.stream().filter(product -> product.getId().equals(id)).findFirst().orElse(null); + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/ProductResolver.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/ProductResolver.java new file mode 100644 index 0000000000..d9789ea0c6 --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/ProductResolver.java @@ -0,0 +1,30 @@ +package com.baeldung.graphqlreturnmap.resolver; + +import com.baeldung.graphqlreturnmap.entity.Product; +import com.baeldung.graphqlreturnmap.model.AttributeKeyValueModel; +import com.coxautodev.graphql.tools.GraphQLResolver; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.LinkedList; +import java.util.List; + +public class ProductResolver implements GraphQLResolver { + public ProductResolver(){ + } + + public List getAttribute_list(Product product){ + List attributeModelList = new LinkedList<>(); + product.getAttributes().forEach((key, val) -> attributeModelList.add(new AttributeKeyValueModel(key, val))); + return attributeModelList; + } + + public String getAttribute_string(Product product){ + try { + return new ObjectMapper().writeValueAsString(product.getAttributes()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + return ""; + } + } +} diff --git a/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/Query.java b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/Query.java new file mode 100644 index 0000000000..cbcff6056b --- /dev/null +++ b/graphql/graphql-java/src/main/java/com/baeldung/graphqlreturnmap/resolver/Query.java @@ -0,0 +1,33 @@ +package com.baeldung.graphqlreturnmap.resolver; + +import com.baeldung.graphql.data.Book; +import com.baeldung.graphqlreturnmap.entity.Product; +import com.baeldung.graphqlreturnmap.repository.ProductRepository; +import com.baeldung.graphqlreturnmap.repository.impl.ProductRepositoryImpl; +import com.coxautodev.graphql.tools.GraphQLQueryResolver; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +public class Query implements GraphQLQueryResolver { + + @Autowired + private ProductRepository productRepository; + public Query(){ + productRepository = new ProductRepositoryImpl(); + } + + public List getProducts(int pageSize, int pageNumber) { + return productRepository.getProducts(pageSize, pageNumber); + } + + public Product getProduct(int id) { + return productRepository.getProduct(id); + } + + public List allBooks() { + return null; + } + + +} diff --git a/graphql/graphql-java/src/main/resources/schema.graphqls b/graphql/graphql-java/src/main/resources/schema.graphqls index b0834e04b7..da10cd18bd 100644 --- a/graphql/graphql-java/src/main/resources/schema.graphqls +++ b/graphql/graphql-java/src/main/resources/schema.graphqls @@ -10,8 +10,34 @@ type Author { type Query { allBooks: [Book] + products(size: Int, page: Int): [Product]! + product(id: Int): Product! } + + +type Product { + id: ID + name: String! + description: String + attribute_string:String + attribute_list:[AttributeKeyValuePair] + attributes: JSON +} + +type AttributeKeyValuePair { + key:String + value:Attribute +} + +type Attribute { + name:String + description:String + unit:String +} +scalar JSON + + 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 index fb5a789428..e72f6a38b9 100644 --- a/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java +++ b/graphql/graphql-java/src/test/java/com/baeldung/graphql/GraphQLMockServer.java @@ -3,12 +3,13 @@ package com.baeldung.graphql; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.mockserver.client.MockServerClient; +import org.mockserver.configuration.Configuration; import org.mockserver.integration.ClientAndServer; import org.mockserver.model.HttpStatusCode; +import org.slf4j.event.Level; 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; @@ -17,20 +18,22 @@ import static org.mockserver.model.HttpResponse.response; public class GraphQLMockServer { - public static ClientAndServer mockServer; + private static final String SERVER_ADDRESS = "127.0.0.1"; + private static final String PATH = "/graphql"; + public static String serviceUrl; + private static ClientAndServer mockServer; 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 { + static void startServer() throws IOException { serverPort = getFreePort(); serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH; - mockServer = startClientAndServer(serverPort); + + Configuration config = Configuration.configuration().logLevel(Level.WARN); + mockServer = startClientAndServer(config, serverPort); + mockAllBooksTitleRequest(); mockAllBooksTitleAuthorRequest(); } diff --git a/graphql/graphql-spqr/pom.xml b/graphql/graphql-spqr/pom.xml index c825be9b79..75a1b5d79b 100644 --- a/graphql/graphql-spqr/pom.xml +++ b/graphql/graphql-spqr/pom.xml @@ -2,30 +2,21 @@ - 4.0.0 - com.baeldung.graphql graphql-spqr 1.0 - graphql-java + graphql-spqr - com.baeldung - parent-modules + com.baeldung.graphql + graphql 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 @@ -34,18 +25,8 @@ - - - - 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/spqr/BookService.java b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java index 7c9b129491..2e9c6d8367 100644 --- a/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java +++ b/graphql/graphql-spqr/src/main/java/com/baeldung/spqr/BookService.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; @Service @GraphQLApi @@ -27,8 +28,7 @@ public class BookService implements IBookService { @GraphQLQuery(name = "getAllBooks", description = "Get all books") public List getAllBooks() { - return books.stream() - .toList(); + return books.stream().collect(Collectors.toList()); } @GraphQLMutation(name = "addBook") diff --git a/graphql/pom.xml b/graphql/pom.xml new file mode 100644 index 0000000000..aec097752a --- /dev/null +++ b/graphql/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + com.baeldung.graphql + graphql + 1.0.0-SNAPSHOT + graphql + pom + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + graphql-dgs + graphql-error-handling + graphql-java + graphql-spqr + + + \ No newline at end of file diff --git a/grpc/pom.xml b/grpc/pom.xml index 40284c90fe..40d35183dc 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -40,7 +40,7 @@ javax.annotation javax.annotation-api - 1.2 + ${annotation-api.version} @@ -79,6 +79,7 @@ 3.17.2 1.6.2 0.6.1 + 1.2 \ No newline at end of file diff --git a/immutables/README.md b/immutables/README.md deleted file mode 100644 index a93a342f9c..0000000000 --- a/immutables/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Immutables - -This module contains articles about the Immutables library. - -### Relevant Articles: -- [Introduction to Immutables](https://www.baeldung.com/immutables) diff --git a/immutables/pom.xml b/immutables/pom.xml deleted file mode 100644 index 7704cddbb6..0000000000 --- a/immutables/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - 4.0.0 - immutables - immutables - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - org.immutables - value - ${immutables.version} - - - org.mutabilitydetector - MutabilityDetector - ${mutabilitydetector.version} - test - - - - - 2.5.6 - 0.9.6 - - - \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/README.md b/jackson-modules/jackson-annotations/README.md index 783a06605b..3b6cd6f20b 100644 --- a/jackson-modules/jackson-annotations/README.md +++ b/jackson-modules/jackson-annotations/README.md @@ -7,3 +7,4 @@ This module contains articles about Jackson annotations. - [More Jackson Annotations](https://www.baeldung.com/jackson-advanced-annotations) - [Jackson – Bidirectional Relationships](https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion) - [Jackson JSON Views](https://www.baeldung.com/jackson-json-view-annotation) +- [Deduction-Based Polymorphism in Jackson 2.12](https://www.baeldung.com/jackson-deduction-based-polymorphism) diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/Character.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/Character.java new file mode 100644 index 0000000000..6be7483cc2 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/Character.java @@ -0,0 +1,12 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; + +@JsonTypeInfo(use = Id.DEDUCTION) +@JsonSubTypes({ @Type(ImperialSpy.class), @Type(King.class), @Type(Knight.class) }) +public interface Character { + +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/ControlledCharacter.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/ControlledCharacter.java new file mode 100644 index 0000000000..9f6f03954e --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/ControlledCharacter.java @@ -0,0 +1,14 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +public class ControlledCharacter { + + private Character character; + + public Character getCharacter() { + return character; + } + + public void setCharacter(Character character) { + this.character = character; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/ImperialSpy.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/ImperialSpy.java new file mode 100644 index 0000000000..ff86966e38 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/ImperialSpy.java @@ -0,0 +1,5 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +public class ImperialSpy implements Character { + +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/King.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/King.java new file mode 100644 index 0000000000..3270d92b3a --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/King.java @@ -0,0 +1,14 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +public class King extends NamedCharacter { + + private String land; + + public String getLand() { + return land; + } + + public void setLand(String land) { + this.land = land; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/Knight.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/Knight.java new file mode 100644 index 0000000000..197d3b758b --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/Knight.java @@ -0,0 +1,14 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +public class Knight extends NamedCharacter { + + private String weapon; + + public String getWeapon() { + return weapon; + } + + public void setWeapon(String weapon) { + this.weapon = weapon; + } +} diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/NamedCharacter.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/NamedCharacter.java new file mode 100644 index 0000000000..15892f8659 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/deductionbasedpolymorphism/NamedCharacter.java @@ -0,0 +1,14 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +public class NamedCharacter implements Character { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/CaseInsensitiveInferenceUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/CaseInsensitiveInferenceUnitTest.java new file mode 100644 index 0000000000..cad9e73091 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/CaseInsensitiveInferenceUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +import static com.baeldung.jackson.deductionbasedpolymorphism.JsonStringFormatterUtil.formatJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; + +class CaseInsensitiveInferenceUnitTest { + + private final ObjectMapper objectMapper = JsonMapper.builder() + .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true) + .build(); + + @Test + void givenACaseInsensitiveKnight_whenMapping_thenExpectKnight() throws Exception { + String knightJson = formatJson("{'NaMe':'Ostrava, of Boletaria', 'WeaPON':'Rune Sword'}"); + + Character character = objectMapper.readValue(knightJson, Character.class); + + assertTrue(character instanceof Knight); + assertSame(character.getClass(), Knight.class); + Knight knight = (Knight) character; + assertEquals("Ostrava, of Boletaria", knight.getName()); + assertEquals("Rune Sword", knight.getWeapon()); + } + +} diff --git a/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/ContainedInferenceUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/ContainedInferenceUnitTest.java new file mode 100644 index 0000000000..810051f2ab --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/ContainedInferenceUnitTest.java @@ -0,0 +1,73 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +import static com.baeldung.jackson.deductionbasedpolymorphism.JsonStringFormatterUtil.formatJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; + +class ContainedInferenceUnitTest { + + private final ObjectMapper objectMapper = JsonMapper.builder() + .build(); + + @Test + void givenAKnightControlledCharacter_whenMapping_thenExpectAControlledCharacterWithKnight() throws Exception { + String controlledCharacterJson = formatJson("{'character': {'name': 'Ostrava, of Boletaria', 'weapon': 'Rune Sword'}}"); + + ControlledCharacter controlledCharacter = objectMapper.readValue(controlledCharacterJson, ControlledCharacter.class); + Character character = controlledCharacter.getCharacter(); + + assertTrue(character instanceof Knight); + assertSame(character.getClass(), Knight.class); + Knight knight = (Knight) character; + assertEquals("Ostrava, of Boletaria", knight.getName()); + assertEquals("Rune Sword", knight.getWeapon()); + } + + @Test + void givenAKingControlledCharacter_whenMapping_thenExpectAControlledCharacterWithKing() throws Exception { + String controlledCharacterJson = formatJson("{'character': {'name': 'King Allant', 'land': 'Boletaria'}}"); + + ControlledCharacter controlledCharacter = objectMapper.readValue(controlledCharacterJson, ControlledCharacter.class); + Character character = controlledCharacter.getCharacter(); + + assertTrue(character instanceof King); + assertSame(character.getClass(), King.class); + King king = (King) character; + assertEquals("King Allant", king.getName()); + assertEquals("Boletaria", king.getLand()); + } + + @Test + void givenAnEmptySubtype_whenMapping_thenExpectImperialSpy() throws Exception { + String controlledCharacterJson = formatJson("{'character': {}}"); + + ControlledCharacter controlledCharacter = objectMapper.readValue(controlledCharacterJson, ControlledCharacter.class); + + assertTrue(controlledCharacter.getCharacter() instanceof ImperialSpy); + } + + @Test + void givenANullCharacter_whenMapping_thenExpectNullCharacter() throws Exception { + String controlledCharacterJson = formatJson("{'character': null}"); + + ControlledCharacter controlledCharacter = objectMapper.readValue(controlledCharacterJson, ControlledCharacter.class); + + assertNull(controlledCharacter.getCharacter()); + } + + @Test + void givenAAnAbsentCharacter_whenMapping_thenExpectNullCharacter() throws Exception { + String controlledCharacterJson = formatJson("{}"); + + ControlledCharacter controlledCharacter = objectMapper.readValue(controlledCharacterJson, ControlledCharacter.class); + + assertNull(controlledCharacter.getCharacter()); + } +} diff --git a/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/JsonStringFormatterUtil.java b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/JsonStringFormatterUtil.java new file mode 100644 index 0000000000..948b264c45 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/JsonStringFormatterUtil.java @@ -0,0 +1,9 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +public class JsonStringFormatterUtil { + + public static String formatJson(String input) { + return input.replaceAll("'", "\""); + } + +} diff --git a/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/SimpleInferenceUnitTest.java b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/SimpleInferenceUnitTest.java new file mode 100644 index 0000000000..5e63e95289 --- /dev/null +++ b/jackson-modules/jackson-annotations/src/test/java/com/baeldung/jackson/deductionbasedpolymorphism/SimpleInferenceUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.jackson.deductionbasedpolymorphism; + +import static com.baeldung.jackson.deductionbasedpolymorphism.JsonStringFormatterUtil.formatJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; + +class SimpleInferenceUnitTest { + + private final ObjectMapper objectMapper = JsonMapper.builder() + .build(); + + @Test + void givenAKnight_whenMapping_thenExpectAKnightType() throws Exception { + String knightJson = formatJson("{'name':'Ostrava, of Boletaria', 'weapon':'Rune Sword'}"); + + Character character = objectMapper.readValue(knightJson, Character.class); + + assertTrue(character instanceof Knight); + assertSame(character.getClass(), Knight.class); + Knight king = (Knight) character; + assertEquals("Ostrava, of Boletaria", king.getName()); + assertEquals("Rune Sword", king.getWeapon()); + } + + @Test + void givenAKing_whenMapping_thenExpectAKingType() throws Exception { + String kingJson = formatJson("{'name':'Old King Allant', 'land':'Boletaria'}"); + + Character character = objectMapper.readValue(kingJson, Character.class); + + assertTrue(character instanceof King); + assertSame(character.getClass(), King.class); + King king = (King) character; + assertEquals("Old King Allant", king.getName()); + assertEquals("Boletaria", king.getLand()); + } + + @Test + void givenAnEmptyObject_whenMapping_thenExpectAnImperialSpy() throws Exception { + String imperialSpyJson = "{}"; + + Character character = objectMapper.readValue(imperialSpyJson, Character.class); + + assertTrue(character instanceof ImperialSpy); + } + + @Test + void givenANullObject_whenMapping_thenExpectANullObject() throws Exception { + Character character = objectMapper.readValue("null", Character.class); + + assertNull(character); + } + +} diff --git a/jakarta-ee/pom.xml b/jakarta-ee/pom.xml index dea4437345..afd31d7ece 100644 --- a/jakarta-ee/pom.xml +++ b/jakarta-ee/pom.xml @@ -51,25 +51,20 @@ admin password - ${local.glassfish.domain} 8080 4848 - ${project.artifactId} target/${project.build.finalName}.war - true false true - - diff --git a/java-numbers-4/README.md b/java-numbers-4/README.md index a6d866218c..2a77992c8f 100644 --- a/java-numbers-4/README.md +++ b/java-numbers-4/README.md @@ -5,3 +5,7 @@ - [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) +- [Convert Byte Size Into a Human-Readable Format in Java](https://www.baeldung.com/java-human-readable-byte-size) +- [Convert boolean to int in Java](https://www.baeldung.com/java-boolean-to-int) +- [Generate a Random Value From an Enum](https://www.baeldung.com/java-enum-random-value) +- [Reverse a Number in Java](https://www.baeldung.com/java-reverse-number) diff --git a/java-numbers-4/pom.xml b/java-numbers-4/pom.xml index 40fe17cc0d..4750b58511 100644 --- a/java-numbers-4/pom.xml +++ b/java-numbers-4/pom.xml @@ -23,7 +23,6 @@ org.apache.commons commons-lang3 ${commons-lang3.version} - test com.google.guava diff --git a/java-numbers-4/src/main/java/com/baeldung/booleantoint/BooleanToInt.java b/java-numbers-4/src/main/java/com/baeldung/booleantoint/BooleanToInt.java new file mode 100644 index 0000000000..3cca1592fb --- /dev/null +++ b/java-numbers-4/src/main/java/com/baeldung/booleantoint/BooleanToInt.java @@ -0,0 +1,42 @@ +package com.baeldung.booleantoint; + +import org.apache.commons.lang3.BooleanUtils; + +public class BooleanToInt { + public static int booleanPrimitiveToInt(boolean foo) { + int bar = 0; + if (foo) { + bar = 1; + } + return bar; + } + + public static int booleanPrimitiveToIntTernary(boolean foo) { + return (foo) ? 1 : 0; + } + + public static int booleanObjectToInt(boolean foo) { + return Boolean.compare(foo, false); + } + + public static int booleanObjectToIntInverse(boolean foo) { + return Boolean.compare(foo, true) + 1; + } + + public static int booleanObjectMethodToInt(Boolean foo) { + return foo.compareTo(false); + } + + public static int booleanObjectMethodToIntInverse(Boolean foo) { + return foo.compareTo(true) + 1; + } + + public static int booleanUtilsToInt(Boolean foo) { + return BooleanUtils.toInteger(foo); + } + + public static int bitwiseBooleanToInt(Boolean foo) { + return (Boolean.hashCode(foo) >> 1) & 1; + } +} + diff --git a/java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java b/java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java new file mode 100644 index 0000000000..941aa105aa --- /dev/null +++ b/java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java @@ -0,0 +1,81 @@ +package com.baeldung.humanreadablebytes; + +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class FileSizeFormatUtil { + private static final long BYTE = 1L; + private static final long KB = BYTE << 10; + private static final long MB = KB << 10; + private static final long GB = MB << 10; + private static final long TB = GB << 10; + private static final long PB = TB << 10; + private static final long EB = PB << 10; + private static final DecimalFormat DEC_FORMAT = new DecimalFormat("#.##"); + + public static String toHumanReadable(long size) { + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + if (size >= EB) return formatSize(size, EB, "EB"); + if (size >= PB) return formatSize(size, PB, "PB"); + if (size >= TB) return formatSize(size, TB, "TB"); + if (size >= GB) return formatSize(size, GB, "GB"); + if (size >= MB) return formatSize(size, MB, "MB"); + if (size >= KB) return formatSize(size, KB, "KB"); + return formatSize(size, BYTE, "Bytes"); + } + + private static String formatSize(long size, long divider, String unitName) { + return DEC_FORMAT.format((double) size / divider) + " " + unitName; + } + + public static String toHumanReadableWithEnum(long size) { + final List units = SizeUnit.unitsInDescending(); + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + String result = null; + for (SizeUnit unit : units) { + if (size >= unit.getUnitBase()) { + result = formatSize(size, unit.getUnitBase(), unit.name()); + break; + } + } + return result == null ? formatSize(size, SizeUnit.Bytes.getUnitBase(), SizeUnit.Bytes.name()) : result; + } + + public static String toHumanReadableByNumOfLeadingZeros(long size) { + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + if (size < 1024) return size + " Bytes"; + int unitIdx = (63 - Long.numberOfLeadingZeros(size)) / 10; + return formatSize(size, 1L << (unitIdx * 10), " KMGTPE".charAt(unitIdx) + "B"); + } + + enum SizeUnit { + Bytes(1L), + KB(Bytes.unitBase << 10), + MB(KB.unitBase << 10), + GB(MB.unitBase << 10), + TB(GB.unitBase << 10), + PB(TB.unitBase << 10), + EB(PB.unitBase << 10); + + private final Long unitBase; + + public static List unitsInDescending() { + List list = Arrays.asList(values()); + Collections.reverse(list); + return list; + } + + public Long getUnitBase() { + return unitBase; + } + + SizeUnit(long unitBase) { + this.unitBase = unitBase; + } + } +} diff --git a/java-numbers-4/src/main/java/com/baeldung/reversenumber/ReverseNumber.java b/java-numbers-4/src/main/java/com/baeldung/reversenumber/ReverseNumber.java new file mode 100644 index 0000000000..04865a8d52 --- /dev/null +++ b/java-numbers-4/src/main/java/com/baeldung/reversenumber/ReverseNumber.java @@ -0,0 +1,45 @@ +package com.baeldung.reversenumber; + +public class ReverseNumber { + + public static int reverseNumberWhileLoop(int number) { + int reversedNumber = 0; + int numberToReverse = Math.abs(number); + + while (numberToReverse > 0) { + int mod = numberToReverse % 10; + reversedNumber = reversedNumber * 10 + mod; + numberToReverse /= 10; + } + + return number < 0 ? reversedNumber * -1 : reversedNumber; + } + + public static int reverseNumberForLoop(int number) { + int reversedNumber = 0; + int numberToReverse = Math.abs(number); + + for (; numberToReverse > 0; numberToReverse /= 10) { + int mod = numberToReverse % 10; + reversedNumber = reversedNumber * 10 + mod; + } + + return number < 0 ? reversedNumber * -1 : reversedNumber; + } + + public static int reverseNumberRecWrapper(int number) { + int output = reverseNumberRec(Math.abs(number), 0); + return number < 0 ? output * -1 : output; + } + private static int reverseNumberRec(int numberToReverse, int recursiveReversedNumber) { + + if (numberToReverse > 0) { + int mod = numberToReverse % 10; + recursiveReversedNumber = recursiveReversedNumber * 10 + mod; + numberToReverse /= 10; + return reverseNumberRec(numberToReverse, recursiveReversedNumber); + } + + return recursiveReversedNumber; + } +} diff --git a/java-numbers-4/src/test/java/com/baeldung/booleantoint/BooleanToIntUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/booleantoint/BooleanToIntUnitTest.java new file mode 100644 index 0000000000..032eb1d28c --- /dev/null +++ b/java-numbers-4/src/test/java/com/baeldung/booleantoint/BooleanToIntUnitTest.java @@ -0,0 +1,55 @@ +package com.baeldung.booleantoint; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class BooleanToIntUnitTest { + @Test + void givenBooleanPrimitiveValue_ThenReturnInt() { + assertEquals(1, BooleanToInt.booleanPrimitiveToInt(true)); + assertEquals(0, BooleanToInt.booleanPrimitiveToInt(false)); + } + + @Test + void givenBooleanPrimitiveValue_ThenReturnIntTernary() { + assertEquals(1, BooleanToInt.booleanPrimitiveToIntTernary(true)); + assertEquals(0, BooleanToInt.booleanPrimitiveToIntTernary(false)); + } + + @Test + void givenBooleanObject_ThenReturnInt() { + assertEquals(0, BooleanToInt.booleanObjectToInt(false)); + assertEquals(1, BooleanToInt.booleanObjectToInt(true)); + } + + @Test + void givenBooleanObject_ThenReturnIntInverse() { + assertEquals(0, BooleanToInt.booleanObjectToIntInverse(false)); + assertEquals(1, BooleanToInt.booleanObjectToIntInverse(true)); + } + + @Test + void givenBooleanObject_ThenReturnIntUsingClassMethod() { + assertEquals(0, BooleanToInt.booleanObjectMethodToInt(false)); + assertEquals(1, BooleanToInt.booleanObjectMethodToInt(true)); + } + + @Test + void givenBooleanObject_ThenReturnIntUsingClassMethodInverse() { + assertEquals(0, BooleanToInt.booleanObjectMethodToIntInverse(false)); + assertEquals(1, BooleanToInt.booleanObjectMethodToIntInverse(true)); + } + + @Test + void givenBoolean_ThenReturnIntUsingBooleanUtils() { + assertEquals(0, BooleanToInt.booleanUtilsToInt(false)); + assertEquals(1, BooleanToInt.booleanUtilsToInt(true)); + } + + @Test + void givenBoolean_ThenReturnIntUsingBitwiseOperators() { + assertEquals(0, BooleanToInt.bitwiseBooleanToInt(false)); + assertEquals(1, BooleanToInt.bitwiseBooleanToInt(true)); + } +} diff --git a/java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java new file mode 100644 index 0000000000..4326e92e2f --- /dev/null +++ b/java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.humanreadablebytes; + +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class FileSizeFormatUtilUnitTest { + private final static Map DATA_MAP = new HashMap() {{ + put(0L, "0 Bytes"); + put(1023L, "1023 Bytes"); + put(1024L, "1 KB"); + put(12_345L, "12.06 KB"); + put(10_123_456L, "9.65 MB"); + put(10_123_456_798L, "9.43 GB"); + put(1_777_777_777_777_777_777L, "1.54 EB"); + }}; + + @Test + public void givenBytes_whenCalltoHumanReadableMethod_thenGetExpectedResults() { + DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadable(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableWithEnumMethod_thenGetExpectedResults() { + DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableWithEnum(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableByLeadingZeros_thenGetExpectedResults() { + DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableByNumOfLeadingZeros(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableByFileUtils_thenOutputExpectedResults() { + DATA_MAP.forEach((in, expected) -> System.out.println(in + " bytes -> " + FileUtils.byteCountToDisplaySize(in))); + } +} diff --git a/java-numbers-4/src/test/java/com/baeldung/reversenumber/ReverseNumberUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/reversenumber/ReverseNumberUnitTest.java new file mode 100644 index 0000000000..2c55bcc539 --- /dev/null +++ b/java-numbers-4/src/test/java/com/baeldung/reversenumber/ReverseNumberUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.reversenumber; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ReverseNumberUnitTest { + + private static final int ORIGINAL_NUMBER = 123456789; + private static final int REVERSED_NUMBER = 987654321; + + @Test + void whenReverseNumberWhileLoop_thenOriginalEqualToReverse() { + Assertions.assertThat(ReverseNumber.reverseNumberWhileLoop(ORIGINAL_NUMBER)).isEqualTo(REVERSED_NUMBER); + } + + @Test + void whenReverseNumberForLoop_thenOriginalEqualToReverse() { + Assertions.assertThat(ReverseNumber.reverseNumberForLoop(ORIGINAL_NUMBER)).isEqualTo(REVERSED_NUMBER); + } + + @Test + void whenReverseNumberRec_thenOriginalEqualToReverse() { + Assertions.assertThat(ReverseNumber.reverseNumberRecWrapper(ORIGINAL_NUMBER)).isEqualTo(REVERSED_NUMBER); + } + + @Test + void whenReverseNegativeNumber_thenNumberShouldReverse() { + Assertions.assertThat(ReverseNumber.reverseNumberWhileLoop(ORIGINAL_NUMBER * -1)).isEqualTo(REVERSED_NUMBER * -1); + Assertions.assertThat(ReverseNumber.reverseNumberForLoop(ORIGINAL_NUMBER * -1)).isEqualTo(REVERSED_NUMBER * -1); + Assertions.assertThat(ReverseNumber.reverseNumberRecWrapper(ORIGINAL_NUMBER * -1)).isEqualTo(REVERSED_NUMBER * -1); + } +} \ No newline at end of file diff --git a/javaxval/README.md b/javaxval/README.md index 24c2cf98c5..8fc5b07ccf 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -12,3 +12,4 @@ This module contains articles about Bean Validation. - [Validations for Enum Types](https://www.baeldung.com/javax-validations-enums) - [Guide to ParameterMessageInterpolator](https://www.baeldung.com/hibernate-parametermessageinterpolator) - [Hibernate Validator Annotation Processor in Depth](https://www.baeldung.com/hibernate-validator-annotation-processor) +- [Constraint Composition with Bean Validation](https://www.baeldung.com/java-bean-validation-constraint-composition) diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/Account.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/Account.java new file mode 100644 index 0000000000..b47a47ec81 --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/Account.java @@ -0,0 +1,37 @@ +package com.baeldung.javaxval.constraint.composition; + +public class Account { + + @ValidAlphanumeric + private String username; + + @ValidAlphanumericWithSingleViolation + private String password; + + @ValidLengthOrNumericCharacter + private String nickname; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } +} diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AccountService.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AccountService.java new file mode 100644 index 0000000000..f76fed8f04 --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AccountService.java @@ -0,0 +1,19 @@ +package com.baeldung.javaxval.constraint.composition; + +import org.springframework.stereotype.Component; +import org.springframework.validation.annotation.Validated; + +@Component +@Validated +public class AccountService { + + @AlphanumericReturnValue + public String getAnInvalidAlphanumericValue() { + return "john"; + } + + @AlphanumericReturnValue + public String getValidAlphanumericValue() { + return "johnDoe1234"; + } +} diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java new file mode 100644 index 0000000000..6e3408712b --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/AlphanumericReturnValue.java @@ -0,0 +1,36 @@ +package com.baeldung.javaxval.constraint.composition; + +import org.hibernate.validator.constraints.Length; + +import javax.validation.Constraint; +import javax.validation.Payload; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraintvalidation.SupportedValidationTarget; +import javax.validation.constraintvalidation.ValidationTarget; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@NotNull +@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character") +@Length(min = 6, max = 32, message = "must have between 6 and 32 characters") +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +@Documented +@Constraint(validatedBy = {}) +@SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT) +public @interface AlphanumericReturnValue { + + String message() default "method return value should have a valid length and contain numeric character(s)."; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} + diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionConfig.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionConfig.java new file mode 100644 index 0000000000..ac0ec81ab2 --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionConfig.java @@ -0,0 +1,21 @@ +package com.baeldung.javaxval.constraint.composition; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; + +@Configuration +@ComponentScan({ "com.baeldung.javaxval.constraint.composition" }) +public class ConstraintCompositionConfig { + + @Bean + public MethodValidationPostProcessor methodValidationPostProcessor() { + return new MethodValidationPostProcessor(); + } + + @Bean + public AccountService accountService() { + return new AccountService(); + } +} \ No newline at end of file diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java new file mode 100644 index 0000000000..916b4e36a4 --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumeric.java @@ -0,0 +1,37 @@ +package com.baeldung.javaxval.constraint.composition; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +import org.hibernate.validator.constraints.Length; + +@NotNull +@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character") +@Length(min = 6, max = 32, message = "must have between 6 and 32 characters") +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +@Documented +@Constraint(validatedBy = {}) +public @interface ValidAlphanumeric { + + String message() default "field should have a valid length and contain numeric character(s)."; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} + diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java new file mode 100644 index 0000000000..edc5b6af3e --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidAlphanumericWithSingleViolation.java @@ -0,0 +1,38 @@ +package com.baeldung.javaxval.constraint.composition; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; +import javax.validation.ReportAsSingleViolation; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +import org.hibernate.validator.constraints.Length; + +@NotNull +@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character") +@Length(min = 6, max = 32, message = "must have between 6 and 32 characters") +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +@Documented +@Constraint(validatedBy = {}) +@ReportAsSingleViolation +public @interface ValidAlphanumericWithSingleViolation { + + String message() default "field should have a valid length and contain numeric character(s)."; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} \ No newline at end of file diff --git a/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java new file mode 100644 index 0000000000..444cb4a63a --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/constraint/composition/ValidLengthOrNumericCharacter.java @@ -0,0 +1,34 @@ +package com.baeldung.javaxval.constraint.composition; + +import org.hibernate.validator.constraints.CompositionType; +import org.hibernate.validator.constraints.ConstraintComposition; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Constraint; +import javax.validation.Payload; +import javax.validation.constraints.Pattern; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Pattern(regexp = ".*\\d.*", message = "must contain at least one numeric character") +@Length(min = 6, max = 32, message = "must have between 6 and 32 characters") +@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) +@Retention(RUNTIME) +@Documented +@Constraint(validatedBy = {}) +@ConstraintComposition(CompositionType.OR) +public @interface ValidLengthOrNumericCharacter { + + String message() default "field should have a valid length or contain numeric character(s)."; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} + diff --git a/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java b/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java new file mode 100644 index 0000000000..6c2b8f801c --- /dev/null +++ b/javaxval/src/test/java/com/baeldung/javaxval/constraint/composition/ConstraintCompositionUnitTest.java @@ -0,0 +1,80 @@ +package com.baeldung.javaxval.constraint.composition; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +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; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { ConstraintCompositionConfig.class }, loader = AnnotationConfigContextLoader.class) +public class ConstraintCompositionUnitTest { + + @Autowired + private AccountService accountService; + + private Validator validator; + + @Before + public void setup() { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + validator = factory.getValidator(); + } + + @Test + public void whenUsernameIsInvalid_validationShouldReturnTwoViolations() { + Account account = new Account(); + account.setNickname("valid_nickname123"); + account.setPassword("valid_password123"); + account.setUsername("john"); + + Set> violations = validator.validate(account); + + assertThat(violations).hasSize(2); + } + + @Test + public void whenPasswordIsInvalid_validationShouldReturnSingleViolation() { + Account account = new Account(); + account.setUsername("valid_username123"); + account.setNickname("valid_nickname123"); + account.setPassword("john"); + + Set> violations = validator.validate(account); + + assertThat(violations).hasSize(1); + } + + @Test + public void whenNicknameIsTooShortButContainsNumericCharacter_validationShouldPass() { + Account account = new Account(); + account.setUsername("valid_username123"); + account.setPassword("valid_password123"); + account.setNickname("doe1"); + + Set> violations = validator.validate(account); + + assertThat(violations).isEmpty(); + } + + @Test + public void whenMethodReturnValuesIsInvalid_validationShouldFail() { + assertThatThrownBy(() -> accountService.getAnInvalidAlphanumericValue()).isInstanceOf(ConstraintViolationException.class) + .hasMessageContaining("must contain at least one numeric character") + .hasMessageContaining("must have between 6 and 32 characters"); + } + +} \ No newline at end of file diff --git a/jersey/README.md b/jersey/README.md index 366e7665f3..4c8c235be5 100644 --- a/jersey/README.md +++ b/jersey/README.md @@ -10,3 +10,4 @@ This module contains articles about Jersey. - [Exploring the Jersey Test Framework](https://www.baeldung.com/jersey-test) - [Explore Jersey Request Parameters](https://www.baeldung.com/jersey-request-parameters) - [Add a Header to a Jersey SSE Client Request](https://www.baeldung.com/jersey-sse-client-request-headers) +- [Exception Handling With Jersey](https://www.baeldung.com/java-exception-handling-jersey) diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/ExceptionHandlingConfig.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/ExceptionHandlingConfig.java new file mode 100644 index 0000000000..d4cc1a81a1 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/ExceptionHandlingConfig.java @@ -0,0 +1,19 @@ +package com.baeldung.jersey.exceptionhandling; + +import javax.ws.rs.ApplicationPath; + +import org.glassfish.jersey.server.ResourceConfig; + +import com.baeldung.jersey.exceptionhandling.rest.exceptions.IllegalArgumentExceptionMapper; +import com.baeldung.jersey.exceptionhandling.rest.exceptions.ServerExceptionMapper; + +@ApplicationPath("/exception-handling/*") +public class ExceptionHandlingConfig extends ResourceConfig { + + public ExceptionHandlingConfig() { + packages("com.baeldung.jersey.exceptionhandling.rest"); + register(IllegalArgumentExceptionMapper.class); + register(ServerExceptionMapper.class); + } + +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/data/Stock.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/data/Stock.java new file mode 100644 index 0000000000..9a3f321651 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/data/Stock.java @@ -0,0 +1,33 @@ +package com.baeldung.jersey.exceptionhandling.data; + +import com.baeldung.jersey.exceptionhandling.repo.Identifiable; + +public class Stock implements Identifiable { + private static final long serialVersionUID = 1L; + private String id; + private Double price; + + public Stock() { + } + + public Stock(String id, Double price) { + this.id = id; + this.price = price; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/data/Wallet.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/data/Wallet.java new file mode 100644 index 0000000000..8ef47b4c99 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/data/Wallet.java @@ -0,0 +1,51 @@ +package com.baeldung.jersey.exceptionhandling.data; + +import com.baeldung.jersey.exceptionhandling.repo.Identifiable; + +public class Wallet implements Identifiable { + private static final long serialVersionUID = 1L; + + public static final Double MIN_CHARGE = 50.0; + public static final String MIN_CHARGE_MSG = "minimum charge is: " + MIN_CHARGE; + + private String id; + private Double balance = 0.0; + + public Wallet() { + } + + public Wallet(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Double getBalance() { + return balance; + } + + public void setBalance(Double balance) { + this.balance = balance; + } + + public Double addBalance(Double amount) { + if (balance == null) + balance = 0.0; + + return balance += amount; + } + + public boolean hasFunds(Double amount) { + if (balance == null || amount == null) { + return false; + } + + return (balance - amount) >= 0; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/repo/Db.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/repo/Db.java new file mode 100644 index 0000000000..c91085f25b --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/repo/Db.java @@ -0,0 +1,32 @@ +package com.baeldung.jersey.exceptionhandling.repo; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +public class Db { + private Map db = new HashMap<>(); + + public Optional findById(String id) { + return Optional.ofNullable(db.get(id)); + } + + public String save(T t) { + String id = t.getId(); + if (id == null) { + id = UUID.randomUUID() + .toString(); + t.setId(id); + } + db.put(id, t); + return id; + } + + public void remove(T t) { + db.entrySet() + .removeIf(entry -> entry.getValue() + .getId() + .equals(t.getId())); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/repo/Identifiable.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/repo/Identifiable.java new file mode 100644 index 0000000000..11af44bcc5 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/repo/Identifiable.java @@ -0,0 +1,17 @@ +package com.baeldung.jersey.exceptionhandling.repo; + +import java.io.Serializable; + +public interface Identifiable extends Serializable { + void setId(String id); + + String getId(); + + public static void assertValid(Identifiable i) { + if (i == null) + throw new IllegalArgumentException("object cannot be null"); + + if (i.getId() == null) + throw new IllegalArgumentException("object id cannot be null"); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/StocksResource.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/StocksResource.java new file mode 100644 index 0000000000..64b645a1c6 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/StocksResource.java @@ -0,0 +1,42 @@ +package com.baeldung.jersey.exceptionhandling.rest; + +import java.util.Optional; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.baeldung.jersey.exceptionhandling.data.Stock; +import com.baeldung.jersey.exceptionhandling.repo.Db; +import com.baeldung.jersey.exceptionhandling.service.Repository; + +@Path("/stocks") +public class StocksResource { + private static final Db stocks = Repository.STOCKS_DB; + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response post(Stock stock) { + stocks.save(stock); + + return Response.ok(stock) + .build(); + } + + @GET + @Path("/{ticker}") + @Produces(MediaType.APPLICATION_JSON) + public Response get(@PathParam("ticker") String id) { + Optional stock = stocks.findById(id); + stock.orElseThrow(() -> new IllegalArgumentException("ticker")); + + return Response.ok(stock.get()) + .build(); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/WalletsResource.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/WalletsResource.java new file mode 100644 index 0000000000..e5f8ddec06 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/WalletsResource.java @@ -0,0 +1,98 @@ +package com.baeldung.jersey.exceptionhandling.rest; + +import java.util.Optional; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import com.baeldung.jersey.exceptionhandling.data.Stock; +import com.baeldung.jersey.exceptionhandling.data.Wallet; +import com.baeldung.jersey.exceptionhandling.repo.Db; +import com.baeldung.jersey.exceptionhandling.rest.exceptions.InvalidTradeException; +import com.baeldung.jersey.exceptionhandling.rest.exceptions.RestErrorResponse; +import com.baeldung.jersey.exceptionhandling.service.Repository; + +@Path("/wallets") +public class WalletsResource { + private static final Db stocks = Repository.STOCKS_DB; + private static final Db wallets = Repository.WALLETS_DB; + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response post(Wallet wallet) { + wallets.save(wallet); + + return Response.ok(wallet) + .build(); + } + + @GET + @Path("/{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response get(@PathParam("id") String id) { + Optional wallet = wallets.findById(id); + wallet.orElseThrow(IllegalArgumentException::new); + + return Response.ok(wallet.get()) + .build(); + } + + @PUT + @Path("/{id}/{amount}") + @Produces(MediaType.APPLICATION_JSON) + public Response putAmount(@PathParam("id") String id, @PathParam("amount") Double amount) { + Optional wallet = wallets.findById(id); + wallet.orElseThrow(IllegalArgumentException::new); + + if (amount < Wallet.MIN_CHARGE) { + throw new InvalidTradeException(Wallet.MIN_CHARGE_MSG); + } + + wallet.get() + .addBalance(amount); + wallets.save(wallet.get()); + + return Response.ok(wallet) + .build(); + } + + @POST + @Path("/{wallet}/buy/{ticker}") + @Produces(MediaType.APPLICATION_JSON) + public Response postBuyStock(@PathParam("wallet") String walletId, @PathParam("ticker") String id) { + Optional stock = stocks.findById(id); + stock.orElseThrow(InvalidTradeException::new); + + Optional w = wallets.findById(walletId); + w.orElseThrow(InvalidTradeException::new); + + Wallet wallet = w.get(); + Double price = stock.get() + .getPrice(); + + if (!wallet.hasFunds(price)) { + RestErrorResponse response = new RestErrorResponse(); + response.setSubject(wallet); + response.setMessage("insufficient balance"); + throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE) + .entity(response) + .build()); + } + + wallet.addBalance(-price); + wallets.save(wallet); + + return Response.ok(wallet) + .build(); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/IllegalArgumentExceptionMapper.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/IllegalArgumentExceptionMapper.java new file mode 100644 index 0000000000..b577121027 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/IllegalArgumentExceptionMapper.java @@ -0,0 +1,23 @@ +package com.baeldung.jersey.exceptionhandling.rest.exceptions; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +public class IllegalArgumentExceptionMapper implements ExceptionMapper { + public static final String DEFAULT_MESSAGE = "an illegal argument was provided"; + + @Override + public Response toResponse(final IllegalArgumentException exception) { + return Response.status(Response.Status.EXPECTATION_FAILED) + .entity(build(exception.getMessage())) + .type(MediaType.APPLICATION_JSON) + .build(); + } + + private RestErrorResponse build(String message) { + RestErrorResponse response = new RestErrorResponse(); + response.setMessage(DEFAULT_MESSAGE + ": " + message); + return response; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/InvalidTradeException.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/InvalidTradeException.java new file mode 100644 index 0000000000..11277c048a --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/InvalidTradeException.java @@ -0,0 +1,17 @@ +package com.baeldung.jersey.exceptionhandling.rest.exceptions; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class InvalidTradeException extends WebApplicationException { + private static final long serialVersionUID = 1L; + private static final String MESSAGE = "invalid trade operation"; + + public InvalidTradeException() { + super(MESSAGE, Response.Status.NOT_ACCEPTABLE); + } + + public InvalidTradeException(String detail) { + super(MESSAGE + ": " + detail, Response.Status.NOT_ACCEPTABLE); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/RestErrorResponse.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/RestErrorResponse.java new file mode 100644 index 0000000000..dd193ab059 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/RestErrorResponse.java @@ -0,0 +1,34 @@ +package com.baeldung.jersey.exceptionhandling.rest.exceptions; + +public class RestErrorResponse { + private Object subject; + private String message; + + public RestErrorResponse() { + } + + public RestErrorResponse(String message) { + this.message = message; + } + + public RestErrorResponse(Object subject, String message) { + this.subject = subject; + this.message = message; + } + + public Object getSubject() { + return subject; + } + + public void setSubject(Object subject) { + this.subject = subject; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/ServerExceptionMapper.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/ServerExceptionMapper.java new file mode 100644 index 0000000000..adfac000e8 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/rest/exceptions/ServerExceptionMapper.java @@ -0,0 +1,35 @@ +package com.baeldung.jersey.exceptionhandling.rest.exceptions; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.ExceptionMapper; + +public class ServerExceptionMapper implements ExceptionMapper { + public static final String HTTP_405_MESSAGE = "use one of"; + + @Override + public Response toResponse(final WebApplicationException exception) { + String message = exception.getMessage(); + Response response = exception.getResponse(); + Status status = response.getStatusInfo() + .toEnum(); + + switch (status) { + case METHOD_NOT_ALLOWED: + message = HTTP_405_MESSAGE + response.getAllowedMethods(); + break; + case INTERNAL_SERVER_ERROR: + message = "internal validation - " + exception; + break; + default: + message = "[unhandled response code] " + exception; + } + + return Response.status(status) + .entity(status + ": " + message) + .type(MediaType.TEXT_PLAIN) + .build(); + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/service/Repository.java b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/service/Repository.java new file mode 100644 index 0000000000..459b062068 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/exceptionhandling/service/Repository.java @@ -0,0 +1,10 @@ +package com.baeldung.jersey.exceptionhandling.service; + +import com.baeldung.jersey.exceptionhandling.data.Stock; +import com.baeldung.jersey.exceptionhandling.data.Wallet; +import com.baeldung.jersey.exceptionhandling.repo.Db; + +public class Repository { + public static Db STOCKS_DB = new Db<>(); + public static Db WALLETS_DB = new Db<>(); +} diff --git a/jersey/src/test/java/com/baeldung/jersey/exceptionhandling/rest/StocksResourceIntegrationTest.java b/jersey/src/test/java/com/baeldung/jersey/exceptionhandling/rest/StocksResourceIntegrationTest.java new file mode 100644 index 0000000000..ceb59adc1f --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/exceptionhandling/rest/StocksResourceIntegrationTest.java @@ -0,0 +1,101 @@ +package com.baeldung.jersey.exceptionhandling.rest; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; +import org.junit.Test; + +import com.baeldung.jersey.exceptionhandling.ExceptionHandlingConfig; +import com.baeldung.jersey.exceptionhandling.data.Stock; +import com.baeldung.jersey.exceptionhandling.data.Wallet; +import com.baeldung.jersey.exceptionhandling.rest.exceptions.IllegalArgumentExceptionMapper; +import com.baeldung.jersey.exceptionhandling.rest.exceptions.RestErrorResponse; +import com.baeldung.jersey.exceptionhandling.rest.exceptions.ServerExceptionMapper; + +public class StocksResourceIntegrationTest extends JerseyTest { + private static final Entity EMPTY_BODY = Entity.json(""); + private static final Stock STOCK = new Stock("BAEL", 51.57); + private static final String MY_WALLET = "MY-WALLET"; + private static final Wallet WALLET = new Wallet(MY_WALLET); + private static final int INSUFFICIENT_AMOUNT = (int) (Wallet.MIN_CHARGE - 1); + + @Override + protected Application configure() { + forceSet(TestProperties.CONTAINER_PORT, "0"); + return new ExceptionHandlingConfig(); + } + + private Invocation.Builder stocks(String path) { + return target("/stocks" + path).request(); + } + + private Invocation.Builder wallets(String path, Object... args) { + return target("/wallets" + String.format(path, args)).request(); + } + + private Entity entity(Object object) { + return Entity.entity(object, MediaType.APPLICATION_JSON_TYPE); + } + + @Test + public void whenMethodNotAllowed_thenCustomMessage() { + Response response = stocks("").get(); + + assertEquals(Status.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatus()); + + String content = response.readEntity(String.class); + assertThat(content, containsString(ServerExceptionMapper.HTTP_405_MESSAGE)); + } + + @Test + public void whenTickerNotExists_thenRestErrorResponse() { + Response response = stocks("/UNDEFINED").get(); + + assertEquals(Status.EXPECTATION_FAILED.getStatusCode(), response.getStatus()); + + RestErrorResponse content = response.readEntity(RestErrorResponse.class); + assertThat(content.getMessage(), startsWith(IllegalArgumentExceptionMapper.DEFAULT_MESSAGE)); + } + + @Test + public void givenAmountLessThanMinimum_whenAddingToWallet_thenInvalidTradeException() { + wallets("").post(entity(WALLET)); + Response response = wallets("/%s/%d", MY_WALLET, INSUFFICIENT_AMOUNT).put(EMPTY_BODY); + + assertEquals(Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus()); + + String content = response.readEntity(String.class); + assertThat(content, containsString(Wallet.MIN_CHARGE_MSG)); + } + + @Test + public void givenInsifficientFunds_whenBuyingStock_thenWebApplicationException() { + stocks("").post(entity(STOCK)); + wallets("").post(entity(WALLET)); + + Response response = wallets("/%s/buy/%s", MY_WALLET, STOCK.getId()).post(EMPTY_BODY); + assertEquals(Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus()); + + RestErrorResponse content = response.readEntity(RestErrorResponse.class); + assertNotNull(content.getSubject()); + + HashMap subject = (HashMap) content.getSubject(); + assertEquals(subject.get("id"), WALLET.getId()); + assertTrue(WALLET.getBalance() < Wallet.MIN_CHARGE); + } +} diff --git a/jhipster-5/bookstore-monolith/pom.xml b/jhipster-5/bookstore-monolith/pom.xml index 411de0e712..ccf7a3c85e 100644 --- a/jhipster-5/bookstore-monolith/pom.xml +++ b/jhipster-5/bookstore-monolith/pom.xml @@ -1090,6 +1090,66 @@ + + integration-lite-first + + + + com.github.eirslett + frontend-maven-plugin + + + + install node and npm + none + + + npm install + none + + + webpack build dev + none + + + webpack build test + none + + + + + + + + integration-lite-second + + + + com.github.eirslett + frontend-maven-plugin + + + + install node and npm + none + + + npm install + none + + + webpack build dev + none + + + webpack build test + none + + + + + + diff --git a/jib/pom.xml b/jib/pom.xml index 8208eebdf7..bbc9a3c623 100644 --- a/jib/pom.xml +++ b/jib/pom.xml @@ -43,4 +43,5 @@ 2.5.0 + \ No newline at end of file diff --git a/jmeter/README.md b/jmeter/README.md index 6fdc79a2ce..23614307bd 100644 --- a/jmeter/README.md +++ b/jmeter/README.md @@ -53,3 +53,4 @@ Enjoy it :) - [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter) - [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/ops/jenkins-and-jmeter) - [Write Extracted Data to a File Using JMeter](https://www.baeldung.com/jmeter-write-to-file) +- [Basic Authentication in JMeter](https://www.baeldung.com/jmeter-basic-auth) diff --git a/json-2/README.md b/json-2/README.md index ed5a79dd3d..b3e7fb0b94 100644 --- a/json-2/README.md +++ b/json-2/README.md @@ -9,4 +9,5 @@ This module contains articles about JSON. - [Hypermedia Serialization With JSON-LD](https://www.baeldung.com/json-linked-data) - [Generate a Java Class From JSON](https://www.baeldung.com/java-generate-class-from-json) - [A Guide to FastJson](https://www.baeldung.com/fastjson) +- [Check Whether a String is Valid JSON in Java](https://www.baeldung.com/java-validate-json-string) - More Articles: [[<-- prev]](/json) diff --git a/json-2/pom.xml b/json-2/pom.xml index 751199d394..6fbdebc953 100644 --- a/json-2/pom.xml +++ b/json-2/pom.xml @@ -14,6 +14,11 @@ + + org.json + json + ${json.version} + com.alibaba fastjson @@ -22,7 +27,7 @@ org.jsonschema2pojo jsonschema2pojo-core - 1.1.1 + ${jsonschema2pojo-core.version} com.jsoniter @@ -57,7 +62,7 @@ com.io-informatics.oss jackson-jsonld - 0.1.1 + ${jackson-jsonld.version} jackson-databind @@ -80,7 +85,7 @@ de.escalon.hypermedia hydra-jsonld - 0.4.2 + ${hydra-jsonld.version} jackson-databind @@ -91,7 +96,7 @@ com.github.jsonld-java jsonld-java - 0.13.0 + ${jsonld-java.version} jackson-core @@ -148,6 +153,11 @@ 0.9.23 1.9.2 1.2.21 + 20211205 + 1.1.1 + 0.1.1 + 0.4.2 + 0.13.0 \ No newline at end of file diff --git a/json-2/src/main/java/com/baeldung/jsonvalidation/GsonValidator.java b/json-2/src/main/java/com/baeldung/jsonvalidation/GsonValidator.java new file mode 100644 index 0000000000..841513fc28 --- /dev/null +++ b/json-2/src/main/java/com/baeldung/jsonvalidation/GsonValidator.java @@ -0,0 +1,32 @@ +package com.baeldung.jsonvalidation; + +import java.io.IOException; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.TypeAdapter; + +public class GsonValidator { + + final TypeAdapter strictAdapter = new Gson().getAdapter(JsonElement.class); + + public boolean isValid(String json) { + try { + JsonParser.parseString(json); + } catch (JsonSyntaxException e) { + return false; + } + return true; + } + + public boolean isValidStrict(String json) { + try { + strictAdapter.fromJson(json); + } catch (JsonSyntaxException | IOException e) { + return false; + } + return true; + } +} diff --git a/json-2/src/main/java/com/baeldung/jsonvalidation/JacksonValidator.java b/json-2/src/main/java/com/baeldung/jsonvalidation/JacksonValidator.java new file mode 100644 index 0000000000..8c339f46c8 --- /dev/null +++ b/json-2/src/main/java/com/baeldung/jsonvalidation/JacksonValidator.java @@ -0,0 +1,18 @@ +package com.baeldung.jsonvalidation; + +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonValidator { + + final ObjectMapper mapper = new ObjectMapper(); + + public boolean isValid(String json) { + try { + mapper.readTree(json); + } catch (JacksonException e) { + return false; + } + return true; + } +} diff --git a/json-2/src/main/java/com/baeldung/jsonvalidation/JsonValidator.java b/json-2/src/main/java/com/baeldung/jsonvalidation/JsonValidator.java new file mode 100644 index 0000000000..e4183e2322 --- /dev/null +++ b/json-2/src/main/java/com/baeldung/jsonvalidation/JsonValidator.java @@ -0,0 +1,30 @@ +package com.baeldung.jsonvalidation; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class JsonValidator { + + public boolean isValidObject(String json) { + try { + new JSONObject(json); + } catch (JSONException e) { + return false; + } + return true; + } + + public boolean isValidJson(String json) { + try { + new JSONObject(json); + } catch (JSONException e) { + try { + new JSONArray(json); + } catch (JSONException ne) { + return false; + } + } + return true; + } +} diff --git a/json-2/src/test/java/com/baeldung/jsonvalidation/GsonValidatorUnitTest.java b/json-2/src/test/java/com/baeldung/jsonvalidation/GsonValidatorUnitTest.java new file mode 100644 index 0000000000..3b8989bdb5 --- /dev/null +++ b/json-2/src/test/java/com/baeldung/jsonvalidation/GsonValidatorUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.jsonvalidation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class GsonValidatorUnitTest { + + private final GsonValidator validator = new GsonValidator(); + + @Test + public void givenValidObjectJson_whenValidatingNonStrict_thenValid() { + String json = "{\"email\": \"example@com\", \"name\": \"John\"}"; + assertTrue(validator.isValid(json)); + } + + @Test + public void givenValidArrayJson_whenValidatingNonStrict_thenValid() { + String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]"; + assertTrue(validator.isValid(json)); + } + + @Test + public void givenInvalidJson_whenValidatingNonStrict_thenValid() { + String json = "Invalid_Json"; + assertTrue(validator.isValid(json)); + } + + @Test + public void givenInvalidJson_whenValidatingStrict_thenInvalid() { + String json = "Invalid_Json"; + assertFalse(validator.isValidStrict(json)); + } +} diff --git a/json-2/src/test/java/com/baeldung/jsonvalidation/JacksonValidatorUnitTest.java b/json-2/src/test/java/com/baeldung/jsonvalidation/JacksonValidatorUnitTest.java new file mode 100644 index 0000000000..b633af7fdc --- /dev/null +++ b/json-2/src/test/java/com/baeldung/jsonvalidation/JacksonValidatorUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.jsonvalidation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class JacksonValidatorUnitTest { + + private final JacksonValidator validator = new JacksonValidator(); + + @Test + public void givenValidObjectJson_whenValidating_thenValid() { + String json = "{\"email\": \"example@com\", \"name\": \"John\"}"; + assertTrue(validator.isValid(json)); + } + + @Test + public void givenValidArrayJson_whenValidating_thenValid() { + String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]"; + assertTrue(validator.isValid(json)); + } + + @Test + public void givenInvalidJson_whenValidating_thenInvalid() { + String json = "Invalid_Json"; + assertFalse(validator.isValid(json)); + } +} diff --git a/json-2/src/test/java/com/baeldung/jsonvalidation/JsonValidatorUnitTest.java b/json-2/src/test/java/com/baeldung/jsonvalidation/JsonValidatorUnitTest.java new file mode 100644 index 0000000000..a590b3f709 --- /dev/null +++ b/json-2/src/test/java/com/baeldung/jsonvalidation/JsonValidatorUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.jsonvalidation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class JsonValidatorUnitTest { + + private final JsonValidator validator = new JsonValidator(); + + @Test + public void givenValidObjectJson_whenValidatingObject_thenValid() { + String json = "{\"email\": \"example@com\", \"name\": \"John\"}"; + assertTrue(validator.isValidObject(json)); + } + + @Test + public void givenInvalidJson_whenValidating_thenInvalid() { + String json = "Invalid_Json"; + assertFalse(validator.isValidObject(json)); + } + + @Test + public void givenValidArrayJson_whenValidatingObject_thenInvalid() { + String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]"; + assertFalse(validator.isValidObject(json)); + } + + @Test + public void givenValidJson_whenValidatingJson_thenValid() { + String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]"; + assertTrue(validator.isValidJson(json)); + } +} diff --git a/kubernetes/k8s-intro/pom.xml b/kubernetes/k8s-intro/pom.xml index 6d1cec9971..067700bdad 100644 --- a/kubernetes/k8s-intro/pom.xml +++ b/kubernetes/k8s-intro/pom.xml @@ -15,7 +15,7 @@ io.kubernetes client-java - 11.0.0 + ${client-java.version} ch.qos.logback @@ -39,4 +39,8 @@ + + 11.0.0 + + \ No newline at end of file diff --git a/libraries-3/README.md b/libraries-3/README.md index 047d6738a1..99b1b60a0a 100644 --- a/libraries-3/README.md +++ b/libraries-3/README.md @@ -16,5 +16,6 @@ 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) -- [Introduction to Structurizr](https://www.baeldung.com/structurizr) +- [Intro to Structurizr](https://www.baeldung.com/structurizr) +- [Introduction to Immutables](https://www.baeldung.com/immutables) - More articles [[<-- prev]](../libraries-2) [[next -->]](../libraries-4) diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index e38aecd879..d68a9e0703 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -112,6 +112,17 @@ structurizr-plantuml ${structurizr.version} + + org.immutables + value + ${immutables.version} + + + org.mutabilitydetector + MutabilityDetector + ${mutabilitydetector.version} + test + @@ -166,7 +177,7 @@ - -XepExcludedPaths:(.*)/test/.*|(.*)/jcabi/.* @@ -179,7 +190,7 @@ plexus-compiler-javac-errorprone 2.8 - com.google.errorprone @@ -256,6 +267,8 @@ 2.8 2.1.3 1.0.0 + 2.5.6 + 0.9.6 \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/Address.java b/libraries-3/src/main/java/com/baeldung/immutable/Address.java similarity index 100% rename from immutables/src/main/java/com/baeldung/immutable/Address.java rename to libraries-3/src/main/java/com/baeldung/immutable/Address.java diff --git a/immutables/src/main/java/com/baeldung/immutable/Person.java b/libraries-3/src/main/java/com/baeldung/immutable/Person.java similarity index 100% rename from immutables/src/main/java/com/baeldung/immutable/Person.java rename to libraries-3/src/main/java/com/baeldung/immutable/Person.java diff --git a/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java b/libraries-3/src/main/java/com/baeldung/immutable/auxiliary/Person.java similarity index 100% rename from immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java rename to libraries-3/src/main/java/com/baeldung/immutable/auxiliary/Person.java diff --git a/immutables/src/main/java/com/baeldung/immutable/default_/Person.java b/libraries-3/src/main/java/com/baeldung/immutable/default_/Person.java similarity index 100% rename from immutables/src/main/java/com/baeldung/immutable/default_/Person.java rename to libraries-3/src/main/java/com/baeldung/immutable/default_/Person.java diff --git a/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java b/libraries-3/src/main/java/com/baeldung/immutable/parameter/Person.java similarity index 100% rename from immutables/src/main/java/com/baeldung/immutable/parameter/Person.java rename to libraries-3/src/main/java/com/baeldung/immutable/parameter/Person.java diff --git a/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java b/libraries-3/src/main/java/com/baeldung/immutable/prehash/Person.java similarity index 100% rename from immutables/src/main/java/com/baeldung/immutable/prehash/Person.java rename to libraries-3/src/main/java/com/baeldung/immutable/prehash/Person.java diff --git a/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java b/libraries-3/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java similarity index 100% rename from immutables/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java rename to libraries-3/src/test/java/com/baeldung/immutable/ImmutablePersonUnitTest.java diff --git a/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryUnitTest.java b/libraries-3/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryUnitTest.java similarity index 100% rename from immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryUnitTest.java rename to libraries-3/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryUnitTest.java diff --git a/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultUnitTest.java b/libraries-3/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultUnitTest.java similarity index 100% rename from immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultUnitTest.java rename to libraries-3/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultUnitTest.java diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index dd48453a8c..f0f5338560 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -172,7 +172,7 @@ 1.0.0 2.4.0 2.8.2 - 1.1.0 + 1.1.1 1.5.0 3.8.4 0.15.0 diff --git a/libraries-primitive/pom.xml b/libraries-primitive/pom.xml index ed4982d91c..7d12e9a436 100644 --- a/libraries-primitive/pom.xml +++ b/libraries-primitive/pom.xml @@ -8,6 +8,12 @@ 1.0-SNAPSHOT libraries-primitive + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + diff --git a/lightrun/README.md b/lightrun/README.md new file mode 100644 index 0000000000..18d4ccc12f --- /dev/null +++ b/lightrun/README.md @@ -0,0 +1,36 @@ +# Lightrun Example Application - Tasks Management + +This application exists as an example for the Lightrun series of articles. + +## Building + +This application requires [Apache Maven](https://maven.apache.org/) and [Java 17+](https://www.oracle.com/java/technologies/downloads/). + +Building the code is done by executing: + +``` +$ mvn install +``` + +from the top level. + +## Running + +The application consists of three services: + +* Tasks +* Users +* API + +These are all Spring Boot applications. + +The Tasks and Users services exist as microservices for managing one facet of data. Each uses a database, and utilise a JMS queue between them as well. For convenience this infrastructure is all embedded in the applications. + +This does mean that the startup order is important. The JMS queue exists within the Tasks service and is connected to from the Users service. As such, the Tasks service must be started before the others. + +Each service can be started either by executing `mvn spring-boot:run` from within the appropriate directory. Alternatively, as Spring Boot applications, the build will produce an executable JAR file within the `target` directory that can be executed as, for +example: + +``` +$ java -jar ./target/tasks-service-0.0.1-SNAPSHOT.jar +``` diff --git a/lightrun/api-service/.gitignore b/lightrun/api-service/.gitignore new file mode 100644 index 0000000000..549e00a2a9 --- /dev/null +++ b/lightrun/api-service/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/lightrun/api-service/pom.xml b/lightrun/api-service/pom.xml new file mode 100644 index 0000000000..3423c490f1 --- /dev/null +++ b/lightrun/api-service/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.7 + + + com.baeldung + api-service + 0.0.1-SNAPSHOT + api-service + Aggregator Service for LightRun Article + + 17 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/ApiServiceApplication.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/ApiServiceApplication.java new file mode 100644 index 0000000000..a9b29cbd4b --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/ApiServiceApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.apiservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ApiServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ApiServiceApplication.class, args); + } + +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/RequestIdGenerator.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RequestIdGenerator.java new file mode 100644 index 0000000000..f15738c1e6 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RequestIdGenerator.java @@ -0,0 +1,33 @@ +package com.baeldung.apiservice; + +import java.util.UUID; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.MDC; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@Component +public class RequestIdGenerator implements HandlerInterceptor { + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String requestId = UUID.randomUUID() + .toString(); + + MDC.put(RequestIdGenerator.class.getCanonicalName(), requestId); + response.addHeader("X-Request-Id", requestId); + + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + MDC.remove(RequestIdGenerator.class.getCanonicalName()); + } + + public static String getRequestId() { + return MDC.get(RequestIdGenerator.class.getCanonicalName()); + } +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/RestTemplateConfig.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RestTemplateConfig.java new file mode 100644 index 0000000000..1582ba5953 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/RestTemplateConfig.java @@ -0,0 +1,20 @@ +package com.baeldung.apiservice; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) { + return builder.additionalInterceptors((request, body, execution) -> { + request.getHeaders() + .add("X-Request-Id", RequestIdGenerator.getRequestId()); + + return execution.execute(request, body); + }) + .build(); + } +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/WebConfig.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/WebConfig.java new file mode 100644 index 0000000000..9edfcff6f6 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/WebConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.apiservice; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + @Autowired + private RequestIdGenerator requestIdGenerator; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(requestIdGenerator); + } +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TaskResponse.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TaskResponse.java new file mode 100644 index 0000000000..875390fdcd --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TaskResponse.java @@ -0,0 +1,6 @@ +package com.baeldung.apiservice.adapters.http; + +import java.time.Instant; + +public record TaskResponse(String id, String title, Instant created, UserResponse createdBy, UserResponse assignedTo, String status) { +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TasksController.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TasksController.java new file mode 100644 index 0000000000..55b449f249 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/TasksController.java @@ -0,0 +1,56 @@ +package com.baeldung.apiservice.adapters.http; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.apiservice.adapters.tasks.Task; +import com.baeldung.apiservice.adapters.tasks.TaskRepository; +import com.baeldung.apiservice.adapters.users.UserRepository; + +@RequestMapping("/") +@RestController +public class TasksController { + @Autowired + private TaskRepository taskRepository; + @Autowired + private UserRepository userRepository; + + @GetMapping("/{id}") + public TaskResponse getTaskById(@PathVariable("id") String id) { + Task task = taskRepository.getTaskById(id); + + if (task == null) { + throw new UnknownTaskException(); + } + + return buildResponse(task); + } + + private TaskResponse buildResponse(Task task) { + return new TaskResponse(task.id(), task.title(), task.created(), getUser(task.createdBy()), getUser(task.assignedTo()), task.status()); + } + + private UserResponse getUser(String userId) { + if (userId == null) { + return null; + } + + var user = userRepository.getUserById(userId); + if (user == null) { + return null; + } + + return new UserResponse(user.id(), user.name()); + } + + @ExceptionHandler(UnknownTaskException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public void handleUnknownTask() { + } +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UnknownTaskException.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UnknownTaskException.java new file mode 100644 index 0000000000..1635ca8796 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UnknownTaskException.java @@ -0,0 +1,4 @@ +package com.baeldung.apiservice.adapters.http; + +public class UnknownTaskException extends RuntimeException { +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UserResponse.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UserResponse.java new file mode 100644 index 0000000000..f311b895a8 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/http/UserResponse.java @@ -0,0 +1,4 @@ +package com.baeldung.apiservice.adapters.http; + +public record UserResponse(String id, String name) { +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/Task.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/Task.java new file mode 100644 index 0000000000..188d3e951c --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/Task.java @@ -0,0 +1,6 @@ +package com.baeldung.apiservice.adapters.tasks; + +import java.time.Instant; + +public record Task(String id, String title, Instant created, String createdBy, String assignedTo, String status) { +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/TaskRepository.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/TaskRepository.java new file mode 100644 index 0000000000..9260a125af --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/tasks/TaskRepository.java @@ -0,0 +1,30 @@ +package com.baeldung.apiservice.adapters.tasks; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +@Repository +public class TaskRepository { + @Autowired + private RestTemplate restTemplate; + + @Value("${tasks-service.url}") + private String tasksService; + + public Task getTaskById(String id) { + var uri = UriComponentsBuilder.fromUriString(tasksService) + .path(id) + .build() + .toUri(); + + try { + return restTemplate.getForObject(uri, Task.class); + } catch (HttpClientErrorException.NotFound e) { + return null; + } + } +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/User.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/User.java new file mode 100644 index 0000000000..a3a53c0805 --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/User.java @@ -0,0 +1,4 @@ +package com.baeldung.apiservice.adapters.users; + +public record User(String id, String name) { +} diff --git a/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/UserRepository.java b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/UserRepository.java new file mode 100644 index 0000000000..d5625f6efc --- /dev/null +++ b/lightrun/api-service/src/main/java/com/baeldung/apiservice/adapters/users/UserRepository.java @@ -0,0 +1,30 @@ +package com.baeldung.apiservice.adapters.users; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +@Repository +public class UserRepository { + @Autowired + private RestTemplate restTemplate; + + @Value("${users-service.url}") + private String usersService; + + public User getUserById(String id) { + var uri = UriComponentsBuilder.fromUriString(usersService) + .path(id) + .build() + .toUri(); + + try { + return restTemplate.getForObject(uri, User.class); + } catch (HttpClientErrorException.NotFound e) { + return null; + } + } +} diff --git a/lightrun/api-service/src/main/resources/application.properties b/lightrun/api-service/src/main/resources/application.properties new file mode 100644 index 0000000000..f3f227f46f --- /dev/null +++ b/lightrun/api-service/src/main/resources/application.properties @@ -0,0 +1,2 @@ +users-service.url=http://localhost:8081 +tasks-service.url=http://localhost:8082 \ No newline at end of file diff --git a/lightrun/pom.xml b/lightrun/pom.xml new file mode 100644 index 0000000000..3ce71069a9 --- /dev/null +++ b/lightrun/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + com.baelduung + lightrun + 0.0.1-SNAPSHOT + pom + lightrun + Services for LightRun Article + + + tasks-service + users-service + api-service + + diff --git a/lightrun/tasks-service/.gitignore b/lightrun/tasks-service/.gitignore new file mode 100644 index 0000000000..549e00a2a9 --- /dev/null +++ b/lightrun/tasks-service/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/lightrun/tasks-service/pom.xml b/lightrun/tasks-service/pom.xml new file mode 100644 index 0000000000..441b4d3713 --- /dev/null +++ b/lightrun/tasks-service/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.7 + + + com.baeldung + tasks-service + 0.0.1-SNAPSHOT + tasks-service + Tasks Service for LightRun Article + + 17 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-artemis + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.flywaydb + flyway-core + + + + com.h2database + h2 + runtime + + + org.apache.activemq + artemis-jms-server + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/ArtemisConfig.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/ArtemisConfig.java new file mode 100644 index 0000000000..56ee3bbc93 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/ArtemisConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.tasksservice; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConfigurationCustomizer; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ArtemisConfig implements ArtemisConfigurationCustomizer { + @Value("${spring.artemis.host}") + private String hostname; + + @Value("${spring.artemis.port}") + private int port; + + @Override + public void customize(org.apache.activemq.artemis.core.config.Configuration configuration) { + try { + configuration.addAcceptorConfiguration("remote", "tcp://" + hostname + ":" + port); + } catch (Exception e) { + throw new RuntimeException("Failed to configure Artemis listener", e); + } + } +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/TasksServiceApplication.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/TasksServiceApplication.java new file mode 100644 index 0000000000..dfd9859674 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/TasksServiceApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.tasksservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class TasksServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(TasksServiceApplication.class, args); + } + +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/CreateTaskRequest.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/CreateTaskRequest.java new file mode 100644 index 0000000000..64acea8b1b --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/CreateTaskRequest.java @@ -0,0 +1,15 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.adapters.http; + +public record CreateTaskRequest(String title, String createdBy) { +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/PatchTaskRequest.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/PatchTaskRequest.java new file mode 100644 index 0000000000..20974b1c1d --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/PatchTaskRequest.java @@ -0,0 +1,17 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.adapters.http; + +import java.util.Optional; + +public record PatchTaskRequest(Optional status, Optional assignedTo) { +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TaskResponse.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TaskResponse.java new file mode 100644 index 0000000000..4e01a649b1 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TaskResponse.java @@ -0,0 +1,17 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.adapters.http; + +import java.time.Instant; + +public record TaskResponse(String id, String title, Instant created, String createdBy, String assignedTo, String status) { +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TasksController.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TasksController.java new file mode 100644 index 0000000000..a4145a2243 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/TasksController.java @@ -0,0 +1,84 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.adapters.http; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +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.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.tasksservice.adapters.repository.TaskRecord; +import com.baeldung.tasksservice.service.TasksService; +import com.baeldung.tasksservice.service.UnknownTaskException; + +@RestController +@RequestMapping("/") +class TasksController { + @Autowired + private TasksService tasksService; + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public TaskResponse createTask(@RequestBody CreateTaskRequest body) { + var task = tasksService.createTask(body.title(), body.createdBy()); + return buildResponse(task); + } + + @GetMapping + public List searchTasks(@RequestParam("status") Optional status, @RequestParam("createdBy") Optional createdBy) { + var tasks = tasksService.search(status, createdBy); + + return tasks.stream() + .map(this::buildResponse) + .collect(Collectors.toList()); + } + + @GetMapping("/{id}") + public TaskResponse getTask(@PathVariable("id") String id) { + var task = tasksService.getTaskById(id); + return buildResponse(task); + } + + @DeleteMapping("/{id}") + public void deleteTask(@PathVariable("id") String id) { + tasksService.deleteTaskById(id); + } + + @PatchMapping("/{id}") + public TaskResponse patchTask(@PathVariable("id") String id, @RequestBody PatchTaskRequest body) { + var task = tasksService.updateTask(id, body.status(), body.assignedTo()); + + return buildResponse(task); + } + + private TaskResponse buildResponse(final TaskRecord task) { + return new TaskResponse(task.getId(), task.getTitle(), task.getCreated(), task.getCreatedBy(), task.getAssignedTo(), task.getStatus()); + } + + @ExceptionHandler(UnknownTaskException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public void handleUnknownTask() { + } +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/http-client.env.json b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/http-client.env.json new file mode 100644 index 0000000000..f27fc4325b --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/http-client.env.json @@ -0,0 +1,5 @@ +{ + "local-tasks": { + "host": "localhost:8082" + } +} \ No newline at end of file diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/tasks.http b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/tasks.http new file mode 100644 index 0000000000..eb7d578ac9 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/http/tasks.http @@ -0,0 +1,35 @@ +GET http://{{host}}/createdemoapplication1 HTTP/1.1 + +### +GET http://{{host}}/unknown HTTP/1.1 + +### +GET http://{{host}}?status=PENDING + +### +GET http://{{host}}?createdBy=baeldung + +### +GET http://{{host}}?createdBy=baeldung&status=COMPLETE + +### +DELETE http://{{host}}/createdemoapplication1 HTTP/1.1 + +### +DELETE http://{{host}}/unknown HTTP/1.1 + +### +POST http://{{host}} HTTP/1.1 +Content-Type: application/json + +{ + "title": "My Task", + "createdBy": "graham" +} +### +PATCH http://{{host}}/createdemoapplication1 HTTP/1.1 +Content-Type: application/json + +{ + "status": "COMPLETE" +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/jms/JmsConsumer.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/jms/JmsConsumer.java new file mode 100644 index 0000000000..c380a16acc --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/jms/JmsConsumer.java @@ -0,0 +1,18 @@ +package com.baeldung.tasksservice.adapters.jms; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.annotation.JmsListener; +import org.springframework.stereotype.Service; + +import com.baeldung.tasksservice.service.DeletedUserService; + +@Service +public class JmsConsumer { + @Autowired + private DeletedUserService deletedUserService; + + @JmsListener(destination = "deleted_user") + public void receive(String user) { + deletedUserService.handleDeletedUser(user); + } +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TaskRecord.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TaskRecord.java new file mode 100644 index 0000000000..dee3017a59 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TaskRecord.java @@ -0,0 +1,80 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.adapters.repository; + +import java.time.Instant; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "tasks") +public class TaskRecord { + @Id + @Column(name = "task_id") + private String id; + private String title; + @Column(name = "created_at") + private Instant created; + @Column(name = "created_by") + private String createdBy; + @Column(name = "assigned_to") + private String assignedTo; + private String status; + + public TaskRecord(final String id, final String title, final Instant created, final String createdBy, final String assignedTo, final String status) { + this.id = id; + this.title = title; + this.created = created; + this.createdBy = createdBy; + this.assignedTo = assignedTo; + this.status = status; + } + + private TaskRecord() { + // Needed for JPA + } + + public String getId() { + return id; + } + + public String getTitle() { + return title; + } + + public Instant getCreated() { + return created; + } + + public String getCreatedBy() { + return createdBy; + } + + public String getAssignedTo() { + return assignedTo; + } + + public String getStatus() { + return status; + } + + public void setAssignedTo(final String assignedTo) { + this.assignedTo = assignedTo; + } + + public void setStatus(final String status) { + this.status = status; + } +} \ No newline at end of file diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TasksRepository.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TasksRepository.java new file mode 100644 index 0000000000..9b6f041fd2 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/adapters/repository/TasksRepository.java @@ -0,0 +1,28 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.adapters.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TasksRepository extends JpaRepository { + List findByStatus(String status); + + List findByCreatedBy(String createdBy); + + List findByStatusAndCreatedBy(String status, String createdBy); + + List findByAssignedTo(String assignedTo); +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/DeletedUserService.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/DeletedUserService.java new file mode 100644 index 0000000000..fa0c3572fb --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/DeletedUserService.java @@ -0,0 +1,27 @@ +package com.baeldung.tasksservice.service; + +import javax.transaction.Transactional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.tasksservice.adapters.repository.TaskRecord; +import com.baeldung.tasksservice.adapters.repository.TasksRepository; + +@Service +public class DeletedUserService { + @Autowired + private TasksRepository tasksRepository; + + @Transactional + public void handleDeletedUser(String user) { + var ownedByUser = tasksRepository.findByCreatedBy(user); + tasksRepository.deleteAll(ownedByUser); + + var assignedToUser = tasksRepository.findByAssignedTo(user); + for (TaskRecord record : assignedToUser) { + record.setAssignedTo(null); + record.setStatus("PENDING"); + } + } +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/TasksService.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/TasksService.java new file mode 100644 index 0000000000..3539dbbc3c --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/TasksService.java @@ -0,0 +1,73 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.service; + +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import javax.transaction.Transactional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.tasksservice.adapters.repository.TaskRecord; +import com.baeldung.tasksservice.adapters.repository.TasksRepository; + +@Service +public class TasksService { + @Autowired + private TasksRepository tasksRepository; + + public TaskRecord getTaskById(String id) { + return tasksRepository.findById(id) + .orElseThrow(() -> new UnknownTaskException(id)); + } + + @Transactional + public void deleteTaskById(String id) { + var task = tasksRepository.findById(id) + .orElseThrow(() -> new UnknownTaskException(id)); + tasksRepository.delete(task); + } + + public List search(Optional createdBy, Optional status) { + if (createdBy.isPresent() && status.isPresent()) { + return tasksRepository.findByStatusAndCreatedBy(status.get(), createdBy.get()); + } else if (createdBy.isPresent()) { + return tasksRepository.findByCreatedBy(createdBy.get()); + } else if (status.isPresent()) { + return tasksRepository.findByStatus(status.get()); + } else { + return tasksRepository.findAll(); + } + } + + @Transactional + public TaskRecord updateTask(String id, Optional newStatus, Optional newAssignedTo) { + var task = tasksRepository.findById(id) + .orElseThrow(() -> new UnknownTaskException(id)); + + newStatus.ifPresent(task::setStatus); + newAssignedTo.ifPresent(task::setAssignedTo); + + return task; + } + + public TaskRecord createTask(String title, String createdBy) { + var task = new TaskRecord(UUID.randomUUID() + .toString(), title, Instant.now(), createdBy, null, "PENDING"); + tasksRepository.save(task); + return task; + } +} diff --git a/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/UnknownTaskException.java b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/UnknownTaskException.java new file mode 100644 index 0000000000..fd9fce4d16 --- /dev/null +++ b/lightrun/tasks-service/src/main/java/com/baeldung/tasksservice/service/UnknownTaskException.java @@ -0,0 +1,24 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.tasksservice.service; + +public class UnknownTaskException extends RuntimeException { + private final String id; + + public UnknownTaskException(final String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/lightrun/tasks-service/src/main/resources/application.properties b/lightrun/tasks-service/src/main/resources/application.properties new file mode 100644 index 0000000000..88326ed10e --- /dev/null +++ b/lightrun/tasks-service/src/main/resources/application.properties @@ -0,0 +1,9 @@ +server.port=8082 +spring.artemis.mode=EMBEDDED +spring.artemis.host=localhost +spring.artemis.port=61616 +spring.artemis.embedded.enabled=true +spring.jms.template.default-destination=my-queue-1 +logging.level.org.apache.activemq.audit.base=WARN +logging.level.org.apache.activemq.audit.message=WARN + diff --git a/lightrun/tasks-service/src/main/resources/db/migration/V1_0_0__create-tasks-table.sql b/lightrun/tasks-service/src/main/resources/db/migration/V1_0_0__create-tasks-table.sql new file mode 100644 index 0000000000..f2365c2687 --- /dev/null +++ b/lightrun/tasks-service/src/main/resources/db/migration/V1_0_0__create-tasks-table.sql @@ -0,0 +1,13 @@ +CREATE TABLE tasks ( + task_id VARCHAR(36) PRIMARY KEY, + title VARCHAR(100) NOT NULL, + created_at DATETIME NOT NULL, + created_by VARCHAR(36) NOT NULL, + assigned_to VARCHAR(36) NULL, + status VARCHAR(20) NOT NULL +); + +INSERT INTO tasks(task_id, title, created_at, created_by, assigned_to, status) VALUES + ('createdemoapplication1', 'Create demo applications - Tasks', '2022-05-05 12:34:56', 'baeldung', 'coxg', 'IN_PROGRESS'), + ('createdemoapplication2', 'Create demo applications - Users', '2022-05-05 12:34:56', 'baeldung', NULL, 'PENDING'), + ('createdemoapplication3', 'Create demo applications - API', '2022-05-05 12:34:56', 'baeldung', NULL, 'PENDING'); \ No newline at end of file diff --git a/lightrun/users-service/.gitignore b/lightrun/users-service/.gitignore new file mode 100644 index 0000000000..549e00a2a9 --- /dev/null +++ b/lightrun/users-service/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/lightrun/users-service/README.md b/lightrun/users-service/README.md new file mode 100644 index 0000000000..e7faae858f --- /dev/null +++ b/lightrun/users-service/README.md @@ -0,0 +1,36 @@ +# Lightrun Example Application - Tasks Management + +This application exists as an example for the Lightrun series of articles. + +## Building + +This application requires [Apache Maven](https://maven.apache.org/) and [Java 17+](https://www.oracle.com/java/technologies/downloads/). It does use the Maven Wrapper, so it can be built with only Java available on the path. + +As such, building the code is done by executing: + +``` +$ ./mvnw install +``` + +from the top level. + +## Running + +The application consists of three services: + +* Tasks +* Users +* API + +These are all Spring Boot applications. + +The Tasks and Users services exist as microservices for managing one facet of data. Each uses a database, and utilise a JMS queue between them as well. For convenience this infrastructure is all embedded in the applications. + +This does mean that the startup order is important. The JMS queue exists within the Tasks service and is connected to from the Users service. As such, the Tasks service must be started before the others. + +Each service can be started either by executing `mvn spring-boot:run` from within the appropriate directory. Alternatively, as Spring Boot applications, the build will produce an executable JAR file within the `target` directory that can be executed as, for +example: + +``` +$ java -jar ./target/tasks-service-0.0.1-SNAPSHOT.jar +``` diff --git a/lightrun/users-service/pom.xml b/lightrun/users-service/pom.xml new file mode 100644 index 0000000000..63596ed67b --- /dev/null +++ b/lightrun/users-service/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.7 + + + com.baeldung + users-service + 0.0.1-SNAPSHOT + users-service + Users Service for LightRun Article + + 17 + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-artemis + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.flywaydb + flyway-core + + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/JmsConfig.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/JmsConfig.java new file mode 100644 index 0000000000..c803c9af13 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/JmsConfig.java @@ -0,0 +1,29 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jms.support.converter.MappingJackson2MessageConverter; +import org.springframework.jms.support.converter.MessageConverter; +import org.springframework.jms.support.converter.MessageType; + +@Configuration +public class JmsConfig { + @Bean + public MessageConverter jacksonJmsMessageConverter() { + MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); + converter.setTargetType(MessageType.TEXT); + converter.setTypeIdPropertyName("_type"); + return converter; + } +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/UsersServiceApplication.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/UsersServiceApplication.java new file mode 100644 index 0000000000..3910960282 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/UsersServiceApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.usersservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UsersServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UsersServiceApplication.class, args); + } + +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/CreateUserRequest.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/CreateUserRequest.java new file mode 100644 index 0000000000..c3dfc8d068 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/CreateUserRequest.java @@ -0,0 +1,15 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.http; + +public record CreateUserRequest(String name) { +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/PatchUserRequest.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/PatchUserRequest.java new file mode 100644 index 0000000000..acaf7e635f --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/PatchUserRequest.java @@ -0,0 +1,17 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.http; + +import java.util.Optional; + +public record PatchUserRequest(Optional name) { +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UserResponse.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UserResponse.java new file mode 100644 index 0000000000..e74ede65d5 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UserResponse.java @@ -0,0 +1,15 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.http; + +public record UserResponse(String id, String name) { +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UsersController.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UsersController.java new file mode 100644 index 0000000000..795d240fe9 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/UsersController.java @@ -0,0 +1,70 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.http; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.usersservice.adapters.repository.UserRecord; +import com.baeldung.usersservice.service.UnknownUserException; +import com.baeldung.usersservice.service.UsersService; + +@RestController +@RequestMapping("/") +class UsersController { + @Autowired + private UsersService usersService; + + @GetMapping("/{id}") + public UserResponse getUser(@PathVariable("id") String id) { + var user = usersService.getUserById(id); + return buildResponse(user); + } + + @DeleteMapping("/{id}") + public void deleteUser(@PathVariable("id") String id) { + usersService.deleteUserById(id); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public UserResponse createUser(@RequestBody CreateUserRequest body) { + var user = usersService.createUser(body.name()); + return buildResponse(user); + } + + @PatchMapping("/{id}") + public UserResponse patchUser(@PathVariable("id") String id, @RequestBody PatchUserRequest body) { + var user = usersService.updateUser(id, body.name()); + + return buildResponse(user); + } + + private UserResponse buildResponse(final UserRecord user) { + return new UserResponse(user.getId(), user.getName()); + } + + @ExceptionHandler(UnknownUserException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public void handleUnknownUser() { + } +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/http-client.env.json b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/http-client.env.json new file mode 100644 index 0000000000..3be2f710ff --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/http-client.env.json @@ -0,0 +1,5 @@ +{ + "local-users": { + "host": "localhost:8081" + } +} \ No newline at end of file diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/users.http b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/users.http new file mode 100644 index 0000000000..904c5f1cf1 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/http/users.http @@ -0,0 +1,25 @@ +GET http://{{host}}/baeldung HTTP/1.1 + +### +GET http://{{host}}/unknown HTTP/1.1 + +### +DELETE http://{{host}}/baeldung HTTP/1.1 + +### +DELETE http://{{host}}/unknown HTTP/1.1 + +### +POST http://{{host}} HTTP/1.1 +Content-Type: application/json + +{ + "name": "Testing" +} +### +PATCH http://{{host}}/coxg HTTP/1.1 +Content-Type: application/json + +{ + "name": "Test Name" +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/jms/JmsSender.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/jms/JmsSender.java new file mode 100644 index 0000000000..f5d5d7900f --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/jms/JmsSender.java @@ -0,0 +1,26 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.jms; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.stereotype.Repository; + +@Repository +public class JmsSender { + @Autowired + private JmsTemplate jmsTemplate; + + public void sendDeleteUserMessage(String userId) { + jmsTemplate.convertAndSend("deleted_user", userId); + } +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UserRecord.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UserRecord.java new file mode 100644 index 0000000000..fe87ac3ffe --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UserRecord.java @@ -0,0 +1,47 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.repository; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class UserRecord { + @Id + @Column(name = "user_id") + private String id; + private String name; + + public UserRecord(final String id, final String name) { + this.id = id; + this.name = name; + } + + private UserRecord() { + // Needed for JPA + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UsersRepository.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UsersRepository.java new file mode 100644 index 0000000000..ed193a4955 --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/adapters/repository/UsersRepository.java @@ -0,0 +1,19 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.adapters.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UsersRepository extends JpaRepository { +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UnknownUserException.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UnknownUserException.java new file mode 100644 index 0000000000..d0ca79850c --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UnknownUserException.java @@ -0,0 +1,24 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.service; + +public class UnknownUserException extends RuntimeException { + private final String id; + + public UnknownUserException(final String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UsersService.java b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UsersService.java new file mode 100644 index 0000000000..5115a5a77b --- /dev/null +++ b/lightrun/users-service/src/main/java/com/baeldung/usersservice/service/UsersService.java @@ -0,0 +1,64 @@ +/**************************************************************************************************************** + * + * Copyright (c) 2022 OCLC, Inc. All Rights Reserved. + * + * OCLC proprietary information: the enclosed materials contain + * proprietary information of OCLC, Inc. and shall not be disclosed in whole or in + * any part to any third party or used by any person for any purpose, without written + * consent of OCLC, Inc. Duplication of any portion of these materials shall include this notice. + * + ******************************************************************************************************************/ + +package com.baeldung.usersservice.service; + +import java.util.Optional; +import java.util.UUID; + +import javax.transaction.Transactional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.usersservice.adapters.jms.JmsSender; +import com.baeldung.usersservice.adapters.repository.UserRecord; +import com.baeldung.usersservice.adapters.repository.UsersRepository; + +@Service +public class UsersService { + @Autowired + private UsersRepository usersRepository; + + @Autowired + private JmsSender jmsSender; + + public UserRecord getUserById(String id) { + return usersRepository.findById(id) + .orElseThrow(() -> new UnknownUserException(id)); + } + + @Transactional + public void deleteUserById(String id) { + var user = usersRepository.findById(id) + .orElseThrow(() -> new UnknownUserException(id)); + usersRepository.delete(user); + + jmsSender.sendDeleteUserMessage(id); + } + + @Transactional + public UserRecord updateUser(String id, Optional newName) { + var user = usersRepository.findById(id) + .orElseThrow(() -> new UnknownUserException(id)); + + newName.ifPresent(user::setName); + + return user; + } + + public UserRecord createUser(String name) { + var user = new UserRecord(UUID.randomUUID() + .toString(), name); + usersRepository.save(user); + return user; + } +} diff --git a/lightrun/users-service/src/main/resources/application.properties b/lightrun/users-service/src/main/resources/application.properties new file mode 100644 index 0000000000..616131c42e --- /dev/null +++ b/lightrun/users-service/src/main/resources/application.properties @@ -0,0 +1,7 @@ +server.port=8081 +spring.artemis.host=localhost +spring.artemis.port=61616 +spring.jms.template.default-destination=my-queue-1 +logging.level.org.apache.activemq.audit.base=WARN +logging.level.org.apache.activemq.audit.message=WARN + diff --git a/lightrun/users-service/src/main/resources/db/migration/V1_0_0__create-users-table.sql b/lightrun/users-service/src/main/resources/db/migration/V1_0_0__create-users-table.sql new file mode 100644 index 0000000000..d1ec9387e6 --- /dev/null +++ b/lightrun/users-service/src/main/resources/db/migration/V1_0_0__create-users-table.sql @@ -0,0 +1,8 @@ +CREATE TABLE users ( + user_id VARCHAR(36) PRIMARY KEY, + name VARCHAR(100) NOT NULL +); + +INSERT INTO users(user_id, name) VALUES + ('baeldung', 'Baeldung'), + ('coxg', 'Graham'); \ No newline at end of file diff --git a/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java index 80fa0edd96..d3b73637a4 100644 --- a/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java +++ b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerIntegrationTest.java @@ -5,7 +5,6 @@ import com.google.common.flogger.LoggerConfig; import com.google.common.flogger.StackSize; import org.junit.Test; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.stream.IntStream; @@ -25,13 +24,6 @@ public class FloggerIntegrationTest { }); } - @Test - public void givenATimeInterval_shouldLogAfterEveryTimeInterval() { - IntStream.range(0, 1_000_0000).forEach(value -> { - logger.atInfo().atMostEvery(10, TimeUnit.SECONDS).log("This log shows [every 10 seconds] => %d", value); - }); - } - @Test public void givenAnObject_shouldLogTheObject() { User user = new User(); diff --git a/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerManualTest.java b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerManualTest.java new file mode 100644 index 0000000000..a3444e596e --- /dev/null +++ b/logging-modules/flogger/src/test/java/com/baeldung/flogger/FloggerManualTest.java @@ -0,0 +1,25 @@ +package com.baeldung.flogger; + +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + +import org.junit.Test; + +import com.google.common.flogger.FluentLogger; + +public class FloggerManualTest { + static { +// System.setProperty("flogger.backend_factory", "com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance"); + System.setProperty("flogger.backend_factory", + "com.google.common.flogger.backend.slf4j.Slf4jBackendFactory#getInstance"); + } + private static final FluentLogger logger = FluentLogger.forEnclosingClass(); + + @Test + public void givenATimeInterval_shouldLogAfterEveryTimeInterval() { + IntStream.range(0, 1_000_0000).forEach(value -> { + logger.atInfo().atMostEvery(10, TimeUnit.SECONDS).log("This log shows [every 10 seconds] => %d", value); + }); + } + +} diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java index e842cda3d6..86cd00c6af 100644 --- a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutIntegrationTest.java @@ -1,47 +1,58 @@ package com.baeldung.logging.log4j2.tests; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; - +import com.baeldung.logging.log4j2.Log4j2BaseIntegrationTest; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.appender.WriterAppender; +import org.apache.logging.log4j.core.layout.JsonLayout; +import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.baeldung.logging.log4j2.Log4j2BaseIntegrationTest; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.CharArrayWriter; +import java.io.Writer; + +import static org.junit.Assert.assertTrue; public class JSONLayoutIntegrationTest extends Log4j2BaseIntegrationTest { - private static Logger logger; - private ByteArrayOutputStream consoleOutput = new ByteArrayOutputStream(); - private PrintStream ps = new PrintStream(consoleOutput); + private Appender appender; + private Logger logger; + private final Writer writer = new CharArrayWriter(); @Before public void setUp() { - // Redirect console output to our stream - System.setOut(ps); logger = LogManager.getLogger("CONSOLE_JSON_APPENDER"); + + appender = WriterAppender.newBuilder() + .setTarget(writer) + .setLayout(JsonLayout.newBuilder().build()) + .setName("json_layout_for_testing") + .build(); + appender.start(); + + ((org.apache.logging.log4j.core.Logger) logger).addAppender(appender); } @Test - public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() { + public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() throws Exception { logger.debug("Debug message"); - String currentLog = consoleOutput.toString(); - assertTrue(currentLog.isEmpty()); - assertTrue(isValidJSON(currentLog)); + + writer.flush(); + assertTrue(isValidJSON(writer.toString())); } - public static boolean isValidJSON(String jsonInString) { - try { - final ObjectMapper mapper = new ObjectMapper(); - mapper.readTree(jsonInString); - return true; - } catch (IOException e) { - return false; - } + @After + public void cleanup() { + ((org.apache.logging.log4j.core.Logger) logger).removeAppender(appender); } -} \ No newline at end of file + + private static boolean isValidJSON(String jsonInString) throws Exception { + JsonNode jsonNode = new ObjectMapper().readTree(jsonInString); + return jsonNode.get("message").asText().equals("Debug message"); + } + +} diff --git a/animal-sniffer-mvn-plugin/README.md b/maven-modules/animal-sniffer-mvn-plugin/README.md similarity index 100% rename from animal-sniffer-mvn-plugin/README.md rename to maven-modules/animal-sniffer-mvn-plugin/README.md diff --git a/animal-sniffer-mvn-plugin/pom.xml b/maven-modules/animal-sniffer-mvn-plugin/pom.xml similarity index 94% rename from animal-sniffer-mvn-plugin/pom.xml rename to maven-modules/animal-sniffer-mvn-plugin/pom.xml index 9e4f25c791..1756adc27d 100644 --- a/animal-sniffer-mvn-plugin/pom.xml +++ b/maven-modules/animal-sniffer-mvn-plugin/pom.xml @@ -11,8 +11,8 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + maven-modules + 0.0.1-SNAPSHOT diff --git a/animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java b/maven-modules/animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java similarity index 100% rename from animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java rename to maven-modules/animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java diff --git a/maven-archetype/src/main/resources/logback.xml b/maven-modules/animal-sniffer-mvn-plugin/src/main/resources/logback.xml similarity index 100% rename from maven-archetype/src/main/resources/logback.xml rename to maven-modules/animal-sniffer-mvn-plugin/src/main/resources/logback.xml diff --git a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java b/maven-modules/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java similarity index 100% rename from animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java rename to maven-modules/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java diff --git a/maven-modules/host-maven-repo-example/pom.xml b/maven-modules/host-maven-repo-example/pom.xml index bd58dddeda..20528853cd 100644 --- a/maven-modules/host-maven-repo-example/pom.xml +++ b/maven-modules/host-maven-repo-example/pom.xml @@ -6,11 +6,11 @@ com.baeldung.maven.plugin host-maven-repo-example 1.0-SNAPSHOT - https://github.com/sgrverma23/host-maven-repo-example.git + https://github.com/${repository-owner}/${repository-name}.git - https://github.com/sgrverma23/host-maven-repo-example.git - scm:git:git@github.com:sgrverma23/host-maven-repo-example.git - scm:git:git@github.com:sgrverma23/host-maven-repo-example.git + https://github.com/${repository-owner}/${repository-name}.git + scm:git:git@github.com:${repository-owner}/${repository-name}.git + scm:git:git@github.com:${repository-owner}/${repository-name}.git @@ -43,13 +43,13 @@ Maven artifacts for ${project.version} true ${project.build.directory} - refs/heads/main + refs/heads/${branch-name} **/* true - host-maven-repo-example - sgrverma23 + ${repository-name} + ${repository-owner} github @@ -89,7 +89,7 @@ PROJECT-REPO-URL - https://github.com/sgrverma23/host-maven-repo-example/main + https://github.com/${repository-owner}/${repository-name}/${branch-name} true always @@ -98,9 +98,13 @@ + + Put-repo-owner + Put-repository-name + Put-branch-name github 8 8 - \ No newline at end of file + diff --git a/maven-archetype/README.md b/maven-modules/maven-archetype/README.md similarity index 100% rename from maven-archetype/README.md rename to maven-modules/maven-archetype/README.md diff --git a/maven-archetype/pom.xml b/maven-modules/maven-archetype/pom.xml similarity index 100% rename from maven-archetype/pom.xml rename to maven-modules/maven-archetype/pom.xml diff --git a/maven-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/maven-modules/maven-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml similarity index 100% rename from maven-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml rename to maven-modules/maven-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml diff --git a/maven-archetype/src/main/resources/archetype-resources/pom.xml b/maven-modules/maven-archetype/src/main/resources/archetype-resources/pom.xml similarity index 100% rename from maven-archetype/src/main/resources/archetype-resources/pom.xml rename to maven-modules/maven-archetype/src/main/resources/archetype-resources/pom.xml diff --git a/maven-archetype/src/main/resources/archetype-resources/src/main/java/AppConfig.java b/maven-modules/maven-archetype/src/main/resources/archetype-resources/src/main/java/AppConfig.java similarity index 100% rename from maven-archetype/src/main/resources/archetype-resources/src/main/java/AppConfig.java rename to maven-modules/maven-archetype/src/main/resources/archetype-resources/src/main/java/AppConfig.java diff --git a/maven-archetype/src/main/resources/archetype-resources/src/main/java/PingResource.java b/maven-modules/maven-archetype/src/main/resources/archetype-resources/src/main/java/PingResource.java similarity index 100% rename from maven-archetype/src/main/resources/archetype-resources/src/main/java/PingResource.java rename to maven-modules/maven-archetype/src/main/resources/archetype-resources/src/main/java/PingResource.java diff --git a/maven-archetype/src/main/resources/archetype-resources/src/main/liberty/config/server.xml b/maven-modules/maven-archetype/src/main/resources/archetype-resources/src/main/liberty/config/server.xml similarity index 100% rename from maven-archetype/src/main/resources/archetype-resources/src/main/liberty/config/server.xml rename to maven-modules/maven-archetype/src/main/resources/archetype-resources/src/main/liberty/config/server.xml diff --git a/spring-boot-modules/spring-boot-1/src/main/resources/logback.xml b/maven-modules/maven-archetype/src/main/resources/logback.xml similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/resources/logback.xml rename to maven-modules/maven-archetype/src/main/resources/logback.xml diff --git a/maven-modules/maven-parent-pom-resolution/README.md b/maven-modules/maven-parent-pom-resolution/README.md index b315b2f626..ec4ef41149 100644 --- a/maven-modules/maven-parent-pom-resolution/README.md +++ b/maven-modules/maven-parent-pom-resolution/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Understanding Maven’s “relativePath” Tag for a Parent POM](https://www.baeldung.com/maven-relativepath) +- [How to Disable a Maven Plugin Defined in a Parent POM](https://www.baeldung.com/maven-disable-parent-pom-plugin) diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml new file mode 100644 index 0000000000..2dfa34568e --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/empty-phase/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + com.baeldung.maven-parent-pom-resolution + empty-phase + 1.0.0-SNAPSHOT + pom + + + com.baeldung.maven-parent-pom-resolution + disable-plugin-examples + 1.0.0-SNAPSHOT + + + + + + maven-enforcer-plugin + + + enforce-file-exists + + + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/phase-none/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/phase-none/pom.xml new file mode 100644 index 0000000000..8870f28fd2 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/phase-none/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + com.baeldung.maven-parent-pom-resolution + phase-none + 1.0.0-SNAPSHOT + pom + + + com.baeldung.maven-parent-pom-resolution + disable-plugin-examples + 1.0.0-SNAPSHOT + + + + + + maven-enforcer-plugin + + + enforce-file-exists + any-value-that-is-not-a-phase + + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/plugin-enabled/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/plugin-enabled/pom.xml new file mode 100644 index 0000000000..e3ff22aaf7 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/plugin-enabled/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + com.baeldung.maven-parent-pom-resolution + plugin-enabled + 1.0.0-SNAPSHOT + pom + + + com.baeldung.maven-parent-pom-resolution + disable-plugin-examples + 1.0.0-SNAPSHOT + + + \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/plugin-enabled/src/file-that-must-exist.txt b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/plugin-enabled/src/file-that-must-exist.txt new file mode 100644 index 0000000000..2a6fae012f --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/plugin-enabled/src/file-that-must-exist.txt @@ -0,0 +1 @@ +Example source file \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml new file mode 100644 index 0000000000..4d16a94838 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + com.baeldung.maven-parent-pom-resolution + disable-plugin-examples + 1.0.0-SNAPSHOT + pom + + + com.baeldung + maven-parent-pom-resolution + 1.0.0-SNAPSHOT + + + + plugin-enabled + skip-parameter + phase-none + empty-phase + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0 + + + enforce-file-exists + + enforce + + + + + + ${project.basedir}/src/file-that-must-exist.txt + + + + + + + + + + + + UTF-8 + + + \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/skip-parameter/pom.xml b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/skip-parameter/pom.xml new file mode 100644 index 0000000000..31415bec24 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/skip-parameter/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + com.baeldung.maven-parent-pom-resolution + skip-parameter + 1.0.0-SNAPSHOT + pom + + + com.baeldung.maven-parent-pom-resolution + disable-plugin-examples + 1.0.0-SNAPSHOT + + + + + + maven-enforcer-plugin + + true + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/src/file-that-must-exist.txt b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/src/file-that-must-exist.txt new file mode 100644 index 0000000000..2a6fae012f --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/disable-plugin-examples/src/file-that-must-exist.txt @@ -0,0 +1 @@ +Example source file \ No newline at end of file diff --git a/maven-modules/maven-parent-pom-resolution/pom.xml b/maven-modules/maven-parent-pom-resolution/pom.xml index e5340032b7..8506f1c5fa 100644 --- a/maven-modules/maven-parent-pom-resolution/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/pom.xml @@ -10,6 +10,7 @@ aggregator + disable-plugin-examples diff --git a/maven-polyglot/README.md b/maven-modules/maven-polyglot/README.md similarity index 100% rename from maven-polyglot/README.md rename to maven-modules/maven-polyglot/README.md diff --git a/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml b/maven-modules/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml similarity index 100% rename from maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml rename to maven-modules/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml diff --git a/maven-polyglot/maven-polyglot-json-app/pom.json b/maven-modules/maven-polyglot/maven-polyglot-json-app/pom.json similarity index 100% rename from maven-polyglot/maven-polyglot-json-app/pom.json rename to maven-modules/maven-polyglot/maven-polyglot-json-app/pom.json diff --git a/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java b/maven-modules/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java similarity index 100% rename from maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java rename to maven-modules/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java diff --git a/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json b/maven-modules/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json similarity index 100% rename from maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json rename to maven-modules/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json diff --git a/maven-polyglot/maven-polyglot-json-extension/pom.xml b/maven-modules/maven-polyglot/maven-polyglot-json-extension/pom.xml similarity index 94% rename from maven-polyglot/maven-polyglot-json-extension/pom.xml rename to maven-modules/maven-polyglot/maven-polyglot-json-extension/pom.xml index 13d0b2099b..ade8974e0e 100644 --- a/maven-polyglot/maven-polyglot-json-extension/pom.xml +++ b/maven-modules/maven-polyglot/maven-polyglot-json-extension/pom.xml @@ -10,8 +10,8 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + maven-modules + 0.0.1-SNAPSHOT ../.. diff --git a/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java b/maven-modules/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java similarity index 100% rename from maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java rename to maven-modules/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java diff --git a/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml b/maven-modules/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml similarity index 100% rename from maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml rename to maven-modules/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml diff --git a/maven-polyglot/maven-polyglot-yml-app/pom.yml b/maven-modules/maven-polyglot/maven-polyglot-yml-app/pom.yml similarity index 100% rename from maven-polyglot/maven-polyglot-yml-app/pom.yml rename to maven-modules/maven-polyglot/maven-polyglot-yml-app/pom.yml diff --git a/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java b/maven-modules/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java similarity index 100% rename from maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java rename to maven-modules/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java diff --git a/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json b/maven-modules/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json similarity index 100% rename from maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json rename to maven-modules/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json diff --git a/maven-polyglot/pom.xml b/maven-modules/maven-polyglot/pom.xml similarity index 88% rename from maven-polyglot/pom.xml rename to maven-modules/maven-polyglot/pom.xml index 496ce58bf2..7ff375b9ba 100644 --- a/maven-polyglot/pom.xml +++ b/maven-modules/maven-polyglot/pom.xml @@ -10,8 +10,8 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + maven-modules + 0.0.1-SNAPSHOT diff --git a/maven-modules/maven-simple/README.md b/maven-modules/maven-simple/README.md new file mode 100644 index 0000000000..01ae4387ad --- /dev/null +++ b/maven-modules/maven-simple/README.md @@ -0,0 +1,8 @@ +### Maven Articles that are also part of the e-book + +This module contains articles about Maven that are also part of an Ebook. + + +### NOTE: + +Since this is a module tied to an e-book, it should **not** be moved or used to store the code for any further article. diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml index 6553889c24..2e3a6eee7d 100644 --- a/maven-modules/maven-simple/parent-project/core/pom.xml +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -23,4 +23,5 @@ 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 bde903b1b5..2f28eff49f 100644 --- a/maven-modules/maven-simple/parent-project/pom.xml +++ b/maven-modules/maven-simple/parent-project/pom.xml @@ -33,4 +33,5 @@ 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 f6cee60cbf..ce964c222f 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -5,7 +5,6 @@ 4.0.0 webapp webapp - war @@ -30,4 +29,5 @@ 3.3.2 + \ No newline at end of file diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index 0d65e5f9f4..253f5d9fa0 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -15,6 +15,8 @@ + animal-sniffer-mvn-plugin + maven-archetype maven-copy-files maven-custom-plugin @@ -23,6 +25,7 @@ maven-integration-test maven-multi-source maven-plugins + maven-polyglot maven-properties maven-unused-dependencies diff --git a/muleesb/pom.xml b/muleesb/pom.xml index d78cebada2..a2204c15b7 100644 --- a/muleesb/pom.xml +++ b/muleesb/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 com.mycompany muleesb @@ -218,4 +219,4 @@ 2.2.1 - + \ No newline at end of file diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index b2d581c9c1..dfdfa77d36 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -24,7 +24,7 @@ - 5.3.16 + 5.3.20 5.6.0 1.5.10.RELEASE diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md index 6622f9733f..4bc7d8b663 100644 --- a/persistence-modules/core-java-persistence-2/README.md +++ b/persistence-modules/core-java-persistence-2/README.md @@ -7,3 +7,4 @@ - [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) +- [Converting a JDBC ResultSet to JSON in Java](https://www.baeldung.com/java-jdbc-convert-resultset-to-json) diff --git a/persistence-modules/core-java-persistence-2/example.csv b/persistence-modules/core-java-persistence-2/example.csv new file mode 100644 index 0000000000..d7715864d1 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/example.csv @@ -0,0 +1,4 @@ +Username,Id,First name,Last name +doe1,7173,John,Doe +smith3,3722,Dana,Smith +john22,5490,John,Wang \ No newline at end of file diff --git a/persistence-modules/core-java-persistence-2/pom.xml b/persistence-modules/core-java-persistence-2/pom.xml index 780c1fcfca..c7547e1c46 100644 --- a/persistence-modules/core-java-persistence-2/pom.xml +++ b/persistence-modules/core-java-persistence-2/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 com.baeldung.core-java-persistence-2 core-java-persistence-2 @@ -41,6 +39,20 @@ mssql-jdbc ${mssql.driver.version} + + + + org.jooq + jooq + 3.11.11 + + + + org.json + json + 20220320 + + diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultset2json/ResultSet2JSON.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultset2json/ResultSet2JSON.java new file mode 100755 index 0000000000..bbe3ccf9a0 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/resultset2json/ResultSet2JSON.java @@ -0,0 +1,137 @@ +package com.baeldung.resultset2json; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.jooq.Record; +import org.jooq.RecordMapper; +import org.jooq.impl.DSL; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONArray; + +public class ResultSet2JSON { + + public static void main(String... args) throws ClassNotFoundException, SQLException { + + ResultSet2JSON testClass = new ResultSet2JSON(); + testClass.convertWithoutJOOQ(); + } + + public void convertWithoutJOOQ() throws ClassNotFoundException, SQLException { + Class.forName("org.h2.Driver"); + Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc", "user", "password"); + + // Create a table + Statement stmt = dbConnection.createStatement(); + stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM words"); + + JSONArray result1 = resultSet2JdbcWithoutJOOQ(resultSet); + System.out.println(result1); + + resultSet.close(); + } + + public void convertUsingJOOQDefaultApproach() throws ClassNotFoundException, SQLException { + Class.forName("org.h2.Driver"); + Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc", "user", "password"); + // Create a table + Statement stmt = dbConnection.createStatement(); + stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM words"); + + JSONObject result1 = resultSet2JdbcUsingJOOQDefaultApproach(resultSet, dbConnection); + System.out.println(result1); + + resultSet.close(); + } + + public void convertUsingCustomisedJOOQ() throws ClassNotFoundException, SQLException { + Class.forName("org.h2.Driver"); + Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc", "user", "password"); + // Create a table + Statement stmt = dbConnection.createStatement(); + stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM words"); + + JSONArray result1 = resultSet2JdbcUsingCustomisedJOOQ(resultSet, dbConnection); + System.out.println(result1); + + resultSet.close(); + } + + public static JSONArray resultSet2JdbcWithoutJOOQ(ResultSet resultSet) throws SQLException { + ResultSetMetaData md = resultSet.getMetaData(); + int numCols = md.getColumnCount(); + List colNames = IntStream.range(0, numCols) + .mapToObj(i -> { + try { + return md.getColumnName(i + 1); + } catch (SQLException e) { + + e.printStackTrace(); + return "?"; + } + }) + .collect(Collectors.toList()); + + JSONArray result = new JSONArray(); + while (resultSet.next()) { + JSONObject row = new JSONObject(); + colNames.forEach(cn -> { + try { + row.put(cn, resultSet.getObject(cn)); + } catch (JSONException | SQLException e) { + + e.printStackTrace(); + } + }); + result.put(row); + } + return result; + } + + public static JSONObject resultSet2JdbcUsingJOOQDefaultApproach(ResultSet resultSet, Connection dbConnection) throws SQLException { + JSONObject result = new JSONObject(DSL.using(dbConnection) + .fetch(resultSet) + .formatJSON()); + return result; + } + + public static JSONArray resultSet2JdbcUsingCustomisedJOOQ(ResultSet resultSet, Connection dbConnection) throws SQLException { + ResultSetMetaData md = resultSet.getMetaData(); + int numCols = md.getColumnCount(); + List colNames = IntStream.range(0, numCols) + .mapToObj(i -> { + try { + return md.getColumnName(i + 1); + } catch (SQLException e) { + + e.printStackTrace(); + return "?"; + } + }) + .collect(Collectors.toList()); + + List json = DSL.using(dbConnection) + .fetch(resultSet) + .map(new RecordMapper() { + + @Override + public JSONObject map(Record r) { + JSONObject obj = new JSONObject(); + colNames.forEach(cn -> obj.put(cn, r.get(cn))); + return obj; + } + }); + return new JSONArray(json); + } +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultset2json/ResultSet2JSONUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultset2json/ResultSet2JSONUnitTest.java new file mode 100644 index 0000000000..f3dd8350fa --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/resultset2json/ResultSet2JSONUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.resultset2json; + +import static com.baeldung.resultset2json.ResultSet2JSON.resultSet2JdbcWithoutJOOQ; +import static com.baeldung.resultset2json.ResultSet2JSON.resultSet2JdbcUsingJOOQDefaultApproach; +import static com.baeldung.resultset2json.ResultSet2JSON.resultSet2JdbcUsingCustomisedJOOQ; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class ResultSet2JSONUnitTest { + JSONObject object = new JSONObject( + "{\"records\":[[\"doe1\",\"7173\",\"John\",\"Doe\"],[\"smith3\",\"3722\",\"Dana\",\"Smith\"],[\"john22\",\"5490\",\"John\",\"Wang\"]],\"fields\":[{\"schema\":\"PUBLIC\",\"name\":\"USERNAME\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"},{\"schema\":\"PUBLIC\",\"name\":\"ID\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"},{\"schema\":\"PUBLIC\",\"name\":\"First name\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"},{\"schema\":\"PUBLIC\",\"name\":\"Last name\",\"type\":\"VARCHAR\",\"table\":\"WORDS\"}]}"); + + JSONArray array = new JSONArray( + "[{\"USERNAME\":\"doe1\",\"First name\":\"John\",\"ID\":\"7173\",\"Last name\":\"Doe\"},{\"USERNAME\":\"smith3\",\"First name\":\"Dana\",\"ID\":\"3722\",\"Last name\":\"Smith\"},{\"USERNAME\":\"john22\",\"First name\":\"John\",\"ID\":\"5490\",\"Last name\":\"Wang\"}]"); + + @Test + void whenResultSetConvertedWithoutJOOQ_shouldMatchJSON() throws SQLException, ClassNotFoundException { + Class.forName("org.h2.Driver"); + Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc1", "user", "password"); + + // Create a table + Statement stmt = dbConnection.createStatement(); + stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM words"); + + JSONArray result1 = resultSet2JdbcWithoutJOOQ(resultSet); + + resultSet.close(); + + assertTrue(array.similar(result1)); + } + + @Test + void whenResultSetConvertedUsingJOOQDefaultApproach_shouldMatchJSON() throws SQLException, ClassNotFoundException { + Class.forName("org.h2.Driver"); + Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc2", "user", "password"); + // Create a table + Statement stmt = dbConnection.createStatement(); + stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM words"); + + JSONObject result2 = resultSet2JdbcUsingJOOQDefaultApproach(resultSet, dbConnection); + + resultSet.close(); + + assertTrue(object.similar(result2)); + } + + @Test + void whenResultSetConvertedUsingCustomisedJOOQ_shouldMatchJSON() throws SQLException, ClassNotFoundException { + Class.forName("org.h2.Driver"); + Connection dbConnection = DriverManager.getConnection("jdbc:h2:mem:rs2jdbc3", "user", "password"); + // Create a table + Statement stmt = dbConnection.createStatement(); + stmt.execute("CREATE TABLE words AS SELECT * FROM CSVREAD('./example.csv')"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM words"); + + JSONArray result3 = resultSet2JdbcUsingCustomisedJOOQ(resultSet, dbConnection); + + resultSet.close(); + + assertTrue(array.similar(result3)); + } + +} diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/MetadataExtractor.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/MetadataExtractor.java index 27c615aebc..e9618836e9 100644 --- a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/MetadataExtractor.java +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbcmetadata/MetadataExtractor.java @@ -14,65 +14,66 @@ public class MetadataExtractor { } public void extractTableInfo() throws SQLException { - ResultSet resultSet = databaseMetaData.getTables(null, null, "CUST%", new String[] { "TABLE" }); - while (resultSet.next()) { - // Print the names of existing tables - System.out.println(resultSet.getString("TABLE_NAME")); - System.out.println(resultSet.getString("REMARKS")); + try (ResultSet resultSet = databaseMetaData.getTables(null, null, "CUST%", new String[] { "TABLE" })) { + while (resultSet.next()) { + // Print the names of existing tables + System.out.println(resultSet.getString("TABLE_NAME")); + System.out.println(resultSet.getString("REMARKS")); + } } } public void extractSystemTables() throws SQLException { - ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[] { "SYSTEM TABLE" }); - while (resultSet.next()) { - // Print the names of system tables - System.out.println(resultSet.getString("TABLE_NAME")); + try (ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[] { "SYSTEM TABLE" })) { + while (resultSet.next()) { + // Print the names of system tables + System.out.println(resultSet.getString("TABLE_NAME")); + } } } public void extractViews() throws SQLException { - ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[] { "VIEW" }); - while (resultSet.next()) { - // Print the names of existing views - System.out.println(resultSet.getString("TABLE_NAME")); - } + try(ResultSet resultSet = databaseMetaData.getTables(null, null, null, new String[] { "VIEW" })) { + while (resultSet.next()) { + // Print the names of existing views + System.out.println(resultSet.getString("TABLE_NAME")); + } + } } public void extractColumnInfo(String tableName) throws SQLException { - ResultSet columns = databaseMetaData.getColumns(null, null, tableName, null); - - while (columns.next()) { - String columnName = columns.getString("COLUMN_NAME"); - String columnSize = columns.getString("COLUMN_SIZE"); - String datatype = columns.getString("DATA_TYPE"); - String isNullable = columns.getString("IS_NULLABLE"); - String isAutoIncrement = columns.getString("IS_AUTOINCREMENT"); - System.out.println(String.format("ColumnName: %s, columnSize: %s, datatype: %s, isColumnNullable: %s, isAutoIncrementEnabled: %s", columnName, columnSize, datatype, isNullable, isAutoIncrement)); - } + try(ResultSet columns = databaseMetaData.getColumns(null, null, tableName, null)) { + while (columns.next()) { + String columnName = columns.getString("COLUMN_NAME"); + String columnSize = columns.getString("COLUMN_SIZE"); + String datatype = columns.getString("DATA_TYPE"); + String isNullable = columns.getString("IS_NULLABLE"); + String isAutoIncrement = columns.getString("IS_AUTOINCREMENT"); + System.out.println(String.format("ColumnName: %s, columnSize: %s, datatype: %s, isColumnNullable: %s, isAutoIncrementEnabled: %s", columnName, columnSize, datatype, isNullable, isAutoIncrement)); + } + } } public void extractPrimaryKeys(String tableName) throws SQLException { - ResultSet primaryKeys = databaseMetaData.getPrimaryKeys(null, null, tableName); - while (primaryKeys.next()) { - String primaryKeyColumnName = primaryKeys.getString("COLUMN_NAME"); - String primaryKeyName = primaryKeys.getString("PK_NAME"); - System.out.println(String.format("columnName:%s, pkName:%s", primaryKeyColumnName, primaryKeyName)); - } - } - - public void fun() throws SQLException { - + try(ResultSet primaryKeys = databaseMetaData.getPrimaryKeys(null, null, tableName)) { + while (primaryKeys.next()) { + String primaryKeyColumnName = primaryKeys.getString("COLUMN_NAME"); + String primaryKeyName = primaryKeys.getString("PK_NAME"); + System.out.println(String.format("columnName:%s, pkName:%s", primaryKeyColumnName, primaryKeyName)); + } + } } public void extractForeignKeys(String tableName) throws SQLException { - ResultSet foreignKeys = databaseMetaData.getImportedKeys(null, null, tableName); - while (foreignKeys.next()) { - String pkTableName = foreignKeys.getString("PKTABLE_NAME"); - String fkTableName = foreignKeys.getString("FKTABLE_NAME"); - String pkColumnName = foreignKeys.getString("PKCOLUMN_NAME"); - String fkColumnName = foreignKeys.getString("FKCOLUMN_NAME"); - System.out.println(String.format("pkTableName:%s, fkTableName:%s, pkColumnName:%s, fkColumnName:%s", pkTableName, fkTableName, pkColumnName, fkColumnName)); - } + try(ResultSet foreignKeys = databaseMetaData.getImportedKeys(null, null, tableName)) { + while (foreignKeys.next()) { + String pkTableName = foreignKeys.getString("PKTABLE_NAME"); + String fkTableName = foreignKeys.getString("FKTABLE_NAME"); + String pkColumnName = foreignKeys.getString("PKCOLUMN_NAME"); + String fkColumnName = foreignKeys.getString("FKCOLUMN_NAME"); + System.out.println(String.format("pkTableName:%s, fkTableName:%s, pkColumnName:%s, fkColumnName:%s", pkTableName, fkTableName, pkColumnName, fkColumnName)); + } + } } public void extractDatabaseInfo() throws SQLException { @@ -89,11 +90,12 @@ public class MetadataExtractor { public void extractUserName() throws SQLException { String userName = databaseMetaData.getUserName(); System.out.println(userName); - ResultSet schemas = databaseMetaData.getSchemas(); - while (schemas.next()) { - String table_schem = schemas.getString("TABLE_SCHEM"); - String table_catalog = schemas.getString("TABLE_CATALOG"); - System.out.println(String.format("Table_schema:%s, Table_catalog:%s", table_schem, table_catalog)); + try(ResultSet schemas = databaseMetaData.getSchemas()) { + while (schemas.next()) { + String table_schem = schemas.getString("TABLE_SCHEM"); + String table_catalog = schemas.getString("TABLE_CATALOG"); + System.out.println(String.format("Table_schema:%s, Table_catalog:%s", table_schem, table_catalog)); + } } } diff --git a/persistence-modules/deltaspike/pom.xml b/persistence-modules/deltaspike/pom.xml index f151255948..0142e746a1 100644 --- a/persistence-modules/deltaspike/pom.xml +++ b/persistence-modules/deltaspike/pom.xml @@ -278,13 +278,6 @@ - - - redhat-repository-techpreview - https://maven.repository.redhat.com/techpreview/all/ - - - 3.7.4 1.8.2 @@ -296,7 +289,7 @@ 2.6 1.1.3 - 1.2.5.Final-redhat-1 + 1.2.4.Final \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml index ed158216fb..e984078f9a 100644 --- a/persistence-modules/hibernate-annotations/pom.xml +++ b/persistence-modules/hibernate-annotations/pom.xml @@ -16,7 +16,7 @@ - + org.springframework spring-context @@ -32,7 +32,7 @@ hibernate-core ${hibernate-core.version} - + org.hsqldb hsqldb ${hsqldb.version} @@ -82,10 +82,10 @@ 5.0.2.RELEASE 1.10.6.RELEASE - 5.4.7.Final + 5.6.7.Final true 2.1.7.RELEASE - 1.4.200 + 2.1.212 9.0.0.M26 2.3.4 diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/HibernateUtil.java index afe2aeac89..65d9f249fa 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -1,10 +1,5 @@ package com.baeldung.hibernate; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URL; -import java.util.Properties; - import org.apache.commons.lang3.StringUtils; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; @@ -12,62 +7,58 @@ import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; -import com.baeldung.hibernate.joincolumn.Email; -import com.baeldung.hibernate.joincolumn.Office; -import com.baeldung.hibernate.joincolumn.OfficeAddress; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.List; +import java.util.Properties; + +import static java.util.Objects.requireNonNull; public class HibernateUtil { - private static String PROPERTY_FILE_NAME; - public static SessionFactory getSessionFactory() throws IOException { - return getSessionFactory(null); + public static SessionFactory getSessionFactory(String propertyFileName, List> classes) throws IOException { + ServiceRegistry serviceRegistry = configureServiceRegistry(propertyFileName); + return makeSessionFactory(serviceRegistry, classes); } - public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { - PROPERTY_FILE_NAME = propertyFileName; - ServiceRegistry serviceRegistry = configureServiceRegistry(); - return makeSessionFactory(serviceRegistry); - } - - public static SessionFactory getSessionFactoryByProperties(Properties properties) throws IOException { - ServiceRegistry serviceRegistry = configureServiceRegistry(properties); - return makeSessionFactory(serviceRegistry); - } - - private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { + private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry, List> classes) { MetadataSources metadataSources = new MetadataSources(serviceRegistry); + for (Class clazz: classes) { + metadataSources = metadataSources.addAnnotatedClass(clazz); + } - metadataSources.addPackage("com.baeldung.hibernate.pojo"); - metadataSources.addAnnotatedClass(com.baeldung.hibernate.joincolumn.OfficialEmployee.class); - metadataSources.addAnnotatedClass(Email.class); - metadataSources.addAnnotatedClass(Office.class); - metadataSources.addAnnotatedClass(OfficeAddress.class); - - Metadata metadata = metadataSources.getMetadataBuilder() - .build(); - - return metadata.getSessionFactoryBuilder() - .build(); + Metadata metadata = metadataSources + .getMetadataBuilder() + .build(); + return metadata.getSessionFactoryBuilder().build(); } - private static ServiceRegistry configureServiceRegistry() throws IOException { - return configureServiceRegistry(getProperties()); + private static ServiceRegistry configureServiceRegistry(String propertyFileName) throws IOException { + return configureServiceRegistry(getProperties(propertyFileName)); } - private static ServiceRegistry configureServiceRegistry(Properties properties) throws IOException { + private static ServiceRegistry configureServiceRegistry(Properties properties) { return new StandardServiceRegistryBuilder().applySettings(properties) .build(); } - public static Properties getProperties() throws IOException { + public static Properties getProperties(String propertyFileName) throws IOException { Properties properties = new Properties(); - URL propertiesURL = Thread.currentThread() - .getContextClassLoader() - .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties")); - try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + + String file = getResourceURL(propertyFileName).getFile(); + + try (FileInputStream inputStream = new FileInputStream(file)) { properties.load(inputStream); } + return properties; } + + private static URL getResourceURL(String propertyFileName) { + return requireNonNull(Thread.currentThread() + .getContextClassLoader() + .getResource(StringUtils.defaultString(propertyFileName, "hibernate.properties"))); + } } \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/OfficeEmployee.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/OfficeEmployee.java index 3ca06e4316..1ffeb0b99d 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/OfficeEmployee.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/OfficeEmployee.java @@ -1,6 +1,5 @@ package com.baeldung.hibernate.customtypes; -import com.baeldung.hibernate.pojo.Phone; import org.hibernate.annotations.Columns; import org.hibernate.annotations.Parameter; import org.hibernate.annotations.Type; diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java index 46e6824f42..ef82c1c9ad 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java @@ -1,34 +1,57 @@ package com.baeldung.hibernate.oneToMany.config; +import com.baeldung.hibernate.oneToMany.model.Cart; +import com.baeldung.hibernate.oneToMany.model.CartOIO; +import com.baeldung.hibernate.oneToMany.model.Item; +import com.baeldung.hibernate.oneToMany.model.ItemOIO; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Environment; import org.hibernate.service.ServiceRegistry; +import java.util.HashMap; +import java.util.Map; + public class HibernateAnnotationUtil { - private static SessionFactory sessionFactory; + private static final SessionFactory SESSION_FACTORY = buildSessionFactory(); - private static SessionFactory buildSessionFactory() { - try { - // Create the SessionFactory from hibernate-annotation.cfg.xml - ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure("hibernate-annotation.cfg.xml").build(); - Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build(); - SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build(); - - return sessionFactory; - - } catch (Throwable ex) { - System.err.println("Initial SessionFactory creation failed." + ex); - ex.printStackTrace(); - throw new ExceptionInInitializerError(ex); - } + /** + * Utility class + */ + private HibernateAnnotationUtil() { } public static SessionFactory getSessionFactory() { - if (sessionFactory == null) - sessionFactory = buildSessionFactory(); - return sessionFactory; + return SESSION_FACTORY; + } + + private static SessionFactory buildSessionFactory() { + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(dbSettings()) + .build(); + + Metadata metadata = new MetadataSources(serviceRegistry) + .addAnnotatedClass(Cart.class) + .addAnnotatedClass(CartOIO.class) + .addAnnotatedClass(Item.class) + .addAnnotatedClass(ItemOIO.class) + .buildMetadata(); + + return metadata.buildSessionFactory(); + } + + private static Map dbSettings() { + Map dbSettings = new HashMap<>(); + dbSettings.put(Environment.URL, "jdbc:h2:mem:spring_hibernate_one_to_many"); + dbSettings.put(Environment.USER, "sa"); + dbSettings.put(Environment.PASS, ""); + dbSettings.put(Environment.DRIVER, "org.h2.Driver"); + dbSettings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + dbSettings.put(Environment.SHOW_SQL, "true"); + dbSettings.put(Environment.HBM2DDL_AUTO, "create"); + return dbSettings; } } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyIsOwningSide.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyIsOwningSide.java new file mode 100644 index 0000000000..f74aecbb92 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyIsOwningSide.java @@ -0,0 +1,71 @@ +package com.baeldung.hibernate.oneToMany.main; + +import java.util.HashSet; +import java.util.Set; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil; +import com.baeldung.hibernate.oneToMany.model.Cart; +import com.baeldung.hibernate.oneToMany.model.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HibernateManyIsOwningSide { + + private static final Logger LOGGER = LoggerFactory.getLogger(HibernateManyIsOwningSide.class); + + public static void main(String[] args) { + + Cart cart = new Cart(); + Cart cart2 = new Cart(); + + Item item1 = new Item(cart); + Item item2 = new Item(cart2); + + Set itemsSet = new HashSet<>(); + itemsSet.add(item1); + itemsSet.add(item2); + cart.setItems(itemsSet); + + // Get Session + SessionFactory sessionFactory = HibernateAnnotationUtil.getSessionFactory(); + Session session = sessionFactory.getCurrentSession(); + + try { + LOGGER.info("Session created"); + + // start transaction + Transaction tx = session.beginTransaction(); + + // Save the Model object + session.save(cart); + session.save(cart2); + session.save(item1); + session.save(item2); + + // Commit transaction + tx.commit(); + + session = sessionFactory.getCurrentSession(); + tx = session.beginTransaction(); + + item1 = session.get(Item.class, 1L); + item2 = session.get(Item.class, 2L); + tx.commit(); + + LOGGER.info("item1 ID={}, Foreign Key CartOIO ID={}", item1.getId(), item1.getCart().getId()); + LOGGER.info("item2 ID={}, Foreign Key CartOIO ID={}", item2.getId(), item2.getCart().getId()); + + } catch (Exception e) { + LOGGER.error("Exception occurred", e); + } finally { + if (!sessionFactory.isClosed()) { + LOGGER.info("Closing SessionFactory"); + sessionFactory.close(); + } + } + } +} diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java deleted file mode 100644 index 372fb2fc07..0000000000 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateManyisOwningSide.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.baeldung.hibernate.oneToMany.main; - -import java.util.HashSet; -import java.util.Set; - -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; - -import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil; -import com.baeldung.hibernate.oneToMany.model.Cart; -import com.baeldung.hibernate.oneToMany.model.Items; -import com.baeldung.hibernate.oneToMany.model.ItemsOIO; - -public class HibernateManyisOwningSide { - public static void main(String[] args) { - - Cart cart = new Cart(); - Cart cart2 = new Cart(); - - Items item1 = new Items(cart); - Items item2 = new Items(cart2); - Set itemsSet = new HashSet(); - itemsSet.add(item1); - itemsSet.add(item2); - - cart.setItems(itemsSet); - - - - SessionFactory sessionFactory = null; - Session session = null; - Transaction tx = null; - try { - // Get Session - sessionFactory = HibernateAnnotationUtil.getSessionFactory(); - session = sessionFactory.getCurrentSession(); - System.out.println("Session created"); - // start transaction - tx = session.beginTransaction(); - // Save the Model object - session.save(cart); - session.save(cart2); - session.save(item1); - session.save(item2); - // Commit transaction - tx.commit(); - session = sessionFactory.getCurrentSession(); - tx = session.beginTransaction(); - - item1 = (Items) session.get(Items.class, new Long(1)); - item2 = (Items) session.get(Items.class, new Long(2)); - tx.commit(); - - - System.out.println("item1 ID=" + item1.getId() + ", Foreign Key CartOIO ID=" + item1.getCart() - .getId()); - System.out.println("item2 ID=" + item2.getId() + ", Foreign Key CartOIO ID=" + item2.getCart() - .getId()); - - } catch (Exception e) { - System.out.println("Exception occured. " + e.getMessage()); - e.printStackTrace(); - } finally { - if (!sessionFactory.isClosed()) { - System.out.println("Closing SessionFactory"); - sessionFactory.close(); - } - } - } -} diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneIsOwningSide.java similarity index 50% rename from persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java rename to persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneIsOwningSide.java index 0777664dd0..086e015ad1 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneisOwningSide.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneIsOwningSide.java @@ -9,57 +9,59 @@ import org.hibernate.Transaction; import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil; import com.baeldung.hibernate.oneToMany.model.CartOIO; -import com.baeldung.hibernate.oneToMany.model.ItemsOIO; +import com.baeldung.hibernate.oneToMany.model.ItemOIO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HibernateOneIsOwningSide { + + private static final Logger LOGGER = LoggerFactory.getLogger(HibernateOneIsOwningSide.class); -public class HibernateOneisOwningSide { public static void main(String[] args) { CartOIO cart = new CartOIO(); CartOIO cart2 = new CartOIO(); - ItemsOIO item1 = new ItemsOIO(cart); - ItemsOIO item2 = new ItemsOIO(cart2); - Set itemsSet = new HashSet(); + ItemOIO item1 = new ItemOIO(cart); + ItemOIO item2 = new ItemOIO(cart2); + Set itemsSet = new HashSet<>(); itemsSet.add(item1); itemsSet.add(item2); cart.setItems(itemsSet); - SessionFactory sessionFactory = null; - Session session = null; - Transaction tx = null; + SessionFactory sessionFactory = HibernateAnnotationUtil.getSessionFactory(); + Session session = sessionFactory.getCurrentSession(); + LOGGER.info("Session created"); + + Transaction tx; try { - // Get Session - sessionFactory = HibernateAnnotationUtil.getSessionFactory(); - session = sessionFactory.getCurrentSession(); - System.out.println("Session created"); // start transaction tx = session.beginTransaction(); + // Save the Model object session.save(cart); session.save(cart2); session.save(item1); session.save(item2); + // Commit transaction tx.commit(); session = sessionFactory.getCurrentSession(); tx = session.beginTransaction(); - item1 = (ItemsOIO) session.get(ItemsOIO.class, new Long(1)); - item2 = (ItemsOIO) session.get(ItemsOIO.class, new Long(2)); + item1 = session.get(ItemOIO.class, 1L); + item2 = session.get(ItemOIO.class, 2L); tx.commit(); - System.out.println("item1 ID=" + item1.getId() + ", Foreign Key CartOIO ID=" + item1.getCartOIO() - .getId()); - System.out.println("item2 ID=" + item2.getId() + ", Foreign Key CartOIO ID=" + item2.getCartOIO() - .getId()); + LOGGER.info("item1 ID={}, Foreign Key CartOIO ID={}", item1.getId(), item1.getCartOIO().getId()); + LOGGER.info("item2 ID={}, Foreign Key CartOIO ID={}", item2.getId(), item2.getCartOIO().getId()); } catch (Exception e) { - System.out.println("Exception occured. " + e.getMessage()); - e.printStackTrace(); + LOGGER.error("Exception occurred", e); } finally { if (!sessionFactory.isClosed()) { - System.out.println("Closing SessionFactory"); + LOGGER.info("Closing SessionFactory"); sessionFactory.close(); } } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java index 2bc5e514f7..99df67b4a8 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java @@ -9,52 +9,53 @@ import org.hibernate.Transaction; import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil; import com.baeldung.hibernate.oneToMany.model.Cart; -import com.baeldung.hibernate.oneToMany.model.Items; +import com.baeldung.hibernate.oneToMany.model.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HibernateOneToManyAnnotationMain { + private static final Logger LOGGER = LoggerFactory.getLogger(HibernateOneToManyAnnotationMain.class); + public static void main(String[] args) { Cart cart = new Cart(); - Items item1 = new Items(cart); - Items item2 = new Items(cart); - Set itemsSet = new HashSet(); + Item item1 = new Item(cart); + Item item2 = new Item(cart); + Set itemsSet = new HashSet<>(); itemsSet.add(item1); itemsSet.add(item2); cart.setItems(itemsSet); - - SessionFactory sessionFactory = null; - Session session = null; - Transaction tx = null; + SessionFactory sessionFactory = HibernateAnnotationUtil.getSessionFactory(); + Session session = sessionFactory.getCurrentSession(); + LOGGER.info("Session created"); + try { - // Get Session - sessionFactory = HibernateAnnotationUtil.getSessionFactory(); - session = sessionFactory.getCurrentSession(); - System.out.println("Session created"); // start transaction - tx = session.beginTransaction(); + Transaction tx = session.beginTransaction(); + // Save the Model object session.save(cart); session.save(item1); session.save(item2); + // Commit transaction tx.commit(); - System.out.println("Cart ID=" + cart.getId()); - System.out.println("item1 ID=" + item1.getId() + ", Foreign Key Cart ID=" + item1.getCart().getId()); - System.out.println("item2 ID=" + item2.getId() + ", Foreign Key Cart ID=" + item1.getCart().getId()); + + LOGGER.info("Cart ID={}", cart.getId()); + LOGGER.info("item1 ID={}, Foreign Key Cart ID={}", item1.getId(), item1.getCart().getId()); + LOGGER.info("item2 ID={}, Foreign Key Cart ID={}", item2.getId(), item2.getCart().getId()); } catch (Exception e) { - System.out.println("Exception occured. " + e.getMessage()); - e.printStackTrace(); + LOGGER.error("Exception occurred", e); } finally { if (!sessionFactory.isClosed()) { - System.out.println("Closing SessionFactory"); + LOGGER.info("Closing SessionFactory"); sessionFactory.close(); } } } - } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java index b8b991831e..53878af445 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java @@ -19,9 +19,8 @@ public class Cart { @Column(name = "cart_id") private long id; - @OneToMany(mappedBy = "cart") - private Set items; + private Set items; public long getId() { return id; @@ -31,12 +30,11 @@ public class Cart { this.id = id; } - - public Set getItems() { + public Set getItems() { return items; } - public void setItems(Set items) { + public void setItems(Set items) { this.items = items; } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java index 8a5ed5e7a4..27b28a6753 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/CartOIO.java @@ -9,8 +9,6 @@ import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; - - @Entity @Table(name = "CARTOIO") public class CartOIO { @@ -21,7 +19,7 @@ public class CartOIO { @OneToMany @JoinColumn(name = "cart_id") // we need to duplicate the physical information - private Set items; + private Set items; public long getId() { return id; @@ -31,11 +29,11 @@ public class CartOIO { this.id = id; } - public Set getItems() { + public Set getItems() { return items; } - public void setItems(Set items) { + public void setItems(Set items) { this.items = items; } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java similarity index 92% rename from persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java rename to persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java index f63a4855b5..a055682d0d 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/Item.java @@ -11,23 +11,22 @@ import javax.persistence.Table; @Entity @Table(name = "ITEMS") -public class Items { +public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private long id; - @ManyToOne @JoinColumn(name = "cart_id", nullable = false) private Cart cart; // Hibernate requires no-args constructor - public Items() { + public Item() { } - public Items(Cart c) { + public Item(Cart c) { this.cart = c; } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java similarity index 91% rename from persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java rename to persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java index a3d6a796c5..baaf57b106 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemsOIO.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/model/ItemOIO.java @@ -10,7 +10,7 @@ import javax.persistence.Table; @Entity @Table(name = "ITEMSOIO") -public class ItemsOIO { +public class ItemOIO { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -21,10 +21,10 @@ public class ItemsOIO { private CartOIO cart; // Hibernate requires no-args constructor - public ItemsOIO() { + public ItemOIO() { } - public ItemsOIO(CartOIO c) { + public ItemOIO(CartOIO c) { this.cart = c; } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java index 7fc077eeb2..3029aae640 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/wherejointable/User.java @@ -12,7 +12,7 @@ import javax.persistence.ManyToMany; import org.hibernate.annotations.WhereJoinTable; -@Entity +@Entity(name = "users") public class User { @Id diff --git a/persistence-modules/hibernate-annotations/src/main/resources/log4j.xml b/persistence-modules/hibernate-annotations/src/main/resources/log4j.xml new file mode 100644 index 0000000000..bc2c24ea93 --- /dev/null +++ b/persistence-modules/hibernate-annotations/src/main/resources/log4j.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesManualTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java similarity index 52% rename from persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesManualTest.java rename to persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java index 63dc6330be..460b65ee12 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesManualTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java @@ -1,20 +1,27 @@ package com.baeldung.hibernate.customtypes; -import com.baeldung.hibernate.HibernateUtil; import org.hibernate.SessionFactory; -import org.hibernate.query.Query; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Environment; +import org.hibernate.service.ServiceRegistry; import org.junit.Assert; import org.junit.Test; -import java.io.IOException; +import javax.persistence.TypedQuery; import java.time.LocalDate; +import java.util.HashMap; +import java.util.Map; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -public class HibernateCustomTypesManualTest { +public class HibernateCustomTypesIntegrationTest { @Test - public void givenEmployee_whenSavedWithCustomTypes_thenEntityIsSaved() throws IOException { + public void givenEmployee_whenSavedWithCustomTypes_thenEntityIsSaved() { final OfficeEmployee e = new OfficeEmployee(); e.setDateOfJoining(LocalDate.now()); @@ -39,13 +46,13 @@ public class HibernateCustomTypesManualTest { doInHibernate(this::sessionFactory, session -> { session.save(e); boolean contains = session.contains(e); - Assert.assertTrue(contains); + assertTrue(contains); }); } @Test - public void givenEmployee_whenCustomTypeInQuery_thenReturnEntity() throws IOException { + public void givenEmployee_whenCustomTypeInQuery_thenReturnEntity() { final OfficeEmployee e = new OfficeEmployee(); e.setDateOfJoining(LocalDate.now()); @@ -69,22 +76,39 @@ public class HibernateCustomTypesManualTest { doInHibernate(this::sessionFactory, session -> { session.save(e); - Query query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipcode = :pinCode"); + TypedQuery query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipcode = :pinCode", OfficeEmployee.class); query.setParameter("pinCode",100); - int size = query.list().size(); + int size = query.getResultList().size(); - Assert.assertEquals(1, size); + assertEquals(1, size); }); } private SessionFactory sessionFactory() { - try { - return HibernateUtil.getSessionFactory("hibernate-customtypes.properties"); - } catch (IOException e) { - e.printStackTrace(); - } + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(getProperties()) + .build(); - return null; + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + Metadata metadata = metadataSources + .addAnnotatedClass(OfficeEmployee.class) + .getMetadataBuilder() + .applyBasicType(LocalDateStringType.INSTANCE) + .build(); + + return metadata.buildSessionFactory(); + } + + private static Map getProperties() { + Map dbSettings = new HashMap<>(); + dbSettings.put(Environment.URL, "jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1"); + dbSettings.put(Environment.USER, "sa"); + dbSettings.put(Environment.PASS, ""); + dbSettings.put(Environment.DRIVER, "org.h2.Driver"); + dbSettings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + dbSettings.put(Environment.SHOW_SQL, "true"); + dbSettings.put(Environment.HBM2DDL_AUTO, "create"); + return dbSettings; } } diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java index 0998ff1d90..37125e8b15 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java @@ -1,14 +1,21 @@ package com.baeldung.hibernate.joincolumn; -import com.baeldung.hibernate.HibernateUtil; -import java.io.IOException; +import com.baeldung.hibernate.customtypes.LocalDateStringType; import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; - +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.service.ServiceRegistry; import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; public class JoinColumnIntegrationTest { @@ -16,9 +23,8 @@ public class JoinColumnIntegrationTest { private Transaction transaction; @Before - public void setUp() throws IOException { - session = HibernateUtil.getSessionFactory("hibernate-spatial.properties") - .openSession(); + public void setUp() { + session = sessionFactory().openSession(); transaction = session.beginTransaction(); } @@ -54,4 +60,34 @@ public class JoinColumnIntegrationTest { session.clear(); } -} \ No newline at end of file + private SessionFactory sessionFactory() { + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(getProperties()) + .build(); + + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + Metadata metadata = metadataSources + .addAnnotatedClass(Email.class) + .addAnnotatedClass(Office.class) + .addAnnotatedClass(OfficeAddress.class) + .addAnnotatedClass(OfficialEmployee.class) + .getMetadataBuilder() + .applyBasicType(LocalDateStringType.INSTANCE) + .build(); + + return metadata.buildSessionFactory(); + } + + private static Map getProperties() { + Map dbSettings = new HashMap<>(); + dbSettings.put(Environment.URL, "jdbc:h2:mem:mydbJoinColumn;DB_CLOSE_DELAY=-1"); + dbSettings.put(Environment.USER, "sa"); + dbSettings.put(Environment.PASS, ""); + dbSettings.put(Environment.DRIVER, "org.h2.Driver"); + dbSettings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + dbSettings.put(Environment.SHOW_SQL, "true"); + dbSettings.put(Environment.HBM2DDL_AUTO, "create"); + return dbSettings; + } + +} diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java index 3bc5a6e12a..cb11df4212 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainIntegrationTest.java @@ -1,26 +1,21 @@ package com.baeldung.hibernate.oneToMany.main; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import java.util.HashSet; -import java.util.Set; - +import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil; +import com.baeldung.hibernate.oneToMany.model.Cart; +import com.baeldung.hibernate.oneToMany.model.Item; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; -import org.hibernate.dialect.H2Dialect; -import org.hibernate.service.ServiceRegistry; import org.junit.After; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import com.baeldung.hibernate.oneToMany.model.Cart; -import com.baeldung.hibernate.oneToMany.model.Items; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; public class HibernateOneToManyAnnotationMainIntegrationTest { @@ -28,20 +23,9 @@ public class HibernateOneToManyAnnotationMainIntegrationTest { private Session session; - public HibernateOneToManyAnnotationMainIntegrationTest() { - } - @BeforeClass public static void beforeTests() { - Configuration configuration = new Configuration().addAnnotatedClass(Cart.class).addAnnotatedClass(Items.class) - .setProperty("hibernate.dialect", H2Dialect.class.getName()) - .setProperty("hibernate.connection.driver_class", org.h2.Driver.class.getName()) - .setProperty("hibernate.connection.url", "jdbc:h2:mem:test") - .setProperty("hibernate.connection.username", "sa").setProperty("hibernate.connection.password", "") - .setProperty("hibernate.hbm2ddl.auto", "update"); - ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() - .applySettings(configuration.getProperties()).build(); - sessionFactory = configuration.buildSessionFactory(serviceRegistry); + sessionFactory = HibernateAnnotationUtil.getSessionFactory(); } @Before @@ -52,32 +36,38 @@ public class HibernateOneToManyAnnotationMainIntegrationTest { @Test public void givenSession_checkIfDatabaseIsEmpty() { - Cart cart = (Cart) session.get(Cart.class, new Long(1)); + Cart cart = session.get(Cart.class, 1L); assertNull(cart); - } @Test public void givenSession_checkIfDatabaseIsPopulated_afterCommit() { Cart cart = new Cart(); - Set cartItems = new HashSet<>(); - cartItems = cart.getItems(); - Assert.assertNull(cartItems); - Items item1 = new Items(); + Set cartItems = cart.getItems(); + + assertNull(cartItems); + + Item item1 = new Item(); item1.setCart(cart); + assertNotNull(item1); - Set itemsSet = new HashSet(); - itemsSet.add(item1); - assertNotNull(itemsSet); - cart.setItems(itemsSet); + + Set itemSet = new HashSet<>(); + itemSet.add(item1); + + assertNotNull(itemSet); + cart.setItems(itemSet); + assertNotNull(cart); + session.persist(cart); session.getTransaction().commit(); session.close(); session = sessionFactory.openSession(); session.beginTransaction(); - cart = (Cart) session.get(Cart.class, new Long(1)); + cart = session.get(Cart.class, 1L); + assertNotNull(cart); } diff --git a/persistence-modules/hibernate-annotations/src/test/resources/hibernate-spatial.properties b/persistence-modules/hibernate-annotations/src/test/resources/hibernate-spatial.properties deleted file mode 100644 index 1657c838e3..0000000000 --- a/persistence-modules/hibernate-annotations/src/test/resources/hibernate-spatial.properties +++ /dev/null @@ -1,14 +0,0 @@ -hibernate.connection.driver_class=org.h2.Driver -hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 -hibernate.connection.username=sa -hibernate.connection.autocommit=true -jdbc.password= - -hibernate.dialect=org.hibernate.spatial.dialect.h2geodb.GeoDBDialect -hibernate.show_sql=true -hibernate.hbm2ddl.auto=create-drop - -hibernate.c3p0.min_size=5 -hibernate.c3p0.max_size=20 -hibernate.c3p0.acquire_increment=5 -hibernate.c3p0.timeout=1800 diff --git a/persistence-modules/hibernate-annotations/src/test/resources/log4j.xml b/persistence-modules/hibernate-annotations/src/test/resources/log4j.xml index 7e2895f1e0..bc2c24ea93 100644 --- a/persistence-modules/hibernate-annotations/src/test/resources/log4j.xml +++ b/persistence-modules/hibernate-annotations/src/test/resources/log4j.xml @@ -1,24 +1,31 @@ - + + + + + - + + + - \ No newline at end of file + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/src/test/resources/profile.png b/persistence-modules/hibernate-annotations/src/test/resources/profile.png deleted file mode 100644 index 1cd4e978b9..0000000000 Binary files a/persistence-modules/hibernate-annotations/src/test/resources/profile.png and /dev/null differ diff --git a/persistence-modules/hibernate-exceptions/README.md b/persistence-modules/hibernate-exceptions/README.md index 2e5a98c2f8..c485de2f34 100644 --- a/persistence-modules/hibernate-exceptions/README.md +++ b/persistence-modules/hibernate-exceptions/README.md @@ -5,3 +5,4 @@ - [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception) - [Hibernate’s “Object References an Unsaved Transient Instance” Error](https://www.baeldung.com/hibernate-unsaved-transient-instance-error) - [EntityNotFoundException in Hibernate](https://www.baeldung.com/hibernate-entitynotfoundexception) +- [Hibernate’s “Not-Null Property References a Null or Transient Value” Error](https://www.baeldung.com/hibernate-not-null-error) diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/HibernateUtil.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/HibernateUtil.java new file mode 100644 index 0000000000..641b80b412 --- /dev/null +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/HibernateUtil.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.exception.persistentobject; + +import java.util.Properties; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.service.ServiceRegistry; + +import com.baeldung.hibernate.exception.persistentobject.entity.Article; +import com.baeldung.hibernate.exception.persistentobject.entity.Author; +import com.baeldung.hibernate.exception.persistentobject.entity.Book; + +public class HibernateUtil { + private static SessionFactory sessionFactory; + + public static SessionFactory getSessionFactory() { + if (sessionFactory == null) { + try { + Configuration configuration = new Configuration(); + Properties settings = new Properties(); + + settings.put(Environment.DRIVER, "org.hsqldb.jdbcDriver"); + settings.put(Environment.URL, "jdbc:hsqldb:mem:userrole"); + settings.put(Environment.USER, "sa"); + settings.put(Environment.PASS, ""); + settings.put(Environment.DIALECT, "org.hibernate.dialect.HSQLDialect"); + settings.put(Environment.SHOW_SQL, "true"); + settings.put(Environment.HBM2DDL_AUTO, "update"); + settings.put(Environment.CHECK_NULLABILITY, "true"); + + configuration.setProperties(settings); + configuration.addAnnotatedClass(Book.class); + configuration.addAnnotatedClass(Author.class); + configuration.addAnnotatedClass(Article.class); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(configuration.getProperties()).build(); + sessionFactory = configuration.buildSessionFactory(serviceRegistry); + } catch (Exception e) { + e.printStackTrace(); + } + } + return sessionFactory; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java new file mode 100644 index 0000000000..3c9c7c5b31 --- /dev/null +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Article.java @@ -0,0 +1,29 @@ +package com.baeldung.hibernate.exception.persistentobject.entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity +public class Article { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String title; + + @ManyToOne(optional = false) + private Author author; + + public Article(String title) { + this.title = title; + } + + public void setAuthor(Author author) { + this.author = author; + } + +} diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java new file mode 100644 index 0000000000..fa6aaa9abe --- /dev/null +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Author.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.exception.persistentobject.entity; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; + +import org.hibernate.annotations.Cascade; +import org.hibernate.annotations.CascadeType; + +@Entity +public class Author { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + @OneToMany + @Cascade(CascadeType.ALL) + private List
articles; + + public Author(String name) { + this.name = name; + } + + public Author() { + } + + public List
getArticles() { + return articles; + } + + public void setArticles(List
articles) { + this.articles = articles; + } + + public void addArticles(List
articles) { + this.articles = articles; + articles.forEach(article -> article.setAuthor(this)); + } + +} diff --git a/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java new file mode 100644 index 0000000000..342da27c77 --- /dev/null +++ b/persistence-modules/hibernate-exceptions/src/main/java/com/baeldung/hibernate/exception/persistentobject/entity/Book.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.exception.persistentobject.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; + +@Entity +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(nullable = false) + private String title; + + public Book(String title) { + this.title = title; + } + + public Book() { + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/persistentobject/HibernatePersistentObjectUnitTest.java b/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/persistentobject/HibernatePersistentObjectUnitTest.java new file mode 100644 index 0000000000..09f11b07a2 --- /dev/null +++ b/persistence-modules/hibernate-exceptions/src/test/java/com/baeldung/hibernate/exception/persistentobject/HibernatePersistentObjectUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.hibernate.exception.persistentobject; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.hibernate.PropertyValueException; +import org.hibernate.Session; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.exception.persistentobject.entity.Article; +import com.baeldung.hibernate.exception.persistentobject.entity.Author; +import com.baeldung.hibernate.exception.persistentobject.entity.Book; + +public class HibernatePersistentObjectUnitTest { + + private static Session session; + + @Before + public void beforeAll() { + session = HibernateUtil.getSessionFactory() + .openSession(); + session.beginTransaction(); + } + + @After + public void afterAll() { + session.close(); + } + + @Test + public void whenSavingEntityWithNullMandatoryField_thenThrowPropertyValueException() { + Book book = new Book(); + + assertThatThrownBy(() -> session.save(book)).isInstanceOf(PropertyValueException.class) + .hasMessageContaining("not-null property references a null or transient value"); + } + + @Test + public void whenSavingEntityWithAllMandatoryField_thenDoNotThrowException() { + Book book = new Book(); + book.setTitle("Clean Code"); + + session.save(book); + } + + @Test + public void whenSavingBidirectionalEntitiesWithoutSettingParent_thenThrowPropertyValueException() { + Author author = new Author("John Doe"); + author.setArticles(asList(new Article("Java Tutorial"), new Article("What's New in JUnit5"))); + + assertThatThrownBy(() -> session.save(author)).isInstanceOf(PropertyValueException.class) + .hasMessageContaining("not-null property references a null or transient value"); + } + + @Test + public void whenSavingBidirectionalEntitiesWithCorrectParent_thenDoNotThrowException() { + Author author = new Author("John Doe"); + author.addArticles(asList(new Article("Java tutorial"), new Article("What's new in JUnit5"))); + + session.save(author); + } + +} \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/src/main/resources/log4j.xml b/persistence-modules/hibernate-jpa/src/main/resources/log4j.xml new file mode 100644 index 0000000000..f58dbdc514 --- /dev/null +++ b/persistence-modules/hibernate-jpa/src/main/resources/log4j.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-namedquery.properties b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-namedquery.properties index 457f965347..2f05e32a30 100644 --- a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-namedquery.properties +++ b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-namedquery.properties @@ -5,5 +5,8 @@ hibernate.connection.autocommit=true jdbc.password= hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true + +# enable to see Hibernate generated SQL +hibernate.show_sql=false + hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties index 342f7b0bf5..da6ab4d68a 100644 --- a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties +++ b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-pessimistic-locking.properties @@ -4,5 +4,7 @@ hibernate.connection.username=sa hibernate.connection.autocommit=true hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true +# enable to see Hibernate generated SQL +hibernate.show_sql=false + hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/src/test/resources/hibernate.properties b/persistence-modules/hibernate-jpa/src/test/resources/hibernate.properties index c14782ce0f..20197700a1 100644 --- a/persistence-modules/hibernate-jpa/src/test/resources/hibernate.properties +++ b/persistence-modules/hibernate-jpa/src/test/resources/hibernate.properties @@ -5,7 +5,10 @@ hibernate.connection.autocommit=true jdbc.password= hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true + +# enable to see Hibernate generated SQL +hibernate.show_sql=false + hibernate.hbm2ddl.auto=create-drop hibernate.c3p0.min_size=5 diff --git a/persistence-modules/hibernate-queries/README.md b/persistence-modules/hibernate-queries/README.md index f1bc1cba0f..f5cba1aa6f 100644 --- a/persistence-modules/hibernate-queries/README.md +++ b/persistence-modules/hibernate-queries/README.md @@ -10,3 +10,5 @@ This module contains articles about use of Queries in Hibernate. - [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query) - [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) - [Hibernate’s addScalar() Method](https://www.baeldung.com/hibernate-addscalar) +- [Distinct Queries in HQL](https://www.baeldung.com/java-hql-distinct) +- [JPA and Hibernate – Criteria vs. JPQL vs. HQL Query](https://www.baeldung.com/jpql-hql-criteria-query) diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml index 4f5de5c06e..ff5a9fe221 100644 --- a/persistence-modules/hibernate-queries/pom.xml +++ b/persistence-modules/hibernate-queries/pom.xml @@ -14,7 +14,7 @@ - + org.springframework spring-context @@ -30,8 +30,7 @@ tomcat-dbcp ${tomcat-dbcp.version} - - + com.google.guava @@ -45,7 +44,6 @@ ${org.springframework.version} test - org.hibernate hibernate-core @@ -81,8 +79,7 @@ jmh-generator-annprocess ${jmh-generator.version} - - + 5.0.2.RELEASE diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/HibernateUtil.java index 58724e690c..84b20197bd 100644 --- a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -13,6 +13,8 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; import com.baeldung.hibernate.customtypes.LocalDateStringType; +import com.baeldung.hibernate.distinct.entities.Post; +import com.baeldung.hibernate.distinct.entities.Comment; import com.baeldung.hibernate.entities.DeptEmployee; import com.baeldung.hibernate.pojo.Student; @@ -41,6 +43,8 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(Student.class); metadataSources.addAnnotatedClass(DeptEmployee.class); metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class); + metadataSources.addAnnotatedClass(Comment.class); + metadataSources.addAnnotatedClass(Post.class); Metadata metadata = metadataSources.getMetadataBuilder() .applyBasicType(LocalDateStringType.INSTANCE) diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java new file mode 100644 index 0000000000..8771e02e0b --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/model/Employee.java @@ -0,0 +1,83 @@ +package com.baeldung.hibernate.criteria.model; + +import java.io.Serializable; +import javax.persistence.Entity; + +@org.hibernate.annotations.NamedQueries({ + @org.hibernate.annotations.NamedQuery(name = "Employee_findByEmployeeId", query = "from Employee where id = :employeeId"), + @org.hibernate.annotations.NamedQuery(name = "Employee_findAllByEmployeeSalary", query = "from Employee where salary = :employeeSalary")}) +@org.hibernate.annotations.NamedNativeQueries({ + @org.hibernate.annotations.NamedNativeQuery(name = "Employee_FindByEmployeeId", query = "select * from employee emp where employeeId=:employeeId", resultClass = Employee.class)}) +@Entity +public class Employee implements Serializable { + + private static final long serialVersionUID = 1L; + private Integer id; + private String name; + private Long salary; + + // constructors + public Employee() { + } + + public Employee(final Integer id, final String name, final Long salary) { + super(); + this.id = id; + this.name = name; + this.salary = salary; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Employee other = (Employee) obj; + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getSalary() { + return salary; + } + + public void setSalary(Long salary) { + this.salary = salary; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java new file mode 100644 index 0000000000..f8c525611b --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/criteria/view/EmployeeCriteriaQueries.java @@ -0,0 +1,44 @@ +package com.baeldung.hibernate.criteria.view; + +import com.baeldung.hibernate.criteria.model.Employee; +import com.baeldung.hibernate.criteria.util.HibernateUtil; +import java.util.List; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import org.hibernate.Session; +import org.hibernate.query.Query; + +public class EmployeeCriteriaQueries { + + public List getAllEmployees() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Employee.class); + final Root root = cr.from(Employee.class); + cr.select(root); + Query query = session.createQuery(cr); + List results = query.getResultList(); + session.close(); + return results; + } + + // To get items having salary more than 50000 + public String[] greaterThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Employee.class); + final Root root = cr.from(Employee.class); + cr.select(root) + .where(cb.gt(root.get("salary"), 50000)); + Query query = session.createQuery(cr); + final List greaterThanEmployeeList = query.getResultList(); + final String employeeWithGreaterSalary[] = new String[greaterThanEmployeeList.size()]; + for (int i = 0; i < greaterThanEmployeeList.size(); i++) { + employeeWithGreaterSalary[i] = greaterThanEmployeeList.get(i) + .getName(); + } + session.close(); + return employeeWithGreaterSalary; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/distinct/entities/Comment.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/distinct/entities/Comment.java new file mode 100644 index 0000000000..1d155b112e --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/distinct/entities/Comment.java @@ -0,0 +1,28 @@ +package com.baeldung.hibernate.distinct.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Comment { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String text; + + public Comment() { + } + + public Comment(String text) { + this.text = text; + } + + @Override + public String toString() { + return "Comment{" + "id=" + id + ", text='" + text + '\'' + '}'; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/distinct/entities/Post.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/distinct/entities/Post.java new file mode 100644 index 0000000000..d2608e614c --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/distinct/entities/Post.java @@ -0,0 +1,59 @@ +package com.baeldung.hibernate.distinct.entities; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +import org.hibernate.annotations.Cascade; +import org.hibernate.annotations.CascadeType; + +@Entity +public class Post { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String title; + + @OneToMany + @Cascade(CascadeType.ALL) + private List comments; + + public Post() { + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getComments() { + return comments; + } + + public void setComments(List comments) { + this.comments = comments; + } + + @Override + public String toString() { + return "Post{" + "id=" + id + ", title='" + title + '\'' + ", comments=" + comments + '}'; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/resources/log4j.xml b/persistence-modules/hibernate-queries/src/main/resources/log4j.xml new file mode 100644 index 0000000000..f58dbdc514 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/resources/log4j.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/persistence-modules/hibernate-queries/src/main/resources/logback.xml b/persistence-modules/hibernate-queries/src/main/resources/logback.xml index 612296c6ce..56af2d397e 100644 --- a/persistence-modules/hibernate-queries/src/main/resources/logback.xml +++ b/persistence-modules/hibernate-queries/src/main/resources/logback.xml @@ -12,7 +12,7 @@ - + diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/SpringContextTest.java index 6503454abf..83af0e0be6 100644 --- a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/SpringContextTest.java @@ -1,5 +1,6 @@ package com.baeldung; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; @@ -13,6 +14,7 @@ import com.baeldung.hibernate.criteria.PersistenceConfig; public class SpringContextTest { @Test + @Ignore public void whenSpringContextIsBootstrapped_thenNoExceptions() { } } diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java new file mode 100644 index 0000000000..4553bf398c --- /dev/null +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/criteria/EmployeeCriteriaIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.hibernate.criteria; + +import static org.junit.Assert.assertArrayEquals; + +import com.baeldung.hibernate.criteria.model.Employee; +import com.baeldung.hibernate.criteria.util.HibernateUtil; +import com.baeldung.hibernate.criteria.view.EmployeeCriteriaQueries; +import java.util.List; +import org.hibernate.Session; +import org.junit.Test; + +public class EmployeeCriteriaIntegrationTest { + + final private EmployeeCriteriaQueries employeeCriteriaQueries = new EmployeeCriteriaQueries(); + + @Test + public void testGreaterThanCriteriaQuery() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedGreaterThanList = session.createQuery("From Employee where salary>50000").list(); + final String expectedGreaterThanEmployees[] = new String[expectedGreaterThanList.size()]; + for (int i = 0; i < expectedGreaterThanList.size(); i++) { + expectedGreaterThanEmployees[i] = expectedGreaterThanList.get(i).getName(); + } + session.close(); + assertArrayEquals(expectedGreaterThanEmployees, employeeCriteriaQueries.greaterThanCriteria()); + } + + @Test + public void testGetAllEmployeesQuery() { + final Session session = HibernateUtil.getHibernateSession(); + final List expectedSortCritEmployeeList = session.createQuery("From Employee").list(); + session.close(); + assertArrayEquals(expectedSortCritEmployeeList.toArray(), employeeCriteriaQueries.getAllEmployees().toArray()); + } +} diff --git a/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java new file mode 100644 index 0000000000..799439a51b --- /dev/null +++ b/persistence-modules/hibernate-queries/src/test/java/com/baeldung/hibernate/distinct/entities/DistinctHqlQueriesUnitTest.java @@ -0,0 +1,80 @@ +package com.baeldung.hibernate.distinct.entities; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.annotations.QueryHints; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.HibernateUtil; + +public class DistinctHqlQueriesUnitTest { + + private Session session; + + @Before + public void setUp() throws IOException { + this.session = HibernateUtil.getSessionFactory() + .openSession(); + saveDummyData(); + } + + private void saveDummyData() { + Transaction trx = session.beginTransaction(); + session.createQuery("delete from Post") + .executeUpdate(); + + Post post = new Post(); + post.setTitle("Distinct Queries in HQL"); + post.setComments(Arrays.asList(new Comment("Great article!"), new Comment("Nice one :)"), new Comment("Keep up the good work!"))); + session.persist(post); + + trx.commit(); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void whenExecutingSelectQuery_thereWillBeDuplicates() { + String hql = "SELECT p FROM Post p LEFT JOIN FETCH p.comments"; + List posts = session.createQuery(hql, Post.class) + .getResultList(); + + assertThat(posts).hasSize(3); + } + + @Test + public void whenExecutingSelectDistinctQuery_thereShouldBeNoDuplicates() { + String hql = "SELECT DISTINCT p FROM Post p LEFT JOIN FETCH p.comments"; + List posts = session.createQuery(hql, Post.class) + .getResultList(); + + assertThat(posts).hasSize(1) + .allMatch(post -> post.getTitle() + .equals("Distinct Queries in HQL") && post.getComments() + .size() == 3); + } + + @Test + public void whenExecutingSelectDistinctQueryWithHint_thereShouldBeNoDuplicates() { + String hql = "SELECT DISTINCT p FROM Post p LEFT JOIN FETCH p.comments"; + List posts = session.createQuery(hql, Post.class) + .setHint(QueryHints.PASS_DISTINCT_THROUGH, false) + .getResultList(); + + assertThat(posts).hasSize(1) + .allMatch(post -> post.getTitle() + .equals("Distinct Queries in HQL") && post.getComments() + .size() == 3); + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml b/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml new file mode 100644 index 0000000000..0cc1c54680 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/test/resources/com/baeldung/hibernate/criteria/model/Employee.hbm.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/src/test/resources/criteria.cfg.xml b/persistence-modules/hibernate-queries/src/test/resources/criteria.cfg.xml index 9ca9836a70..30d8168c5c 100644 --- a/persistence-modules/hibernate-queries/src/test/resources/criteria.cfg.xml +++ b/persistence-modules/hibernate-queries/src/test/resources/criteria.cfg.xml @@ -14,5 +14,6 @@ import-db.sql false + \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/src/test/resources/hibernate-customtypes.properties b/persistence-modules/hibernate-queries/src/test/resources/hibernate-customtypes.properties index c14782ce0f..c202f59f82 100644 --- a/persistence-modules/hibernate-queries/src/test/resources/hibernate-customtypes.properties +++ b/persistence-modules/hibernate-queries/src/test/resources/hibernate-customtypes.properties @@ -5,7 +5,8 @@ hibernate.connection.autocommit=true jdbc.password= hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true +# enable to see Hibernate generated SQL +hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop hibernate.c3p0.min_size=5 diff --git a/persistence-modules/hibernate-queries/src/test/resources/hibernate-namedquery.properties b/persistence-modules/hibernate-queries/src/test/resources/hibernate-namedquery.properties index 457f965347..120212070a 100644 --- a/persistence-modules/hibernate-queries/src/test/resources/hibernate-namedquery.properties +++ b/persistence-modules/hibernate-queries/src/test/resources/hibernate-namedquery.properties @@ -5,5 +5,6 @@ hibernate.connection.autocommit=true jdbc.password= hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true +# enable to see Hibernate generated SQL +hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/persistence-modules/hibernate-queries/src/test/resources/hibernate.properties b/persistence-modules/hibernate-queries/src/test/resources/hibernate.properties index c14782ce0f..c202f59f82 100644 --- a/persistence-modules/hibernate-queries/src/test/resources/hibernate.properties +++ b/persistence-modules/hibernate-queries/src/test/resources/hibernate.properties @@ -5,7 +5,8 @@ hibernate.connection.autocommit=true jdbc.password= hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true +# enable to see Hibernate generated SQL +hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop hibernate.c3p0.min_size=5 diff --git a/persistence-modules/hibernate-queries/src/test/resources/import-db.sql b/persistence-modules/hibernate-queries/src/test/resources/import-db.sql index 52c800f6b4..7933d280b8 100644 --- a/persistence-modules/hibernate-queries/src/test/resources/import-db.sql +++ b/persistence-modules/hibernate-queries/src/test/resources/import-db.sql @@ -20,3 +20,10 @@ insert into item (item_id, item_name, item_desc, item_price) values(9,'Household 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); + +insert into EMPLOYEE (id, name, salary) values(1,'Steve Jobs', 55000); + +insert into EMPLOYEE (id, name, salary) values(1,'Bill Hages', 45000); + +insert into EMPLOYEE (id, name, salary) values(1,'Mark clinch', 57000); + diff --git a/persistence-modules/hibernate-queries/src/test/resources/log4j.xml b/persistence-modules/hibernate-queries/src/test/resources/log4j.xml new file mode 100644 index 0000000000..f58dbdc514 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/test/resources/log4j.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java index 9d98d6b86f..36a7cb1002 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/enums/ArticleUnitTest.java @@ -22,8 +22,9 @@ public class ArticleUnitTest { @BeforeClass public static void setup() { Map properties = new HashMap<>(); - properties.put("hibernate.show_sql", "true"); - properties.put("hibernate.format_sql", "true"); + // set these to true to see Hibernate SQL + properties.put("hibernate.show_sql", "false"); + properties.put("hibernate.format_sql", "false"); emFactory = Persistence.createEntityManagerFactory("jpa-h2", properties); em = emFactory.createEntityManager(); } diff --git a/persistence-modules/java-jpa/src/test/resources/persistence.xml b/persistence-modules/java-jpa/src/test/resources/persistence.xml index c902e0a320..e9b5ebbbcf 100644 --- a/persistence-modules/java-jpa/src/test/resources/persistence.xml +++ b/persistence-modules/java-jpa/src/test/resources/persistence.xml @@ -14,7 +14,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/persistence-modules/java-mongodb-2/README.md b/persistence-modules/java-mongodb-2/README.md index bee5439ab1..10cb935f56 100644 --- a/persistence-modules/java-mongodb-2/README.md +++ b/persistence-modules/java-mongodb-2/README.md @@ -11,4 +11,5 @@ This module contains articles about MongoDB in Java. - [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) +- [Checking Connection to MongoDB](https://www.baeldung.com/mongodb-check-connection) - More articles: [[<-- prev]](../java-mongodb) diff --git a/persistence-modules/java-mongodb-2/pom.xml b/persistence-modules/java-mongodb-2/pom.xml index ffc8da0b64..9475a86bee 100644 --- a/persistence-modules/java-mongodb-2/pom.xml +++ b/persistence-modules/java-mongodb-2/pom.xml @@ -50,4 +50,4 @@ 1.5.3 - + \ No newline at end of file diff --git a/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/ConnectionCheck.java b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/ConnectionCheck.java new file mode 100644 index 0000000000..df17e27351 --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/main/java/com/baeldung/mongo/ConnectionCheck.java @@ -0,0 +1,46 @@ +package com.baeldung; + +import com.mongodb.DB; +import com.mongodb.MongoClient; +import com.mongodb.MongoClientOptions; +import com.mongodb.ServerAddress; + +public class ConnectionCheck { + + public static MongoClient checkingConnection() { + + MongoClientOptions.Builder builder = MongoClientOptions.builder(); + + builder.connectionsPerHost(100); + builder.maxWaitTime(60000); + builder.connectTimeout(1500); + builder.socketTimeout(60000); + builder.socketKeepAlive(true); + + ServerAddress ServerAddress = new ServerAddress("localhost", 27017); + MongoClient mongoClient = new MongoClient(ServerAddress, builder.build()); + + try { + System.out.println("MongoDB Server is Up:- " + mongoClient.getAddress()); + DB db = mongoClient.getDB("baeldung"); + System.out.println(mongoClient.getConnectPoint()); + System.out.println(db.getStats()); + } catch (Exception e) { + System.out.println("MongoDB Server is Down"); + } + + return mongoClient; + + } + + public static void main(String[] args) { + + // + // Connection check + // + + checkingConnection(); + + } + +} \ No newline at end of file diff --git a/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/ConnectionCheckLiveTest.java b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/ConnectionCheckLiveTest.java new file mode 100644 index 0000000000..32014a4473 --- /dev/null +++ b/persistence-modules/java-mongodb-2/src/test/java/com/baeldung/mongo/ConnectionCheckLiveTest.java @@ -0,0 +1,24 @@ +package com.baeldung.mongo; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.baeldung.ConnectionCheck; +import com.mongodb.MongoClient; + +public class ConnectionCheckLiveTest { + + ConnectionCheck ConnectionCheck = new ConnectionCheck(); + + @Test + public void givenMongoClient_whenConnectionCheck_thenCheckingForConnectionPoint() { + + MongoClient mongoClient = ConnectionCheck.checkingConnection(); + String connectionPoint = mongoClient.getConnectPoint(); + assertNotNull(connectionPoint); + assertFalse(connectionPoint.isEmpty()); + + } +} \ No newline at end of file diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/bsontojson/BsonToJsonLiveTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/bsontojson/BsonToJsonLiveTest.java index 12053523f8..0548119d7a 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/bsontojson/BsonToJsonLiveTest.java +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/bsontojson/BsonToJsonLiveTest.java @@ -21,7 +21,7 @@ import dev.morphia.Datastore; import dev.morphia.Morphia; public class BsonToJsonLiveTest { - + private static final String DB_NAME = "library"; private static Datastore datastore; @@ -31,17 +31,17 @@ public class BsonToJsonLiveTest { morphia.mapPackage("com.baeldung.bsontojson"); datastore = morphia.createDatastore(new MongoClient(), DB_NAME); datastore.ensureIndexes(); - + datastore.save(new Book() .setIsbn("isbn") .setTitle("title") .setAuthor("author") .setCost(3.95) .setPublisher(new Publisher(new ObjectId("fffffffffffffffffffffffa"),"publisher")) - .setPublishDate(LocalDateTime.parse("2020-01-01T18:13:32Z", DateTimeFormatter.ISO_DATE_TIME)) + .setPublishDate(LocalDateTime.parse("2020-01-01T17:13:32Z", DateTimeFormatter.ISO_DATE_TIME)) .addCompanionBooks(new Book().setIsbn("isbn2"))); } - + @AfterClass public static void tearDown() { datastore.delete(datastore.createQuery(Book.class)); @@ -50,32 +50,32 @@ public class BsonToJsonLiveTest { @Test public void givenBsonDocument_whenUsingStandardJsonTransformation_thenJsonDateIsObjectEpochTime() { - String json = null; + String json; try (MongoClient mongoClient = new MongoClient()) { MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME); Document bson = mongoDatabase.getCollection("Books").find().first(); json = bson.toJson(); } - - String expectedJson = "{\"_id\": \"isbn\", " + - "\"className\": \"com.baeldung.bsontojson.Book\", " + - "\"title\": \"title\", " + - "\"author\": \"author\", " + - "\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " + - "\"name\": \"publisher\"}, " + - "\"price\": 3.95, " + + + String expectedJson = "{\"_id\": \"isbn\", " + + "\"className\": \"com.baeldung.bsontojson.Book\", " + + "\"title\": \"title\", " + + "\"author\": \"author\", " + + "\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " + + "\"name\": \"publisher\"}, " + + "\"price\": 3.95, " + "\"publishDate\": {\"$date\": 1577898812000}}"; assertNotNull(json); - + assertEquals(expectedJson, json); } - + @Test public void givenBsonDocument_whenUsingRelaxedJsonTransformation_thenJsonDateIsObjectIsoDate() { - - String json = null; + + String json; try (MongoClient mongoClient = new MongoClient()) { MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME); Document bson = mongoDatabase.getCollection("Books").find().first(); @@ -84,25 +84,25 @@ public class BsonToJsonLiveTest { .outputMode(JsonMode.RELAXED) .build()); } - - String expectedJson = "{\"_id\": \"isbn\", " + - "\"className\": \"com.baeldung.bsontojson.Book\", " + - "\"title\": \"title\", " + - "\"author\": \"author\", " + - "\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " + - "\"name\": \"publisher\"}, " + - "\"price\": 3.95, " + + + String expectedJson = "{\"_id\": \"isbn\", " + + "\"className\": \"com.baeldung.bsontojson.Book\", " + + "\"title\": \"title\", " + + "\"author\": \"author\", " + + "\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " + + "\"name\": \"publisher\"}, " + + "\"price\": 3.95, " + "\"publishDate\": {\"$date\": \"2020-01-01T17:13:32Z\"}}"; assertNotNull(json); - + assertEquals(expectedJson, json); } - + @Test public void givenBsonDocument_whenUsingCustomJsonTransformation_thenJsonDateIsStringField() { - String json = null; + String json; try (MongoClient mongoClient = new MongoClient()) { MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME); Document bson = mongoDatabase.getCollection("Books").find().first(); @@ -112,13 +112,13 @@ public class BsonToJsonLiveTest { .build()); } - String expectedJson = "{\"_id\": \"isbn\", " + - "\"className\": \"com.baeldung.bsontojson.Book\", " + - "\"title\": \"title\", " + - "\"author\": \"author\", " + - "\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " + - "\"name\": \"publisher\"}, " + - "\"price\": 3.95, " + + String expectedJson = "{\"_id\": \"isbn\", " + + "\"className\": \"com.baeldung.bsontojson.Book\", " + + "\"title\": \"title\", " + + "\"author\": \"author\", " + + "\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " + + "\"name\": \"publisher\"}, " + + "\"price\": 3.95, " + "\"publishDate\": \"2020-01-01T17:13:32Z\"}"; assertEquals(expectedJson, json); diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index f8e3cb05e8..acfd171f3b 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -15,7 +15,7 @@ activejdbc - apache-bookkeeper + apache-bookkeeper apache-cayenne apache-derby core-java-persistence @@ -52,6 +52,7 @@ persistence-libraries querydsl r2dbc + read-only-transactions redis solr @@ -60,6 +61,7 @@ spring-boot-persistence spring-boot-persistence-h2 spring-boot-persistence-mongodb + spring-boot-persistence-mongodb-2 spring-data-arangodb spring-data-cassandra spring-data-cassandra-test @@ -69,7 +71,7 @@ spring-data-dynamodb spring-data-eclipselink spring-data-elasticsearch - spring-data-gemfire + spring-data-geode spring-data-jpa-annotations spring-data-jpa-crud @@ -88,6 +90,9 @@ spring-data-mongodb-reactive spring-data-neo4j spring-data-redis + spring-data-rest + spring-data-rest-2 + spring-data-rest-querydsl spring-data-solr spring-hibernate-3 spring-hibernate-5 @@ -105,4 +110,4 @@ 42.2.20 - + \ No newline at end of file diff --git a/persistence-modules/read-only-transactions/README.md b/persistence-modules/read-only-transactions/README.md new file mode 100644 index 0000000000..8f3898f217 --- /dev/null +++ b/persistence-modules/read-only-transactions/README.md @@ -0,0 +1,8 @@ +### Relevant Articles: +- [Using Transactions for Read-Only Operations](https://www.baeldung.com/spring-transactions-read-only) + +### Instructions +To run the `com.baeldung.read_only_transactions.TransactionSetupIntegrationTest` first follow the steps described next: +- run the command `docker-compose -f docker-compose-mysql.yml up` +- Open a SQL client of your preference and execute the `create.sql` script. +- You can check the mysql logs using `tail -f mysql/${name of de log file created}.log` diff --git a/persistence-modules/read-only-transactions/create.sql b/persistence-modules/read-only-transactions/create.sql new file mode 100644 index 0000000000..0ba60be150 --- /dev/null +++ b/persistence-modules/read-only-transactions/create.sql @@ -0,0 +1,43 @@ +create table book ( + id bigint(20) AUTO_INCREMENT primary key, + name varchar(255) not null, + uuid varchar(40) +); + + +DELIMITER ;; +DROP PROCEDURE IF EXISTS populate; +create procedure populate() +BEGIN + SET @name1='Josh purchase'; + SET @name2='Henry purchase'; + SET @name3='Betty purchase'; + SET @name4='Kate purchase'; + SET @name5='Mari purchase'; + SET @name=''; + SET @counter=0; + + START TRANSACTION; + + while @counter < 1000000 do + SET @name = case + when MOD(@counter, 5) = 0 THEN @name5 + when MOD(@counter, 3) = 0 THEN @name3 + when MOD(@counter, 4) = 0 THEN @name4 + when MOD(@counter, 2) = 0 THEN @name2 + else @name1 + end; + + insert into book(name, uuid) values(@name, uuid()); + SET @counter=@counter+1; + end while; + + COMMIT; + +END;; + +DELIMITER ; + +CALL populate(); + + diff --git a/persistence-modules/read-only-transactions/docker-compose-mysql.yml b/persistence-modules/read-only-transactions/docker-compose-mysql.yml new file mode 100644 index 0000000000..a922fabbd8 --- /dev/null +++ b/persistence-modules/read-only-transactions/docker-compose-mysql.yml @@ -0,0 +1,15 @@ +version: "3.9" # optional since v1.27.0 +services: + mysql: + build: . + restart: always + ports: + - "3306:3306" + environment: + MYSQL_PASSWORD: "baeldung" + MYSQL_USER: "baeldung" + MYSQL_DATABASE: "baeldung" + MYSQL_ROOT_PASSWORD: "baeldung" + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb_buffer_pool_size=3G --innodb_adaptive_hash_index=off --query_cache_size=0 --query_cache_type=0 --log_output=FILE --general_log=1 + volumes: + - ./mysql:/var/lib/mysql/ \ No newline at end of file diff --git a/persistence-modules/read-only-transactions/pom.xml b/persistence-modules/read-only-transactions/pom.xml new file mode 100644 index 0000000000..d3822f8e58 --- /dev/null +++ b/persistence-modules/read-only-transactions/pom.xml @@ -0,0 +1,89 @@ + + + + 4.0.0 + read-only-transactions + 0.0.1-SNAPSHOT + read-only-transactions + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring-boot.version} + + + com.zaxxer + HikariCP + + + + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + + org.springframework + spring-test + ${spring-test.version} + test + + + + mysql + mysql-connector-java + ${mysql.version} + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + + com.zaxxer + HikariCP + ${hikari.version} + + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + + com.h2database + h2 + ${h2.version} + runtime + + + + + + + 8.0.21 + 4.0.3 + 5.6.1.Final + 2.6.1 + 5.3.13 + 5.8.2 + 1.4.200 + + \ No newline at end of file diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/Book.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/Book.java new file mode 100644 index 0000000000..000859a201 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/Book.java @@ -0,0 +1,44 @@ +package com.baeldung.readonlytransactions.h2; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "book") +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + private String uuid; + + 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; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/BookService.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/BookService.java new file mode 100644 index 0000000000..0ecbc4a0d4 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/BookService.java @@ -0,0 +1,24 @@ +package com.baeldung.readonlytransactions.h2; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManagerFactory; + +@Service +public class BookService { + + private EntityManagerFactory entityManagerFactory; + + public BookService(@Autowired @Qualifier("h2EntityManagerFactory") EntityManagerFactory entityManagerFactory) { + this.entityManagerFactory = entityManagerFactory; + } + + @Transactional(readOnly = true) + public Book getBookById(long id) { + return entityManagerFactory.createEntityManager() + .find(Book.class, id); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/Config.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/Config.java new file mode 100644 index 0000000000..241dad417b --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/Config.java @@ -0,0 +1,54 @@ +package com.baeldung.readonlytransactions.h2; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +import java.util.Properties; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +@Configuration +public class Config { + + @Bean("h2DataSource") + public DataSource dataSource() { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:h2:mem:mydb"); + config.setUsername("sa"); + config.setPassword(""); + config.setDriverClassName("org.h2.Driver"); + return new HikariDataSource(config); + } + + @Bean("h2EntityManagerFactory") + public EntityManagerFactory entityManagerFactory(@Qualifier("h2DataSource") DataSource dataSource) { + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setGenerateDdl(false); + + LocalContainerEntityManagerFactoryBean managerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + managerFactoryBean.setJpaVendorAdapter(vendorAdapter); + managerFactoryBean.setPackagesToScan(Config.class.getPackage() + .getName()); + managerFactoryBean.setDataSource(dataSource); + + Properties properties = new Properties(); + + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); + + properties.setProperty("hibernate.show_sql", "true"); + properties.setProperty("hibernate.format_sql", "true"); + + managerFactoryBean.setJpaProperties(properties); + managerFactoryBean.afterPropertiesSet(); + + return managerFactoryBean.getObject(); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/TransactionConfig.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/TransactionConfig.java new file mode 100644 index 0000000000..62abb85edd --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/h2/TransactionConfig.java @@ -0,0 +1,21 @@ +package com.baeldung.readonlytransactions.h2; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; + +@Configuration +@EnableTransactionManagement +public class TransactionConfig { + + @Bean + public PlatformTransactionManager transactionManager(@Qualifier("h2EntityManagerFactory") EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } + +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/BaseRepo.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/BaseRepo.java new file mode 100644 index 0000000000..81ff78efb2 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/BaseRepo.java @@ -0,0 +1,29 @@ +package com.baeldung.readonlytransactions.mysql.dao; + +import com.baeldung.readonlytransactions.utils.ExecutorUtils; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; + +public abstract class BaseRepo { + + protected long execQuery(Consumer function) { + AtomicLong count = new AtomicLong(0); + + ExecutorService executor = ExecutorUtils.createExecutor(10, 10); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + + scheduler.schedule(executor::shutdownNow, 5L, TimeUnit.SECONDS); + scheduler.shutdown(); + + while (!executor.isShutdown()) { + executor.execute(() -> function.accept(count)); + } + + return count.get(); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoJPA.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoJPA.java new file mode 100644 index 0000000000..727e88219f --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoJPA.java @@ -0,0 +1,36 @@ +package com.baeldung.readonlytransactions.mysql.dao; + +import org.hibernate.Session; + +import com.baeldung.readonlytransactions.mysql.entities.Book; + +import java.util.SplittableRandom; +import java.util.concurrent.atomic.AtomicLong; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +public class MyRepoJPA extends BaseRepo { + + private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa-unit"); + private SplittableRandom random = new SplittableRandom(); + + public long runQuery() { + return execQuery(this::runSql); + } + + private void runSql(AtomicLong count) { + if (Thread.interrupted()) { + return; + } + + EntityManager entityManager = entityManagerFactory.createEntityManager(); + Session session = entityManager.unwrap(Session.class); + session.setDefaultReadOnly(true); + entityManager.find(Book.class, 1L + random.nextLong(0, 1000000)); + count.incrementAndGet(); + entityManager.clear(); + } + +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoJdbc.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoJdbc.java new file mode 100644 index 0000000000..306bfd5f0c --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoJdbc.java @@ -0,0 +1,71 @@ +package com.baeldung.readonlytransactions.mysql.dao; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.SplittableRandom; +import java.util.concurrent.atomic.AtomicLong; + +public class MyRepoJdbc extends BaseRepo { + + static { + try { + Class.forName("com.mysql.cj.jdbc.Driver"); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + private HikariDataSource ds; + private SplittableRandom random = new SplittableRandom(); + + public MyRepoJdbc(boolean readOnly, boolean autocommit) { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:mysql://localhost/baeldung?useUnicode=true&characterEncoding=UTF-8"); + config.setUsername("baeldung"); + config.setPassword("baeldung"); + config.setReadOnly(readOnly); + config.setAutoCommit(autocommit); + ds = new HikariDataSource(config); + } + + private Connection getConnection() throws SQLException { + return ds.getConnection(); + } + + public long runQuery(Boolean autoCommit, Boolean readOnly) { + try { + return execQuery(count -> runSql(count, autoCommit, readOnly)); + } finally { + ds.close(); + } + } + + private void runSql(AtomicLong count, Boolean autoCommit, Boolean readOnly) { + if (Thread.interrupted()) { + return; + } + + try (Connection connect = getConnection(); PreparedStatement statement = connect.prepareStatement("select * from transactions where id = ?")) { + if (autoCommit != null) + connect.setAutoCommit(autoCommit); + + if (readOnly != null) + connect.setReadOnly(readOnly); + + statement.setLong(1, 1L + random.nextLong(0, 100000)); + ResultSet resultSet = statement.executeQuery(); + + if (autoCommit != null && !autoCommit) + connect.commit(); + + count.incrementAndGet(); + resultSet.close(); + } catch (Exception ignored) { + } + } +} \ No newline at end of file diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoSpring.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoSpring.java new file mode 100644 index 0000000000..387f5ec722 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/dao/MyRepoSpring.java @@ -0,0 +1,22 @@ +package com.baeldung.readonlytransactions.mysql.dao; + +import com.baeldung.readonlytransactions.mysql.spring.repositories.BookRepository; + +import java.util.SplittableRandom; + +public class MyRepoSpring extends BaseRepo { + + private SplittableRandom random = new SplittableRandom(); + private BookRepository repository; + + public MyRepoSpring(BookRepository repository) { + this.repository = repository; + } + + public long runQuery() { + return execQuery(count -> { + repository.get(1L + random.nextLong(0, 1000000)); + count.incrementAndGet(); + }); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/entities/Book.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/entities/Book.java new file mode 100644 index 0000000000..405cc9c2c2 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/entities/Book.java @@ -0,0 +1,44 @@ +package com.baeldung.readonlytransactions.mysql.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "book") +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + private String uuid; + + 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; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/Config.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/Config.java new file mode 100644 index 0000000000..abaa63b197 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/Config.java @@ -0,0 +1,77 @@ +package com.baeldung.readonlytransactions.mysql.spring; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.baeldung.readonlytransactions.mysql.dao.MyRepoSpring; +import com.baeldung.readonlytransactions.mysql.spring.entities.BookEntity; +import com.baeldung.readonlytransactions.mysql.spring.repositories.BookRepository; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +import java.util.Properties; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +@Configuration +@EnableJpaRepositories(basePackageClasses = Config.class, enableDefaultTransactions = false) +@EnableTransactionManagement +@EnableAspectJAutoProxy +public class Config { + + @Bean + public MyRepoSpring repoSpring(BookRepository repository) { + return new MyRepoSpring(repository); + } + + private DataSource dataSource(boolean readOnly, boolean isAutoCommit) { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:mysql://localhost/baeldung?useUnicode=true&characterEncoding=UTF-8"); + config.setUsername("baeldung"); + config.setPassword("baeldung"); + config.setReadOnly(readOnly); + config.setAutoCommit(isAutoCommit); + return new HikariDataSource(config); + } + + @Bean + public DataSource dataSource() { + return new RoutingDS(dataSource(false, false), dataSource(true, true)); + } + + @Bean + public EntityManagerFactory entityManagerFactory(DataSource dataSource) { + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setGenerateDdl(false); + + LocalContainerEntityManagerFactoryBean managerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + managerFactoryBean.setJpaVendorAdapter(vendorAdapter); + managerFactoryBean.setPackagesToScan(BookEntity.class.getPackage() + .getName()); + managerFactoryBean.setDataSource(dataSource); + + Properties properties = new Properties(); + + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect"); + properties.setProperty("hibernate.hbm2ddl.auto", "validate"); + + managerFactoryBean.setJpaProperties(properties); + managerFactoryBean.afterPropertiesSet(); + + return managerFactoryBean.getObject(); + } + + @Bean + public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } + +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReadOnlyContext.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReadOnlyContext.java new file mode 100644 index 0000000000..2933c8c4a9 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReadOnlyContext.java @@ -0,0 +1,26 @@ +package com.baeldung.readonlytransactions.mysql.spring; + +import java.util.concurrent.atomic.AtomicInteger; + +public class ReadOnlyContext { + + private static final ThreadLocal READ_ONLY_LEVEL = ThreadLocal.withInitial(() -> new AtomicInteger(0)); + + private ReadOnlyContext() { + } + + public static boolean isReadOnly() { + return READ_ONLY_LEVEL.get() + .get() > 0; + } + + public static void enter() { + READ_ONLY_LEVEL.get() + .incrementAndGet(); + } + + public static void exit() { + READ_ONLY_LEVEL.get() + .decrementAndGet(); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReadOnlyInterception.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReadOnlyInterception.java new file mode 100644 index 0000000000..30488970a8 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReadOnlyInterception.java @@ -0,0 +1,29 @@ +package com.baeldung.readonlytransactions.mysql.spring; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class ReadOnlyInterception { + + private static final Logger logger = LoggerFactory.getLogger(ReadOnlyInterception.class); + + @Around("@annotation(com.baeldung.readonlytransactions.mysql.spring.ReaderDS)") + public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable { + try { + ReadOnlyContext.enter(); + //Debug data source switch + logger.debug("-----------------------------Entering read only zone-----------------------------"); + return joinPoint.proceed(); + } finally { + logger.debug("-----------------------------Leaving read only zone------------------------------"); + ReadOnlyContext.exit(); + } + } + +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReaderDS.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReaderDS.java new file mode 100644 index 0000000000..312c65b3cf --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/ReaderDS.java @@ -0,0 +1,10 @@ +package com.baeldung.readonlytransactions.mysql.spring; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +public @interface ReaderDS { +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/RoutingDS.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/RoutingDS.java new file mode 100644 index 0000000000..36ce8a16e6 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/RoutingDS.java @@ -0,0 +1,35 @@ +package com.baeldung.readonlytransactions.mysql.spring; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +public class RoutingDS extends AbstractRoutingDataSource { + + private static final Logger logger = LoggerFactory.getLogger(RoutingDS.class); + + RoutingDS(DataSource writer, DataSource reader) { + + Map dataSources = new HashMap<>(); + dataSources.put("writer", writer); + dataSources.put("reader", reader); + + setTargetDataSources(dataSources); + } + + @Override + protected Object determineCurrentLookupKey() { + String dataSourceMode = ReadOnlyContext.isReadOnly() ? "reader" : "writer"; + + // Testing data source switch + logger.debug("-----------------------------Datasource: {} ---------------------------------", dataSourceMode); + + return dataSourceMode; + } + +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/entities/BookEntity.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/entities/BookEntity.java new file mode 100644 index 0000000000..87c8988a8d --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/entities/BookEntity.java @@ -0,0 +1,45 @@ +package com.baeldung.readonlytransactions.mysql.spring.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "book") +public class BookEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + private String uuid; + + 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; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} + diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/repositories/BookRepository.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/repositories/BookRepository.java new file mode 100644 index 0000000000..2cc61c016d --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/mysql/spring/repositories/BookRepository.java @@ -0,0 +1,21 @@ +package com.baeldung.readonlytransactions.mysql.spring.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.baeldung.readonlytransactions.mysql.spring.ReaderDS; +import com.baeldung.readonlytransactions.mysql.spring.entities.BookEntity; + +import javax.transaction.Transactional; + +public interface BookRepository extends JpaRepository { + + @ReaderDS + @Query("Select 1 from BookEntity t where t.id = ?1") + Long get(Long id); + + @Transactional + default BookEntity persist(BookEntity book) { + return this.save(book); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/utils/ExecutorUtils.java b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/utils/ExecutorUtils.java new file mode 100644 index 0000000000..60c306b3b8 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/java/com/baeldung/readonlytransactions/utils/ExecutorUtils.java @@ -0,0 +1,16 @@ +package com.baeldung.readonlytransactions.utils; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class ExecutorUtils { + + private ExecutorUtils() { + } + + public static ExecutorService createExecutor(int corePoolSize, int maximumPoolSize) { + return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.DiscardOldestPolicy()); + } +} diff --git a/persistence-modules/read-only-transactions/src/main/resources/META-INF/persistence.xml b/persistence-modules/read-only-transactions/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..37fb45ed49 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,23 @@ + + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.readonlytransactions.mysql.entities.Book + true + + + + + + + + + + + + diff --git a/persistence-modules/read-only-transactions/src/main/resources/logback.xml b/persistence-modules/read-only-transactions/src/main/resources/logback.xml new file mode 100644 index 0000000000..5d331c64b3 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - + %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/JPATransactionIntegrationTest.java b/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/JPATransactionIntegrationTest.java new file mode 100644 index 0000000000..a15651b273 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/JPATransactionIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.readonlytransactions; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.hibernate.Session; +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.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.readonlytransactions.h2.Config; +import com.baeldung.readonlytransactions.h2.Book; +import com.baeldung.readonlytransactions.mysql.spring.ReadOnlyInterception; + +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class, initializers = JPATransactionIntegrationTest.TestConfig.class, classes = { ReadOnlyInterception.class }) +class JPATransactionIntegrationTest { + + static class TestConfig implements ApplicationContextInitializer { + @Override + public void initialize(GenericApplicationContext applicationContext) { + new AnnotatedBeanDefinitionReader(applicationContext).register(Config.class); + } + } + + @Autowired + @Qualifier("h2EntityManagerFactory") + private EntityManagerFactory entityManagerFactory; + + @BeforeEach + void setUp() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + entityManager.getTransaction() + .begin(); + entityManager.createQuery("DELETE FROM Book") + .executeUpdate(); + + Book book = new Book(); + book.setName("Test 1"); + book.setUuid(UUID.randomUUID() + .toString()); + + entityManager.merge(book); + entityManager.getTransaction() + .commit(); + } + + @Test + void givenAEntityManagerDefinedAsReadOnly_whenCreatingATransaction_thenAReadOnlyTransactionShouldBeCreated() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + + entityManager.unwrap(Session.class) + .setDefaultReadOnly(true); + entityManager.getTransaction() + .begin(); + Book book = entityManager.find(Book.class, 1L); + entityManager.getTransaction() + .commit(); + entityManager.unwrap(Session.class) + .setDefaultReadOnly(false); + + assertNotNull(book); + } + +} diff --git a/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/SpringTransactionReadOnlyIntegrationTest.java b/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/SpringTransactionReadOnlyIntegrationTest.java new file mode 100644 index 0000000000..2f5fd66140 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/SpringTransactionReadOnlyIntegrationTest.java @@ -0,0 +1,72 @@ +package com.baeldung.readonlytransactions; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +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.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.readonlytransactions.h2.Config; +import com.baeldung.readonlytransactions.h2.Book; +import com.baeldung.readonlytransactions.h2.TransactionConfig; +import com.baeldung.readonlytransactions.h2.BookService; + +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class, initializers = SpringTransactionReadOnlyIntegrationTest.TestConfig.class, classes = { BookService.class }) +class SpringTransactionReadOnlyIntegrationTest { + + static class TestConfig implements ApplicationContextInitializer { + @Override + public void initialize(GenericApplicationContext applicationContext) { + AnnotatedBeanDefinitionReader beanDefinitionReader = new AnnotatedBeanDefinitionReader(applicationContext); + + beanDefinitionReader.register(Config.class); + beanDefinitionReader.register(TransactionConfig.class); + } + } + + @Autowired + @Qualifier("h2EntityManagerFactory") + private EntityManagerFactory entityManagerFactory; + + @Autowired + private BookService service; + + @BeforeEach + void setUp() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + entityManager.getTransaction() + .begin(); + entityManager.createQuery("DELETE FROM Book") + .executeUpdate(); + + Book book = new Book(); + book.setName("Test 1"); + book.setUuid(UUID.randomUUID() + .toString()); + + entityManager.merge(book); + entityManager.getTransaction() + .commit(); + } + + @Test + void givenThatSpringTransactionManagementIsEnabled_whenAMethodIsAnnotatedAsTransactionalReadOnly_thenSpringShouldTakeCareOfTheTransaction() { + Book book = service.getBookById(1L); + + assertNotNull(book); + } +} diff --git a/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/TransactionSetupIntegrationTest.java b/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/TransactionSetupIntegrationTest.java new file mode 100644 index 0000000000..9cbc22afe3 --- /dev/null +++ b/persistence-modules/read-only-transactions/src/test/java/com/baeldung/readonlytransactions/TransactionSetupIntegrationTest.java @@ -0,0 +1,106 @@ +package com.baeldung.readonlytransactions; + +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Disabled; +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.context.ApplicationContextInitializer; +import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.readonlytransactions.mysql.dao.MyRepoJPA; +import com.baeldung.readonlytransactions.mysql.dao.MyRepoJdbc; +import com.baeldung.readonlytransactions.mysql.dao.MyRepoSpring; +import com.baeldung.readonlytransactions.mysql.spring.Config; +import com.baeldung.readonlytransactions.mysql.spring.ReadOnlyInterception; +import com.baeldung.readonlytransactions.mysql.spring.entities.BookEntity; +import com.baeldung.readonlytransactions.mysql.spring.repositories.BookRepository; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Supplier; +import java.util.stream.Stream; + +// Needs to be run with Docker look at the readme file. +@Disabled +@ExtendWith(SpringExtension.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class, initializers = TransactionSetupIntegrationTest.TestConfig.class, classes = { ReadOnlyInterception.class }) +class TransactionSetupIntegrationTest { + + static class TestConfig implements ApplicationContextInitializer { + @Override + public void initialize(GenericApplicationContext applicationContext) { + new AnnotatedBeanDefinitionReader(applicationContext).register(Config.class); + } + } + + private static final Logger logger = LoggerFactory.getLogger(TransactionSetupIntegrationTest.class); + + @Autowired + private MyRepoSpring repoSpring; + + @Autowired + private BookRepository repository; + + @Test + void givenTheDifferentTransactionSetup_whenRunningAThroughputTest_thenWeCanObserveTheSystem() { + Map> jdbcConfigurations = new LinkedHashMap<>(); + + jdbcConfigurations.put("JPA: Session read only true and autocommit disabled", () -> new MyRepoJPA().runQuery()); + + jdbcConfigurations.put("Spring: Session read only and autocommit true", () -> repoSpring.runQuery()); + + jdbcConfigurations.put("JDBC: Global read only and autocommit enabled", () -> new MyRepoJdbc(true, true).runQuery(null, null)); + jdbcConfigurations.put("JDBC: Global read only false and autocommit enabled", () -> new MyRepoJdbc(false, true).runQuery(null, null)); + jdbcConfigurations.put("JDBC: Global read only true and autocommit disabled", () -> new MyRepoJdbc(true, false).runQuery(null, null)); + + jdbcConfigurations.put("JDBC: Session read only and autocommit disabled", () -> new MyRepoJdbc(false, false).runQuery(false, false)); + jdbcConfigurations.put("JDBC: Session read only and autocommit enabled", () -> new MyRepoJdbc(false, false).runQuery(true, true)); + jdbcConfigurations.put("JDBC: Session read only false and autocommit enabled", () -> new MyRepoJdbc(false, false).runQuery(false, true)); + jdbcConfigurations.put("JDBC: Session read only true and autocommit disabled", () -> new MyRepoJdbc(false, false).runQuery(true, false)); + + jdbcConfigurations.entrySet() + .stream() + .flatMap(entry -> { + Stream.Builder builder = Stream.builder(); + return builder.add(entry.getKey() + " Total: " + entry.getValue() + .get()) + .add(entry.getKey() + " Total: " + entry.getValue() + .get()) + .add(entry.getKey() + " Total: " + entry.getValue() + .get()) + .build(); + }) + .collect(toList()) + .stream() + .peek(o -> logger.info("--------------------------------------------------")) + .forEach(logger::info); + } + + @Test + void givenThatSpringTransactionManagementIsEnabled_whenAMethodIsAnnotatedAsTransactionalReadOnly_thenSpringShouldTakeCareOfTheTransaction() { + Long id = repository.get(2L); + + assertNotNull(id); + } + + @Test + void givenThatSpringTransactionManagementIsEnabled_whenAMethodIsAnnotatedAsTransactional_thenSpringShouldTakeCareOfTheTransaction() { + BookEntity book = new BookEntity(); + book.setName("Persistence test"); + book.setUuid(UUID.randomUUID() + .toString()); + book = repository.persist(book); + + assertNotNull(book.getId()); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-boot-mysql/pom.xml b/persistence-modules/spring-boot-mysql/pom.xml index ed3f7d9279..239378c7b1 100644 --- a/persistence-modules/spring-boot-mysql/pom.xml +++ b/persistence-modules/spring-boot-mysql/pom.xml @@ -39,7 +39,7 @@ - 8.0.12 + 8.0.23 \ No newline at end of file diff --git a/persistence-modules/spring-boot-mysql/src/main/resources/application.yml b/persistence-modules/spring-boot-mysql/src/main/resources/application.yml index 5404555d49..f660ab4759 100644 --- a/persistence-modules/spring-boot-mysql/src/main/resources/application.yml +++ b/persistence-modules/spring-boot-mysql/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:mysql://localhost:3306/test?useLegacyDatetimeCode=false + url: jdbc:mysql://localhost:3306/test? username: root password: @@ -9,6 +9,6 @@ spring: ddl-auto: update properties: hibernate: - dialect: org.hibernate.dialect.MySQL5Dialect + dialect: org.hibernate.dialect.MySQL8Dialect jdbc: time_zone: UTC \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-2/src/main/resources/application-oracle-pooling-basic.properties b/persistence-modules/spring-boot-persistence-2/src/main/resources/application-oracle-pooling-basic.properties index 9de2ee476b..39872e9a00 100644 --- a/persistence-modules/spring-boot-persistence-2/src/main/resources/application-oracle-pooling-basic.properties +++ b/persistence-modules/spring-boot-persistence-2/src/main/resources/application-oracle-pooling-basic.properties @@ -23,12 +23,12 @@ spring.datasource.tomcat.minIdle=5 # UCP settings #Note: These properties require JDBC version 21.0.0.0 -spring.datasource.ucp.connection-factory-class-name=oracle.jdbc.pool.OracleDataSource -spring.datasource.ucp.sql-for-validate-connection=select * from dual -spring.datasource.ucp.connection-pool-name=UcpPoolBooks -spring.datasource.ucp.initial-pool-size=5 -spring.datasource.ucp.min-pool-size=5 -spring.datasource.ucp.max-pool-size=10 +spring.datasource.oracleucp.connection-factory-class-name=oracle.jdbc.pool.OracleDataSource +spring.datasource.oracleucp.sql-for-validate-connection=select * from dual +spring.datasource.oracleucp.connection-pool-name=UcpPoolBooks +spring.datasource.oracleucp.initial-pool-size=5 +spring.datasource.oracleucp.min-pool-size=5 +spring.datasource.oracleucp.max-pool-size=10 # JPA settings spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java index cf418b2cf4..aa448bc44a 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java @@ -26,4 +26,5 @@ public class SpringOraclePoolingApplicationOracleUCPLiveTest { assertTrue(dataSource instanceof oracle.ucp.jdbc.UCPDataSource); } + } diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/.gitignore b/persistence-modules/spring-boot-persistence-mongodb-2/.gitignore new file mode 100644 index 0000000000..2d513a0101 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/.gitignore @@ -0,0 +1,2 @@ +/.idea/ +/target/ diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/README.md b/persistence-modules/spring-boot-persistence-mongodb-2/README.md new file mode 100644 index 0000000000..ba27436109 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/README.md @@ -0,0 +1,5 @@ +# Relevant Articles + +- [Logging MongoDB Queries with Spring Boot](https://www.baeldung.com/spring-boot-mongodb-logging) +- [Configure MongoDB Collection Name for a Class in Spring Data](https://www.baeldung.com/spring-data-mongodb-collection-name) +- More articles: [[<--prev]](../spring-boot-persistence-mongodb) diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml b/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml new file mode 100644 index 0000000000..a172c28a80 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + spring-boot-persistence-mongodb-2 + spring-boot-persistence-mongodb-2 + war + This is simple boot application for Spring boot persistence mongodb test + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + ${embed.mongo.version} + test + + + + + 3.2.6 + + + diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/SpringBootPersistenceApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/SpringBootPersistenceApplication.java new file mode 100644 index 0000000000..2dff3f37df --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/SpringBootPersistenceApplication.java @@ -0,0 +1,13 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootPersistenceApplication { + + public static void main(String ... args) { + SpringApplication.run(SpringBootPersistenceApplication.class, args); + } + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/Naming.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/Naming.java new file mode 100644 index 0000000000..9808ecccb6 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/Naming.java @@ -0,0 +1,35 @@ +package com.baeldung.boot.collection.name; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.util.ParsingUtils; +import org.springframework.util.StringUtils; + +public class Naming { + public static void main(String[] args) { + String r = new Naming().fix(args[0]); + System.out.println(r); + } + + public String fix(String name) { + List parts = ParsingUtils.splitCamelCaseToLower(name); + List result = new ArrayList<>(); + + for (String part : parts) { + if (StringUtils.hasText(part)) { + result.add(part); + } + } + + return StringUtils.collectionToDelimitedString(result, "_"); + } + + public String convert(Class type) { + return fix(type.getSimpleName()); + } + + public String convert(Object instance) { + return convert(instance.getClass()); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/SpringBootCollectionNameApplication.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/SpringBootCollectionNameApplication.java new file mode 100644 index 0000000000..e4157b6a53 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/SpringBootCollectionNameApplication.java @@ -0,0 +1,21 @@ +package com.baeldung.boot.collection.name; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +@PropertySource("classpath:boot.collection.name/app.properties") +@EnableMongoRepositories(basePackages = { "com.baeldung.boot.collection.name" }) +public class SpringBootCollectionNameApplication { + public static void main(String... args) { + SpringApplication.run(SpringBootCollectionNameApplication.class, args); + } + + @Bean + public Naming naming() { + return new Naming(); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/CompilationRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/CompilationRepository.java new file mode 100644 index 0000000000..3f83ad4548 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/CompilationRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.boot.collection.name.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.collection.name.data.Compilation; + +public interface CompilationRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicAlbumRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicAlbumRepository.java new file mode 100644 index 0000000000..98709361d7 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicAlbumRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.boot.collection.name.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.collection.name.data.MusicAlbum; + +public interface MusicAlbumRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicTrackRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicTrackRepository.java new file mode 100644 index 0000000000..0964a8de00 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/MusicTrackRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.boot.collection.name.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.collection.name.data.MusicTrack; + +public interface MusicTrackRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/StoreRepository.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/StoreRepository.java new file mode 100644 index 0000000000..b446a7d98d --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/dao/StoreRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.boot.collection.name.dao; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.baeldung.boot.collection.name.data.Store; + +public interface StoreRepository extends MongoRepository { + +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Compilation.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Compilation.java new file mode 100644 index 0000000000..ce081acf25 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Compilation.java @@ -0,0 +1,36 @@ +package com.baeldung.boot.collection.name.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Compilation { + @Id + private String id; + + private String name; + + public Compilation() { + } + + public Compilation(String name) { + super(); + this.name = name; + } + + 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; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicAlbum.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicAlbum.java new file mode 100644 index 0000000000..ce2e084504 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicAlbum.java @@ -0,0 +1,48 @@ +package com.baeldung.boot.collection.name.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("albums") +public class MusicAlbum { + @Id + private String id; + + private String name; + + private String artist; + + public MusicAlbum() { + + } + + public MusicAlbum(String name, String artist) { + super(); + this.name = name; + this.artist = artist; + } + + 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 getArtist() { + return artist; + } + + public void setArtist(String artist) { + this.artist = artist; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicTrack.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicTrack.java new file mode 100644 index 0000000000..39ce3994bb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/MusicTrack.java @@ -0,0 +1,50 @@ +package com.baeldung.boot.collection.name.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("#{@naming.fix('MusicTrack')}") +public class MusicTrack { + @Id + private String id; + + private String name; + + private String artist; + + public MusicTrack() { + } + + public MusicTrack(String name, String artist) { + this.name = name; + this.artist = artist; + } + + public MusicTrack(String name) { + this.name = name; + } + + 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 getArtist() { + return artist; + } + + public void setArtist(String artist) { + this.artist = artist; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Store.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Store.java new file mode 100644 index 0000000000..83f5017a13 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/data/Store.java @@ -0,0 +1,36 @@ +package com.baeldung.boot.collection.name.data; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("store-#{@environment.getProperty('collection.suffix')}") +public class Store { + @Id + private String id; + + private String name; + + public Store() { + } + + public Store(String name) { + super(); + this.name = name; + } + + 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; + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/service/MusicStoreService.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/service/MusicStoreService.java new file mode 100644 index 0000000000..6083e3d0c3 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/service/MusicStoreService.java @@ -0,0 +1,62 @@ +package com.baeldung.boot.collection.name.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.boot.collection.name.dao.CompilationRepository; +import com.baeldung.boot.collection.name.dao.MusicAlbumRepository; +import com.baeldung.boot.collection.name.dao.MusicTrackRepository; +import com.baeldung.boot.collection.name.dao.StoreRepository; +import com.baeldung.boot.collection.name.data.Compilation; +import com.baeldung.boot.collection.name.data.MusicAlbum; +import com.baeldung.boot.collection.name.data.MusicTrack; +import com.baeldung.boot.collection.name.data.Store; + +@Service +public class MusicStoreService { + @Autowired + private MusicAlbumRepository albumRepository; + + @Autowired + private CompilationRepository compilationRepository; + + @Autowired + private StoreRepository storeRepository; + + @Autowired + private MusicTrackRepository trackRepository; + + public MusicAlbum add(MusicAlbum item) { + return albumRepository.save(item); + } + + public List getAlbumList() { + return albumRepository.findAll(); + } + + public Compilation add(Compilation item) { + return compilationRepository.save(item); + } + + public List getCompilationList() { + return compilationRepository.findAll(); + } + + public Store add(Store item) { + return storeRepository.save(item); + } + + public List getStoreList() { + return storeRepository.findAll(); + } + + public MusicTrack add(MusicTrack item) { + return trackRepository.save(item); + } + + public List getTrackList() { + return trackRepository.findAll(); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/CollectionController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/CollectionController.java new file mode 100644 index 0000000000..2efca361b9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/CollectionController.java @@ -0,0 +1,24 @@ +package com.baeldung.boot.collection.name.web; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +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.mongodb.DBObject; + +@RestController +@RequestMapping("/collection") +public class CollectionController { + @Autowired + private MongoTemplate mongo; + + @GetMapping("/{name}") + public List get(@PathVariable String name) { + return mongo.findAll(DBObject.class, name); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/MusicStoreController.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/MusicStoreController.java new file mode 100644 index 0000000000..8c510121c2 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/boot/collection/name/web/MusicStoreController.java @@ -0,0 +1,63 @@ +package com.baeldung.boot.collection.name.web; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.boot.collection.name.data.Compilation; +import com.baeldung.boot.collection.name.data.MusicAlbum; +import com.baeldung.boot.collection.name.data.MusicTrack; +import com.baeldung.boot.collection.name.data.Store; +import com.baeldung.boot.collection.name.service.MusicStoreService; + +@RestController +@RequestMapping("/music") +public class MusicStoreController { + @Autowired + private MusicStoreService service; + + @PostMapping("/album") + public MusicAlbum post(@RequestBody MusicAlbum item) { + return service.add(item); + } + + @GetMapping("/album") + public List getAlbumList() { + return service.getAlbumList(); + } + + @PostMapping("/compilation") + public Compilation post(@RequestBody Compilation item) { + return service.add(item); + } + + @GetMapping("/compilation") + public List getCompilationList() { + return service.getCompilationList(); + } + + @PostMapping("/store") + public Store post(@RequestBody Store item) { + return service.add(item); + } + + @GetMapping("/store") + public List getStoreList() { + return service.getStoreList(); + } + + @PostMapping("/track") + public MusicTrack post(@RequestBody MusicTrack item) { + return service.add(item); + } + + @GetMapping("/track") + public List getTrackList() { + return service.getTrackList(); + } +} 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-2/src/main/java/com/baeldung/logging/model/Book.java similarity index 100% rename from persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/logging/model/Book.java rename to persistence-modules/spring-boot-persistence-mongodb-2/src/main/java/com/baeldung/logging/model/Book.java diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/application.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/application.properties new file mode 100644 index 0000000000..9dbc261896 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.application.name=spring-boot-persistence-mongodb-2 diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.collection.name/app.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.collection.name/app.properties new file mode 100644 index 0000000000..98945a76e1 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/main/resources/boot.collection.name/app.properties @@ -0,0 +1 @@ +collection.suffix=db diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/collection/name/service/MusicStoreServiceIntegrationTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/collection/name/service/MusicStoreServiceIntegrationTest.java new file mode 100644 index 0000000000..eda8b8aafb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/boot/collection/name/service/MusicStoreServiceIntegrationTest.java @@ -0,0 +1,81 @@ +package com.baeldung.boot.collection.name.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.collection.name.data.Compilation; +import com.baeldung.boot.collection.name.data.MusicAlbum; +import com.baeldung.boot.collection.name.data.MusicTrack; +import com.baeldung.boot.collection.name.data.Store; + +@SpringBootTest +@DirtiesContext +@RunWith(SpringRunner.class) +public class MusicStoreServiceIntegrationTest { + @Autowired + private MusicStoreService service; + + @Autowired + private MongoTemplate mongoDb; + + @Test + public void givenAnnotation_whenSearchingByCollectionName_thenFound() { + List list = service.getCompilationList(); + int sizeBefore = list.size(); + + service.add(new Compilation("Spring Hits")); + + list = mongoDb.findAll(Compilation.class, "compilation"); + int sizeAfter = list.size(); + + assertThat(sizeAfter - sizeBefore).isEqualTo(1); + } + + @Test + public void givenAnnotationWithValue_whenSearchingByCollectionName_thenFound() { + List list = service.getAlbumList(); + int sizeBefore = list.size(); + + service.add(new MusicAlbum("Album 1", "Artist A")); + + list = mongoDb.findAll(MusicAlbum.class, "albums"); + int sizeAfter = list.size(); + + assertThat(sizeAfter - sizeBefore).isEqualTo(1); + } + + @Test + public void givenAnnotationWithSpELEnvironment_whenSearchingByCollectionName_thenFound() { + List list = service.getStoreList(); + int sizeBefore = list.size(); + + service.add(new Store("Store A")); + + list = mongoDb.findAll(Store.class, "store-db"); + int sizeAfter = list.size(); + + assertThat(sizeAfter - sizeBefore).isEqualTo(1); + } + + @Test + public void givenAnnotationWithSpELBean_whenSearchingByCollectionName_thenFound() { + List list = service.getTrackList(); + int sizeBefore = list.size(); + + service.add(new MusicTrack("Track 1")); + + list = mongoDb.findAll(MusicTrack.class, "music_track"); + int sizeAfter = list.size(); + + assertThat(sizeAfter - sizeBefore).isEqualTo(1); + } +} diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/GroupByAuthor.java similarity index 100% rename from persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/GroupByAuthor.java rename to persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/GroupByAuthor.java diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/LoggingUnitTest.java similarity index 97% rename from persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java rename to persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/LoggingUnitTest.java index 577e039176..00def53566 100644 --- a/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/logging/LoggingUnitTest.java +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/java/com/baeldung/logging/LoggingUnitTest.java @@ -21,6 +21,7 @@ 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 org.springframework.util.SocketUtils; import com.baeldung.logging.model.Book; import com.mongodb.client.MongoClients; @@ -34,7 +35,7 @@ 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" }) +@TestPropertySource(properties = { "logging.level.org.springframework.data.mongodb.core.MongoTemplate=INFO" }) public class LoggingUnitTest { private static final String CONNECTION_STRING = "mongodb://%s:%d"; @@ -50,7 +51,7 @@ public class LoggingUnitTest { @BeforeEach void setup() throws Exception { String ip = "localhost"; - int port = 27017; + int port = Network.freeServerPort(Network.getLocalHost()); ImmutableMongodConfig mongodConfig = MongodConfig.builder() .version(Version.Main.PRODUCTION) diff --git a/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/application.properties b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/application.properties new file mode 100644 index 0000000000..a5b5fb9804 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/application.properties @@ -0,0 +1 @@ +spring.mongodb.embedded.version=4.4.9 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-1/src/test/resources/logback-test.xml b/persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/logback-test.xml similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/resources/logback-test.xml rename to persistence-modules/spring-boot-persistence-mongodb-2/src/test/resources/logback-test.xml diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md index 91dd8718e1..8e9399f076 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) +- More articles: [[next-->]](../spring-boot-persistence-mongodb-2) diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/persistence/model/Foo.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/persistence/model/Foo.java index eec15c5e56..ac79653b2b 100644 --- a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/persistence/model/Foo.java +++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/persistence/model/Foo.java @@ -13,6 +13,9 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedNativeQueries; import javax.persistence.NamedNativeQuery; +import javax.persistence.NamedStoredProcedureQuery; +import javax.persistence.ParameterMode; +import javax.persistence.StoredProcedureParameter; import org.hibernate.envers.Audited; @@ -20,6 +23,20 @@ import org.hibernate.envers.Audited; @NamedNativeQuery(name = "callGetAllFoos", query = "CALL GetAllFoos()", resultClass = Foo.class), @NamedNativeQuery(name = "callGetFoosByName", query = "CALL GetFoosByName(:fooName)", resultClass = Foo.class) }) +@NamedStoredProcedureQuery( + name="GetAllFoos", + procedureName="GetAllFoos", + resultClasses = { Foo.class } + ) +@NamedStoredProcedureQuery( + name="GetFoosByName", + procedureName="GetFoosByName", + resultClasses = { Foo.class }, + parameters={ + @StoredProcedureParameter(name="fooName", type=String.class, mode=ParameterMode.IN) + } + ) + @Entity @Audited // @Proxy(lazy = false) diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java index 8bf33c4110..f6dedfc6de 100644 --- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java +++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java @@ -1,10 +1,14 @@ package com.baeldung.persistence.service; -import java.util.List; - import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.junit.Assert.assertEquals; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.StoredProcedureQuery; + import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -17,6 +21,7 @@ import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @@ -38,8 +43,15 @@ public class FooStoredProceduresLiveTest { private Session session; + @Autowired + @Qualifier("jpaEntityManager") + private EntityManagerFactory entityManagerFactory; + + private EntityManager entityManager; + @Before public final void before() { + entityManager = entityManagerFactory.createEntityManager(); session = sessionFactory.openSession(); Assume.assumeTrue(getAllFoosExists()); Assume.assumeTrue(getFoosByNameExists()); @@ -70,6 +82,7 @@ public class FooStoredProceduresLiveTest { @After public final void after() { session.close(); + entityManager.close(); } @Test @@ -94,6 +107,15 @@ public class FooStoredProceduresLiveTest { LOGGER.info("getAllFoos() NamedQuery result : {}", foo.getName()); } assertEquals(allFoos2.size(), fooService.findAll().size()); + + StoredProcedureQuery spQuery = + entityManager.createNamedStoredProcedureQuery("GetAllFoos"); + List allFoos3 = spQuery.getResultList(); + for (Foo foo : allFoos3) { + LOGGER.info("getAllFoos() StoredProcedureQuery result : {}", foo.getName()); + } + assertEquals(allFoos3.size(), fooService.findAll().size()); + } @Test @@ -116,6 +138,15 @@ public class FooStoredProceduresLiveTest { for (Foo foo : allFoosByName2) { LOGGER.info("getFoosByName() using Native Query : found => {}", foo.toString()); } - + + StoredProcedureQuery spQuery = entityManager. + createNamedStoredProcedureQuery("GetFoosByName") + .setParameter("fooName", "NewFooName"); + List allFoosByName3 = spQuery.getResultList(); + assertEquals(1, allFoosByName3.size()); + for (Foo foo : allFoosByName3) { + LOGGER.info("getFoosByName() using StoredProcedureQuery : found => {}", foo.toString()); + assertEquals("NewFooName", foo.getName()); + } } } diff --git a/persistence-modules/spring-data-jpa-query-3/README.md b/persistence-modules/spring-data-jpa-query-3/README.md index 246b6ebf3d..268bce96ca 100644 --- a/persistence-modules/spring-data-jpa-query-3/README.md +++ b/persistence-modules/spring-data-jpa-query-3/README.md @@ -4,6 +4,8 @@ This module contains articles about querying data using Spring Data JPA. ### Relevant Articles: - [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date) +- [JPA and Hibernate – Criteria vs. JPQL vs. HQL Query](https://www.baeldung.com/jpql-hql-criteria-query) +- [Joining Tables With Spring Data JPA Specifications](https://www.baeldung.com/spring-jpa-joining-tables) - More articles: [[<-- prev]](../spring-data-jpa-query-2) ### Eclipse Config diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java new file mode 100644 index 0000000000..a511686f1b --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/entity/Employee.java @@ -0,0 +1,18 @@ +package com.baeldung.spring.data.jpa.entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Employee { + + @Id + @GeneratedValue + private Integer id; + + private String name; + + private Long salary; + +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java new file mode 100644 index 0000000000..70e699ebeb --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java @@ -0,0 +1,57 @@ +package com.baeldung.spring.data.jpa.query.specifications.join; + +import javax.persistence.*; + +import java.util.List; + +@Entity +public class Author { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String firstName; + + private String lastName; + + @OneToMany(cascade = CascadeType.ALL) + private List books; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + 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 List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } + + @Override + public String toString() { + return "Author{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", books=" + books + '}'; + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java new file mode 100644 index 0000000000..73d0cd6c01 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java @@ -0,0 +1,24 @@ +package com.baeldung.spring.data.jpa.query.specifications.join; + +import org.springframework.data.jpa.domain.Specification; + +import javax.persistence.criteria.*; + +public class AuthorSpecifications { + + public static Specification hasFirstNameLike(String name) { + return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("firstName"), "%" + name + "%"); + } + + public static Specification hasLastName(String name) { + return (root, query, cb) -> cb.equal(root.get("lastName"), name); + } + + public static Specification hasBookWithTitle(String bookTitle) { + return (root, query, criteriaBuilder) -> { + Join authorsBook = root.join("books"); + return criteriaBuilder.equal(authorsBook.get("title"), bookTitle); + }; + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java new file mode 100644 index 0000000000..67fe86b8b3 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.jpa.query.specifications.join; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface AuthorsRepository extends JpaRepository, JpaSpecificationExecutor { +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java new file mode 100644 index 0000000000..3d658ca107 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.data.jpa.query.specifications.join; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String title; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public String toString() { + return "Book{" + "id=" + id + ", title='" + title + '\'' + '}'; + } +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java new file mode 100644 index 0000000000..85d1a1b324 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/repository/EmployeeRepository.java @@ -0,0 +1,40 @@ +package com.baeldung.spring.data.jpa.repository; + +import com.baeldung.spring.data.jpa.entity.Employee; +import java.util.List; +import net.bytebuddy.TypeCache.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface EmployeeRepository extends JpaRepository { + + @Query(value = "SELECT e FROM Employee e") + List findAllEmployees(Sort sort); + + @Query("SELECT e FROM Employee e WHERE e.salary = ?1") + Employee findAllEmployeesWithSalary(Long salary); + + @Query("SELECT e FROM Employee e WHERE e.name = ?1 and e.salary = ?2") + Employee findUserByNameAndSalary(String name, Long salary); + + @Query( + value = "SELECT * FROM Employee e WHERE e.salary = ?1", + nativeQuery = true + ) + Employee findUserBySalaryNative(Long salary); + + @Query("SELECT e FROM Employee e WHERE e.name = :name and e.salary = :salary") + Employee findUserByEmployeeNameAndSalaryNamedParameters( + @Param("name") String employeeName, + @Param("salary") Long employeeSalary); + + @Query( + value = "SELECT * FROM Employee e WHERE e.name = :name and e.salary = :salary", + nativeQuery = true + ) + Employee findUserByNameAndSalaryNamedParamsNative( + @Param("name") String employeeName, + @Param("salary") Long employeeSalary); + +} diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java new file mode 100644 index 0000000000..27db09d11c --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java @@ -0,0 +1,80 @@ +package com.baeldung.spring.data.jpa.query.specifications.join; + +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.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Arrays; +import java.util.List; + +import static com.baeldung.spring.data.jpa.query.specifications.join.AuthorSpecifications.*; +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@DataJpaTest +public class SpecificationsJoinIntegrationTest { + + @Autowired + private AuthorsRepository repository; + + @Before + public void beforeEach() { + saveTestData(); + } + + @Test + public void whenSearchingByLastName_thenOneAuthorIsReturned() { + + List authors = repository.findAll(hasLastName("Martin")); + + assertThat(authors).hasSize(1); + } + + @Test + public void whenSearchingByLastNameAndFirstNameLike_thenOneAuthorIsReturned() { + + Specification specification = hasLastName("Martin").and(hasFirstNameLike("Robert")); + + List authors = repository.findAll(specification); + + assertThat(authors).hasSize(1); + } + + @Test + public void whenSearchingByBookTitle_thenOneAuthorIsReturned() { + + Specification specification = hasBookWithTitle("Clean Code"); + + List authors = repository.findAll(specification); + + assertThat(authors).hasSize(1); + } + + @Test + public void whenSearchingByBookTitleAndAuthorName_thenOneAuthorIsReturned() { + + Specification specification = hasLastName("Martin").and(hasBookWithTitle("Clean Code")); + + List authors = repository.findAll(specification); + + assertThat(authors).hasSize(1); + } + + private void saveTestData() { + Author uncleBob = new Author(); + uncleBob.setFirstName("Robert"); + uncleBob.setLastName("Martin"); + + Book book1 = new Book(); + book1.setTitle("Clean Code"); + Book book2 = new Book(); + book2.setTitle("Clean Architecture"); + + uncleBob.setBooks(Arrays.asList(book1, book2)); + repository.save(uncleBob); + } +} diff --git a/persistence-modules/spring-data-mongodb/README.md b/persistence-modules/spring-data-mongodb/README.md index acc978c68e..7dd0a82def 100644 --- a/persistence-modules/spring-data-mongodb/README.md +++ b/persistence-modules/spring-data-mongodb/README.md @@ -11,6 +11,7 @@ - [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations) - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) - [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions) +- [Return Only Specific Fields for a Query in Spring Data MongoDB](https://www.baeldung.com/mongodb-return-specific-fields) ## Spring Data MongoDB Live Testing diff --git a/persistence-modules/spring-data-mongodb/pom.xml b/persistence-modules/spring-data-mongodb/pom.xml index ef5a0f0550..afb5e8b9c1 100644 --- a/persistence-modules/spring-data-mongodb/pom.xml +++ b/persistence-modules/spring-data-mongodb/pom.xml @@ -73,6 +73,12 @@ querydsl-apt ${querydsl.version} + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + ${embed.mongo.version} + test + @@ -103,6 +109,7 @@ 4.1.0 3.2.0.RELEASE 4.0.5 + 3.2.6 \ No newline at end of file diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/InStock.java b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/InStock.java new file mode 100644 index 0000000000..6f57808ab0 --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/InStock.java @@ -0,0 +1,46 @@ +package com.baeldung.projection.model; + +import java.util.Objects; + +public class InStock { + + private String wareHouse; + private Integer quantity; + + public InStock(String wareHouse, int quantity) { + this.wareHouse = wareHouse; + this.quantity = quantity; + } + + public String getWareHouse() { + return wareHouse; + } + + public void setWareHouse(String wareHouse) { + this.wareHouse = wareHouse; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + InStock inStock = (InStock) o; + return Objects.equals(wareHouse, inStock.wareHouse) && Objects.equals(quantity, inStock.quantity); + } + + @Override + public int hashCode() { + return Objects.hash(wareHouse, quantity); + } + +} diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/Inventory.java b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/Inventory.java new file mode 100644 index 0000000000..0f4cf6b814 --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/Inventory.java @@ -0,0 +1,71 @@ +package com.baeldung.projection.model; + +import java.util.List; +import java.util.Objects; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.MongoId; + +@Document(collection = "inventory") +public class Inventory { + + @Id + private String id; + private String item; + private String status; + private Size size; + private List inStock; + + public String getId() { + return id; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Size getSize() { + return size; + } + + public void setSize(Size size) { + this.size = size; + } + + public List getInStock() { + return inStock; + } + + public void setInStock(List inStock) { + this.inStock = inStock; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Inventory inventory = (Inventory) o; + return Objects.equals(id, inventory.id) && Objects.equals(item, inventory.item) && Objects.equals(status, inventory.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, item, status); + } + +} diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/Size.java b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/Size.java new file mode 100644 index 0000000000..54af8f09f7 --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/model/Size.java @@ -0,0 +1,56 @@ +package com.baeldung.projection.model; + +import java.util.Objects; + +public class Size { + + private Double height; + private Double width; + private String uom; + + public Size(Double height, Double width, String uom) { + this.height = height; + this.width = width; + this.uom = uom; + } + + public Double getHeight() { + return height; + } + + public void setHeight(Double height) { + this.height = height; + } + + public Double getWidth() { + return width; + } + + public void setWidth(Double width) { + this.width = width; + } + + public String getUom() { + return uom; + } + + public void setUom(String uom) { + this.uom = uom; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Size size = (Size) o; + return Objects.equals(height, size.height) && Objects.equals(width, size.width) && Objects.equals(uom, size.uom); + } + + @Override + public int hashCode() { + return Objects.hash(height, width, uom); + } + +} diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/repository/InventoryRepository.java b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/repository/InventoryRepository.java new file mode 100644 index 0000000000..66b4ef02d5 --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/projection/repository/InventoryRepository.java @@ -0,0 +1,33 @@ +package com.baeldung.projection.repository; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; + +import com.baeldung.projection.model.Inventory; + +public interface InventoryRepository extends MongoRepository { + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1 }") + List findByStatusIncludeItemAndStatusFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, '_id' : 0 }") + List findByStatusIncludeItemAndStatusExcludeIdFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'status' : 0, 'inStock' : 0 }") + List findByStatusIncludeAllButStatusAndStockFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'size.uom': 1 }") + List findByStatusIncludeEmbeddedFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'size.uom': 0 }") + List findByStatusExcludeEmbeddedFields(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'inStock.quantity': 1 }") + List findByStatusIncludeEmbeddedFieldsInArray(String status); + + @Query(value = "{ 'status' : ?0 }", fields = "{ 'item' : 1, 'status' : 1, 'inStock': { $slice: -1 } }") + List findByStatusIncludeEmbeddedFieldsLastElementInArray(String status); + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/AbstractTestProjection.java b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/AbstractTestProjection.java new file mode 100644 index 0000000000..b197ada7aa --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/AbstractTestProjection.java @@ -0,0 +1,49 @@ +package com.baeldung.projection; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.baeldung.projection.model.InStock; +import com.baeldung.projection.model.Inventory; +import com.baeldung.projection.model.Size; + +abstract class AbstractTestProjection { + + public List getInventories() { + Inventory journal = new Inventory(); + journal.setItem("journal"); + journal.setStatus("A"); + journal.setSize(new Size(14.0, 21.0, "cm")); + journal.setInStock(Collections.singletonList(new InStock("A", 5))); + + Inventory notebook = new Inventory(); + notebook.setItem("notebook"); + notebook.setStatus("A"); + notebook.setSize(new Size(8.5, 11.0, "in")); + notebook.setInStock(Collections.singletonList(new InStock("C", 5))); + + Inventory paper = new Inventory(); + paper.setItem("paper"); + paper.setStatus("D"); + paper.setSize(new Size(8.5, 11.0, "in")); + paper.setInStock(Collections.singletonList(new InStock("A", 60))); + + return Arrays.asList(journal, notebook, paper); + } + + abstract void whenIncludeFields_thenOnlyIncludedFieldsAreNotNull(); + + abstract void whenIncludeFieldsAndExcludeOtherFields_thenOnlyExcludedFieldsAreNull(); + + abstract void whenIncludeAllButExcludeSomeFields_thenOnlyExcludedFieldsAreNull(); + + abstract void whenIncludeEmbeddedFields_thenEmbeddedFieldsAreNotNull(); + + abstract void whenExcludeEmbeddedFields_thenEmbeddedFieldsAreNull(); + + abstract void whenIncludeEmbeddedFieldsInArray_thenEmbeddedFieldsInArrayAreNotNull(); + + abstract void whenIncludeEmbeddedFieldsSliceInArray_thenArrayLengthEqualToSlice(); + +} diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/MongoTemplateProjectionUnitTest.java b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/MongoTemplateProjectionUnitTest.java new file mode 100644 index 0000000000..1cd6415a1b --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/MongoTemplateProjectionUnitTest.java @@ -0,0 +1,223 @@ +package com.baeldung.projection; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; + +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.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.projection.config.ProjectionConfig; +import com.baeldung.projection.model.InStock; +import com.baeldung.projection.model.Inventory; +import com.baeldung.projection.model.Size; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = ProjectionConfig.class) +public class MongoTemplateProjectionUnitTest extends AbstractTestProjection { + + @Autowired + private MongoTemplate mongoTemplate; + + @BeforeEach + void setup() { + List inventoryList = getInventories(); + + mongoTemplate.insert(inventoryList, Inventory.class); + } + + @Test + void whenIncludeFields_thenOnlyIncludedFieldsAreNotNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getId()); + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeFieldsAndExcludeOtherFields_thenOnlyExcludedFieldsAreNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .exclude("_id"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getId()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeAllButExcludeSomeFields_thenOnlyExcludedFieldsAreNull() { + Query query = new Query(); + query.fields() + .exclude("status") + .exclude("inStock"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getInStock()); + assertNull(i.getStatus()); + }); + } + + @Test + void whenIncludeEmbeddedFields_thenEmbeddedFieldsAreNotNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .include("size.uom"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNotNull(i.getSize() + .getUom()); + assertNull(i.getSize() + .getHeight()); + assertNull(i.getSize() + .getWidth()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenExcludeEmbeddedFields_thenEmbeddedFieldsAreNull() { + Query query = new Query(); + query.fields() + .exclude("size.uom"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getSize() + .getUom()); + assertNotNull(i.getSize() + .getHeight()); + assertNotNull(i.getSize() + .getWidth()); + assertNotNull(i.getInStock()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsInArray_thenEmbeddedFieldsInArrayAreNotNull() { + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .include("inStock.quantity"); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + i.getInStock() + .forEach(stock -> { + assertNull(stock.getWareHouse()); + assertNotNull(stock.getQuantity()); + }); + assertNull(i.getSize()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsSliceInArray_thenArrayLengthEqualToSlice() { + Inventory postcard = new Inventory(); + postcard.setItem("postcard"); + postcard.setStatus("A"); + postcard.setSize(new Size(10.0, 15.25, "cm")); + + InStock firstInStock = new InStock("B", 15); + InStock lastInStock = new InStock("C", 35); + + postcard.setInStock(Arrays.asList(firstInStock, lastInStock)); + + mongoTemplate.save(postcard); + + Query query = new Query(); + query.fields() + .include("item") + .include("status") + .slice("inStock", -1); + + List inventoryList = mongoTemplate.find(query, Inventory.class); + + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + assertEquals(1, i.getInStock() + .size()); + assertNull(i.getSize()); + }); + + InStock stock = inventoryList.stream() + .filter(i -> i.getItem() + .equals("postcard")) + .map(i -> i.getInStock() + .get(0)) + .findFirst() + .orElse(null); + + assertEquals(lastInStock, stock); + } + +} diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/RepositoryProjectionUnitTest.java b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/RepositoryProjectionUnitTest.java new file mode 100644 index 0000000000..e8f2d4bf7d --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/RepositoryProjectionUnitTest.java @@ -0,0 +1,177 @@ +package com.baeldung.projection; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; + +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.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.projection.config.ProjectionConfig; +import com.baeldung.projection.model.InStock; +import com.baeldung.projection.model.Inventory; +import com.baeldung.projection.model.Size; +import com.baeldung.projection.repository.InventoryRepository; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = ProjectionConfig.class) +public class RepositoryProjectionUnitTest extends AbstractTestProjection { + + @Autowired + private InventoryRepository inventoryRepository; + + @BeforeEach + void setup() { + List inventoryList = getInventories(); + + inventoryRepository.saveAll(inventoryList); + } + + @Test + void whenIncludeFields_thenOnlyIncludedFieldsAreNotNull() { + List inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getId()); + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeFieldsAndExcludeOtherFields_thenOnlyExcludedFieldsAreNull() { + List inventoryList = inventoryRepository.findByStatusIncludeItemAndStatusExcludeIdFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNull(i.getId()); + assertNull(i.getSize()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenIncludeAllButExcludeSomeFields_thenOnlyExcludedFieldsAreNull() { + List inventoryList = inventoryRepository.findByStatusIncludeAllButStatusAndStockFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getInStock()); + assertNull(i.getStatus()); + }); + } + + @Test + void whenIncludeEmbeddedFields_thenEmbeddedFieldsAreNotNull() { + List inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNotNull(i.getSize() + .getUom()); + assertNull(i.getSize() + .getHeight()); + assertNull(i.getSize() + .getWidth()); + assertNull(i.getInStock()); + }); + } + + @Test + void whenExcludeEmbeddedFields_thenEmbeddedFieldsAreNull() { + List inventoryList = inventoryRepository.findByStatusExcludeEmbeddedFields("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getSize()); + assertNull(i.getSize() + .getUom()); + assertNotNull(i.getSize() + .getHeight()); + assertNotNull(i.getSize() + .getWidth()); + assertNotNull(i.getInStock()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsInArray_thenEmbeddedFieldsInArrayAreNotNull() { + List inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFieldsInArray("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + i.getInStock() + .forEach(stock -> { + assertNull(stock.getWareHouse()); + assertNotNull(stock.getQuantity()); + }); + assertNull(i.getSize()); + }); + } + + @Test + void whenIncludeEmbeddedFieldsSliceInArray_thenArrayLengthEqualToSlice() { + Inventory postcard = new Inventory(); + postcard.setItem("postcard"); + postcard.setStatus("A"); + postcard.setSize(new Size(10.0, 15.25, "cm")); + + InStock firstInStock = new InStock("B", 15); + InStock lastInStock = new InStock("C", 35); + + postcard.setInStock(Arrays.asList(firstInStock, lastInStock)); + + inventoryRepository.save(postcard); + + List inventoryList = inventoryRepository.findByStatusIncludeEmbeddedFieldsLastElementInArray("A"); + assertTrue(inventoryList.size() > 0); + + inventoryList.forEach(i -> { + assertNotNull(i.getItem()); + assertNotNull(i.getStatus()); + assertNotNull(i.getId()); + assertNotNull(i.getInStock()); + assertEquals(1, i.getInStock() + .size()); + assertNull(i.getSize()); + }); + + InStock stock = inventoryList.stream() + .filter(i -> i.getItem() + .equals("postcard")) + .map(i -> i.getInStock() + .get(0)) + .findFirst() + .orElse(null); + + assertEquals(lastInStock, stock); + } + +} diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/config/ProjectionConfig.java b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/config/ProjectionConfig.java new file mode 100644 index 0000000000..06260c0295 --- /dev/null +++ b/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/projection/config/ProjectionConfig.java @@ -0,0 +1,43 @@ +package com.baeldung.projection.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +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 +@ComponentScan(basePackages = "com.baeldung.projection") +@EnableMongoRepositories(basePackages = "com.baeldung.projection.repository") +public class ProjectionConfig { + + 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-data-rest-2/README.md b/persistence-modules/spring-data-rest-2/README.md similarity index 100% rename from spring-data-rest-2/README.md rename to persistence-modules/spring-data-rest-2/README.md diff --git a/spring-data-rest-2/pom.xml b/persistence-modules/spring-data-rest-2/pom.xml similarity index 98% rename from spring-data-rest-2/pom.xml rename to persistence-modules/spring-data-rest-2/pom.xml index cf3265c46d..fa328854a2 100644 --- a/spring-data-rest-2/pom.xml +++ b/persistence-modules/spring-data-rest-2/pom.xml @@ -13,7 +13,7 @@ com.baeldung parent-boot-2 0.0.1-SNAPSHOT - ../parent-boot-2 + ../../parent-boot-2 diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/SpringDataRestApplication.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/SpringDataRestApplication.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/SpringDataRestApplication.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/SpringDataRestApplication.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/config/DbConfig.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/config/DbConfig.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/config/DbConfig.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/config/DbConfig.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/config/RestConfig.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/config/RestConfig.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/config/RestConfig.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/config/RestConfig.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/models/WebsiteUser.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/models/WebsiteUser.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/models/WebsiteUser.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/models/WebsiteUser.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/repositories/UserRepository.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/repositories/UserRepository.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/repositories/UserRepository.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/repositories/UserRepository.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/App.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/App.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/halbrowser/App.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/App.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/DBLoader.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/DBLoader.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/DBLoader.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/DBLoader.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/RestConfig.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/RestConfig.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/RestConfig.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/config/RestConfig.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/data/BookRepository.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/data/BookRepository.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/halbrowser/data/BookRepository.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/data/BookRepository.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/model/Book.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/model/Book.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/halbrowser/model/Book.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/halbrowser/model/Book.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/Application.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/Application.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/Application.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/Application.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java diff --git a/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java b/persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java similarity index 100% rename from spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java rename to persistence-modules/spring-data-rest-2/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java diff --git a/spring-data-rest-2/src/main/resources/application.properties b/persistence-modules/spring-data-rest-2/src/main/resources/application.properties similarity index 100% rename from spring-data-rest-2/src/main/resources/application.properties rename to persistence-modules/spring-data-rest-2/src/main/resources/application.properties diff --git a/spring-data-rest-2/src/main/resources/logback.xml b/persistence-modules/spring-data-rest-2/src/main/resources/logback.xml similarity index 100% rename from spring-data-rest-2/src/main/resources/logback.xml rename to persistence-modules/spring-data-rest-2/src/main/resources/logback.xml diff --git a/spring-data-rest-2/src/main/resources/persistence-h2.properties b/persistence-modules/spring-data-rest-2/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-data-rest-2/src/main/resources/persistence-h2.properties rename to persistence-modules/spring-data-rest-2/src/main/resources/persistence-h2.properties diff --git a/spring-data-rest-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-rest-2/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-data-rest-2/src/test/java/com/baeldung/SpringContextTest.java rename to persistence-modules/spring-data-rest-2/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-data-rest-2/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java b/persistence-modules/spring-data-rest-2/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java similarity index 100% rename from spring-data-rest-2/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java rename to persistence-modules/spring-data-rest-2/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java diff --git a/spring-data-rest-2/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java b/persistence-modules/spring-data-rest-2/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java similarity index 100% rename from spring-data-rest-2/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java rename to persistence-modules/spring-data-rest-2/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java diff --git a/spring-data-rest-querydsl/README.md b/persistence-modules/spring-data-rest-querydsl/README.md similarity index 100% rename from spring-data-rest-querydsl/README.md rename to persistence-modules/spring-data-rest-querydsl/README.md diff --git a/spring-data-rest-querydsl/pom.xml b/persistence-modules/spring-data-rest-querydsl/pom.xml similarity index 98% rename from spring-data-rest-querydsl/pom.xml rename to persistence-modules/spring-data-rest-querydsl/pom.xml index 0b1cdd8928..dc1cf64006 100644 --- a/spring-data-rest-querydsl/pom.xml +++ b/persistence-modules/spring-data-rest-querydsl/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-boot-2 0.0.1-SNAPSHOT - ../parent-boot-2 + ../../parent-boot-2 diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java b/persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java similarity index 100% rename from spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java rename to persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/Application.java diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java b/persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java similarity index 100% rename from spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java rename to persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/QueryController.java diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java b/persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java similarity index 100% rename from spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java rename to persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/AddressRepository.java diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java b/persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java similarity index 100% rename from spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java rename to persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/controller/repository/UserRepository.java diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java b/persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java similarity index 100% rename from spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java rename to persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/Address.java diff --git a/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java b/persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java similarity index 100% rename from spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java rename to persistence-modules/spring-data-rest-querydsl/src/main/java/com/baeldung/entity/User.java diff --git a/spring-data-rest-querydsl/src/main/resources/application.yml b/persistence-modules/spring-data-rest-querydsl/src/main/resources/application.yml similarity index 100% rename from spring-data-rest-querydsl/src/main/resources/application.yml rename to persistence-modules/spring-data-rest-querydsl/src/main/resources/application.yml diff --git a/spring-data-rest-querydsl/src/main/resources/logback.xml b/persistence-modules/spring-data-rest-querydsl/src/main/resources/logback.xml similarity index 100% rename from spring-data-rest-querydsl/src/main/resources/logback.xml rename to persistence-modules/spring-data-rest-querydsl/src/main/resources/logback.xml diff --git a/spring-data-rest-querydsl/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-rest-querydsl/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-data-rest-querydsl/src/test/java/com/baeldung/SpringContextTest.java rename to persistence-modules/spring-data-rest-querydsl/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java b/persistence-modules/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java similarity index 100% rename from spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java rename to persistence-modules/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/IntegrationTest.java diff --git a/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java b/persistence-modules/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java similarity index 100% rename from spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java rename to persistence-modules/spring-data-rest-querydsl/src/test/java/com/baeldung/springdatarestquerydsl/QuerydslIntegrationTest.java diff --git a/spring-data-rest-querydsl/src/test/resources/application.yml b/persistence-modules/spring-data-rest-querydsl/src/test/resources/application.yml similarity index 100% rename from spring-data-rest-querydsl/src/test/resources/application.yml rename to persistence-modules/spring-data-rest-querydsl/src/test/resources/application.yml diff --git a/spring-data-rest/README.md b/persistence-modules/spring-data-rest/README.md similarity index 100% rename from spring-data-rest/README.md rename to persistence-modules/spring-data-rest/README.md diff --git a/spring-data-rest/pom.xml b/persistence-modules/spring-data-rest/pom.xml similarity index 98% rename from spring-data-rest/pom.xml rename to persistence-modules/spring-data-rest/pom.xml index e223c0488e..f5601cb7ce 100644 --- a/spring-data-rest/pom.xml +++ b/persistence-modules/spring-data-rest/pom.xml @@ -13,7 +13,7 @@ com.baeldung parent-boot-2 0.0.1-SNAPSHOT - ../parent-boot-2 + ../../parent-boot-2 diff --git a/spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/models/Address.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Address.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/models/Address.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Address.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/models/Author.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Author.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/models/Author.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Author.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/models/Book.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Book.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/models/Book.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Book.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/models/Library.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Library.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/models/Library.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Library.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java diff --git a/spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java b/persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java similarity index 100% rename from spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java rename to persistence-modules/spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java diff --git a/spring-data-rest/src/main/resources/application.properties b/persistence-modules/spring-data-rest/src/main/resources/application.properties similarity index 100% rename from spring-data-rest/src/main/resources/application.properties rename to persistence-modules/spring-data-rest/src/main/resources/application.properties diff --git a/spring-data-rest/src/main/resources/logback.xml b/persistence-modules/spring-data-rest/src/main/resources/logback.xml similarity index 100% rename from spring-data-rest/src/main/resources/logback.xml rename to persistence-modules/spring-data-rest/src/main/resources/logback.xml diff --git a/spring-data-rest/src/main/resources/persistence-derby.properties b/persistence-modules/spring-data-rest/src/main/resources/persistence-derby.properties similarity index 100% rename from spring-data-rest/src/main/resources/persistence-derby.properties rename to persistence-modules/spring-data-rest/src/main/resources/persistence-derby.properties diff --git a/spring-data-rest/src/main/resources/persistence-h2.properties b/persistence-modules/spring-data-rest/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-data-rest/src/main/resources/persistence-h2.properties rename to persistence-modules/spring-data-rest/src/main/resources/persistence-h2.properties diff --git a/spring-data-rest/src/main/resources/persistence-hsqldb.properties b/persistence-modules/spring-data-rest/src/main/resources/persistence-hsqldb.properties similarity index 100% rename from spring-data-rest/src/main/resources/persistence-hsqldb.properties rename to persistence-modules/spring-data-rest/src/main/resources/persistence-hsqldb.properties diff --git a/spring-data-rest/src/main/resources/persistence-sqlite.properties b/persistence-modules/spring-data-rest/src/main/resources/persistence-sqlite.properties similarity index 100% rename from spring-data-rest/src/main/resources/persistence-sqlite.properties rename to persistence-modules/spring-data-rest/src/main/resources/persistence-sqlite.properties diff --git a/spring-data-rest/src/main/webapp/users.html b/persistence-modules/spring-data-rest/src/main/webapp/users.html similarity index 100% rename from spring-data-rest/src/main/webapp/users.html rename to persistence-modules/spring-data-rest/src/main/webapp/users.html diff --git a/spring-data-rest/src/main/webapp/view/app.js b/persistence-modules/spring-data-rest/src/main/webapp/view/app.js similarity index 100% rename from spring-data-rest/src/main/webapp/view/app.js rename to persistence-modules/spring-data-rest/src/main/webapp/view/app.js diff --git a/spring-data-rest/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-rest/src/test/java/com/baeldung/SpringContextTest.java similarity index 100% rename from spring-data-rest/src/test/java/com/baeldung/SpringContextTest.java rename to persistence-modules/spring-data-rest/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java b/persistence-modules/spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java similarity index 100% rename from spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java rename to persistence-modules/spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java diff --git a/spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java b/persistence-modules/spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java similarity index 100% rename from spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java rename to persistence-modules/spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java diff --git a/spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java b/persistence-modules/spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java similarity index 100% rename from spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java rename to persistence-modules/spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java diff --git a/persistence-modules/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml index c842922fe5..6a9fb0ef06 100644 --- a/persistence-modules/spring-jooq/pom.xml +++ b/persistence-modules/spring-jooq/pom.xml @@ -195,7 +195,7 @@ - 3.12.4 + 3.14.15 1.0.0 1.5 1.0.0 diff --git a/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java index 7edcc2cd4b..9765a26a2b 100644 --- a/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java +++ b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/CountQueryIntegrationTest.java @@ -76,7 +76,14 @@ public class CountQueryIntegrationTest { int count = dsl.fetchCount(AUTHOR, conditions); Assert.assertEquals(1, count); } - + + + @Test + public void givenValidData_whenFetchCountWithMultipleConditionsUsingAndOperator_thenSucceed() { + int count = dsl.fetchCount(AUTHOR, AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan").and(AUTHOR.ID.notEqual(1))); + Assert.assertEquals(1, count); + } + @Test public void givenValidData_whenFetchCountWithConditionsInVarargs_thenSucceed() { Condition firstCond = AUTHOR.FIRST_NAME.equalIgnoreCase("Bryan"); diff --git a/pom.xml b/pom.xml index 441cf0e580..7cd2bbe3d1 100644 --- a/pom.xml +++ b/pom.xml @@ -333,17 +333,7 @@ akka-http akka-streams - algorithms-genetic - algorithms-miscellaneous-1 - algorithms-miscellaneous-2 - algorithms-miscellaneous-3 - algorithms-miscellaneous-4 - algorithms-miscellaneous-5 - algorithms-miscellaneous-6 - algorithms-searching - algorithms-sorting - algorithms-sorting-2 - animal-sniffer-mvn-plugin + algorithms-modules annotations antlr @@ -366,10 +356,7 @@ atomix - aws - aws-app-sync - aws-lambda - aws-reactive + aws-modules axon @@ -418,8 +405,7 @@ - graphql/graphql-java - graphql/graphql-dgs + graphql grpc gson guava-modules @@ -428,19 +414,14 @@ hazelcast helidon - httpclient + apache-httpclient httpclient-simple hystrix - immutables - jackson-modules jackson-simple java-blockchain - java-collections-conversions - java-collections-conversions-2 - java-collections-maps-3 javafx @@ -508,8 +489,6 @@ mapstruct maven-modules - maven-archetype - maven-polyglot mesos-marathon metrics @@ -632,7 +611,6 @@ spring-bom spring-boot-modules spring-boot-rest - spring-boot-rest-2 spring-caching spring-caching-2 @@ -649,9 +627,6 @@ spring-core-5 spring-cucumber - spring-data-rest - spring-data-rest-2 - spring-data-rest-querydsl spring-di spring-di-2 spring-di-3 @@ -819,17 +794,7 @@ akka-http akka-streams - algorithms-genetic - algorithms-miscellaneous-1 - algorithms-miscellaneous-2 - algorithms-miscellaneous-3 - algorithms-miscellaneous-4 - algorithms-miscellaneous-5 - algorithms-miscellaneous-6 - algorithms-searching - algorithms-sorting - algorithms-sorting-2 - animal-sniffer-mvn-plugin + algorithms-modules annotations antlr @@ -852,10 +817,7 @@ atomix - aws - aws-app-sync - aws-lambda - aws-reactive + aws-modules axon @@ -904,8 +866,7 @@ - graphql/graphql-java - graphql/graphql-dgs + graphql grpc gson guava-modules @@ -914,19 +875,14 @@ hazelcast helidon - httpclient + apache-httpclient httpclient-simple hystrix - immutables - jackson-modules jackson-simple java-blockchain - java-collections-conversions - java-collections-conversions-2 - java-collections-maps-3 javafx @@ -996,8 +952,6 @@ mapstruct maven-modules - maven-archetype - maven-polyglot mesos-marathon metrics @@ -1112,7 +1066,6 @@ spring-bom spring-boot-modules spring-boot-rest - spring-boot-rest-2 spring-caching spring-caching-2 @@ -1129,9 +1082,6 @@ spring-core-5 spring-cucumber - spring-data-rest - spring-data-rest-2 - spring-data-rest-querydsl spring-di spring-di-2 spring-di-3 @@ -1241,6 +1191,7 @@ jenkins/plugins jhipster + jhipster-5 jws libraries @@ -1348,18 +1299,20 @@ core-java-modules/core-java-networking-3 core-java-modules/multimodulemavenproject core-java-modules/core-java-strings - ddd-modules + core-java-modules/core-java-httpclient + ddd-contexts docker - httpclient-2 + apache-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-camel testing-modules/testing-assertions persistence-modules/fauna + lightrun @@ -1415,9 +1368,9 @@ core-java-modules/core-java-networking-3 core-java-modules/multimodulemavenproject core-java-modules/core-java-strings - ddd-modules + ddd-contexts docker - httpclient-2 + apache-httpclient-2 libraries-concurrency persistence-modules/sirix persistence-modules/spring-data-cassandra-2 @@ -1427,6 +1380,7 @@ spring-boot-modules/spring-boot-camel testing-modules/testing-assertions persistence-modules/fauna + lightrun diff --git a/reactive-systems/README.md b/reactive-systems/README.md index b23f4e4dc4..65d4b0a919 100644 --- a/reactive-systems/README.md +++ b/reactive-systems/README.md @@ -1,6 +1,6 @@ ## Reactive Systems in Java -This module contains services for article about reactive systems in Java. Please note that these secrives comprise parts of a full stack application to demonstrate the capabilities of a reactive system. Unless there is an article which extends on this concept, this is probably not a suitable module to add other code. +This module contains services for article about reactive systems in Java. Please note that these services comprise parts of a full stack application to demonstrate the capabilities of a reactive system. Unless there is an article which extends on this concept, this is probably not a suitable module to add other code. ### Relevant Articles diff --git a/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersIntegrationTest.java b/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersIntegrationTest.java index e6108759e1..4f37718814 100644 --- a/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersIntegrationTest.java +++ b/reactor-core/src/test/java/com/baeldung/reactor/core/CombiningPublishersIntegrationTest.java @@ -18,8 +18,8 @@ public class CombiningPublishersIntegrationTest { @Test public void givenFluxes_whenMergeDelayErrorIsInvoked_thenMergeDelayError() { Flux fluxOfIntegers = Flux.mergeDelayError(1, - evenNumbers.delayElements(Duration.ofMillis(2000L)), - oddNumbers.delayElements(Duration.ofMillis(1000L))); + evenNumbers.delayElements(Duration.ofMillis(500L)), + oddNumbers.delayElements(Duration.ofMillis(300L))); StepVerifier.create(fluxOfIntegers) .expectNext(1) diff --git a/regexMatchesToArray/src/regex/array/RegexMatches.java b/regexMatchesToArray/src/regex/array/RegexMatches.java new file mode 100644 index 0000000000..d7b50d95ca --- /dev/null +++ b/regexMatchesToArray/src/regex/array/RegexMatches.java @@ -0,0 +1,24 @@ +package regex.array; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.*; + +class RegexMatches { + + String[] regexMatch(String strSearch) + { + List matchesList = new ArrayList(); + String stringToSearch = strSearch; + Pattern p1 = Pattern.compile("780{1}\\d{7}"); + Matcher m1 = p1.matcher(stringToSearch); + while (m1.find()) + { + matchesList.add(m1.group()); + } + int sizeOfNewArray = matchesList.size(); + String newArrayOfMatches[] = new String[sizeOfNewArray]; + matchesList.toArray(newArrayOfMatches); + return newArrayOfMatches; + } +} diff --git a/regexMatchesToArray/test/regex/array/RegexMatchesUnitTest.java b/regexMatchesToArray/test/regex/array/RegexMatchesUnitTest.java new file mode 100644 index 0000000000..3e8f23c4bb --- /dev/null +++ b/regexMatchesToArray/test/regex/array/RegexMatchesUnitTest.java @@ -0,0 +1,33 @@ +package regex.array; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +import regex.array.RegexMatches; + +class RegexMatchesUnitTest { + + @Test + void whenFourNums_thenFourMatches() { + RegexMatches rm = new RegexMatches(); + String actual[] = rm.regexMatch("7801111211fsdafasdfa 7802222222 sadfsadfsda7803333333 sadfdasfasd 7804444444"); + + assertArrayEquals(new String[] {"7801111211", "7802222222", "7803333333", "7804444444"}, actual, "success"); + } + + @Test + void whenThreeNums_thenThreeMatches() { + RegexMatches rm = new RegexMatches(); + String actual[] = rm.regexMatch("7801111211fsdafasdfa 780222222 sadfsadfsda7803333333 sadfdasfasd 7804444444"); + + assertArrayEquals(new String[] {"7801111211", "7803333333", "7804444444"}, actual, "success"); + } + + @Test + void whenZeroNums_thenZeroMatches() { + RegexMatches rm = new RegexMatches(); + String actual[] = rm.regexMatch("78011111fsdafasdfa 780222222 sadfsadfsda78033333 sadfdasfasd 7804444"); + + assertArrayEquals(new String[] {}, actual, "success"); + } +} diff --git a/resteasy/pom.xml b/resteasy/pom.xml index d35fc852ba..a8c1f2815c 100644 --- a/resteasy/pom.xml +++ b/resteasy/pom.xml @@ -20,12 +20,6 @@ org.jboss.resteasy resteasy-servlet-initializer ${resteasy.version} - - - commons-logging - commons-logging - - org.jboss.resteasy @@ -40,14 +34,15 @@ org.jboss.resteasy - resteasy-jackson-provider + resteasy-jackson2-provider ${resteasy.version} - commons-io - commons-io - ${commons-io.version} + javax.servlet + javax.servlet-api + 4.0.1 + @@ -134,7 +129,7 @@ - 3.0.19.Final + 4.7.2.Final 1.6.1 diff --git a/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java b/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java index 7e709edb96..ba2878cc21 100644 --- a/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java +++ b/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Locale; import javax.naming.NamingException; +import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; @@ -14,21 +15,21 @@ import org.apache.commons.io.IOUtils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.codehaus.jackson.map.DeserializationConfig; -import org.codehaus.jackson.map.ObjectMapper; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; import org.junit.Before; import org.junit.Test; import com.baeldung.client.ServicesInterface; import com.baeldung.model.Movie; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; public class RestEasyClientLiveTest { - public static final UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8082/RestEasyTutorial/rest"); + public static final UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8082/resteasy/rest"); Movie transformerMovie = null; Movie batmanMovie = null; ObjectMapper jsonMapper = null; @@ -36,8 +37,8 @@ public class RestEasyClientLiveTest { @Before public void setup() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NamingException { - jsonMapper = new ObjectMapper().configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); - jsonMapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + jsonMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + jsonMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); jsonMapper.setDateFormat(sdf); @@ -60,8 +61,8 @@ public class RestEasyClientLiveTest { @Test public void testListAllMovies() { - - final ResteasyClient client = new ResteasyClientBuilder().build(); + + final ResteasyClient client = (ResteasyClient)ClientBuilder.newClient(); final ResteasyWebTarget target = client.target(FULL_PATH); final ServicesInterface proxy = target.proxy(ServicesInterface.class); @@ -79,7 +80,7 @@ public class RestEasyClientLiveTest { final String transformerImdbId = "tt0418279"; - final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient(); final ResteasyWebTarget target = client.target(FULL_PATH); final ServicesInterface proxy = target.proxy(ServicesInterface.class); @@ -93,7 +94,7 @@ public class RestEasyClientLiveTest { @Test public void testAddMovie() { - final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient(); final ResteasyWebTarget target = client.target(FULL_PATH); final ServicesInterface proxy = target.proxy(ServicesInterface.class); @@ -114,8 +115,8 @@ public class RestEasyClientLiveTest { final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); final CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); - final ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient); - final ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build(); + final ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); + final ResteasyClient client = ((ResteasyClientBuilder) ClientBuilder.newBuilder()).httpEngine(engine).build(); final ResteasyWebTarget target = client.target(FULL_PATH); final ServicesInterface proxy = target.proxy(ServicesInterface.class); @@ -138,7 +139,7 @@ public class RestEasyClientLiveTest { @Test public void testDeleteMovie() { - final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient(); final ResteasyWebTarget target = client.target(FULL_PATH); final ServicesInterface proxy = target.proxy(ServicesInterface.class); @@ -158,7 +159,7 @@ public class RestEasyClientLiveTest { @Test public void testUpdateMovie() { - final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyClient client = (ResteasyClient) ClientBuilder.newClient(); final ResteasyWebTarget target = client.target(FULL_PATH); final ServicesInterface proxy = target.proxy(ServicesInterface.class); diff --git a/restx/src/main/resources/restx/demo/settings.properties b/restx/src/main/resources/restx/demo/settings.properties index a03c2eea97..3b2b591922 100644 --- a/restx/src/main/resources/restx/demo/settings.properties +++ b/restx/src/main/resources/restx/demo/settings.properties @@ -1 +1,2 @@ -app.name=restx-demo \ No newline at end of file +app.name=restx-demo +restx.stats.share.enable=false \ No newline at end of file diff --git a/rule-engines/jess/pom.xml b/rule-engines/jess/pom.xml index f5db0374ef..be26d54a1e 100644 --- a/rule-engines/jess/pom.xml +++ b/rule-engines/jess/pom.xml @@ -7,18 +7,28 @@ jess 1.0-SNAPSHOT - jsr94 jsr94 1.1 + + + + + wso2 + Numerical Method's Maven Repository + http://dist.wso2.org/maven2/ + + + \ No newline at end of file diff --git a/spring-4/README.md b/spring-4/README.md index 46d9b71e5c..add82c7e00 100644 --- a/spring-4/README.md +++ b/spring-4/README.md @@ -7,3 +7,4 @@ This module contains articles about Spring 4 - [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) - [Spring JSON-P with Jackson](https://www.baeldung.com/spring-jackson-jsonp) - [What’s New in Spring 4.3?](https://www.baeldung.com/whats-new-in-spring-4-3) +- [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators) diff --git a/spring-4/pom.xml b/spring-4/pom.xml index 5887bd43e2..681747c1f6 100644 --- a/spring-4/pom.xml +++ b/spring-4/pom.xml @@ -31,6 +31,10 @@ + + org.springframework.boot + spring-boot-starter-actuator + com.h2database h2 diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/CustomEndpoint.java b/spring-4/src/main/java/com/baeldung/actuator/CustomEndpoint.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/CustomEndpoint.java rename to spring-4/src/main/java/com/baeldung/actuator/CustomEndpoint.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/HealthCheck.java b/spring-4/src/main/java/com/baeldung/actuator/HealthCheck.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/HealthCheck.java rename to spring-4/src/main/java/com/baeldung/actuator/HealthCheck.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/LoginServiceImpl.java b/spring-4/src/main/java/com/baeldung/actuator/LoginServiceImpl.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/LoginServiceImpl.java rename to spring-4/src/main/java/com/baeldung/actuator/LoginServiceImpl.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/SpringBoot.java b/spring-4/src/main/java/com/baeldung/actuator/SpringBoot.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/actuator/SpringBoot.java rename to spring-4/src/main/java/com/baeldung/actuator/SpringBoot.java diff --git a/spring-4/src/main/resources/application.properties b/spring-4/src/main/resources/application.properties index e67700b7be..ca6dbb5580 100644 --- a/spring-4/src/main/resources/application.properties +++ b/spring-4/src/main/resources/application.properties @@ -3,3 +3,24 @@ feature.new.foo=Y last.active.after=2018-03-14T00:00:00Z first.active.after=2999-03-15T00:00:00Z logging.level.org.flips=info + +#actuator properties +### server port +server.port=8080 +#port used to expose actuator +management.port=8081 +#CIDR allowed to hit actuator +management.address=127.0.0.1 +# Actuator Configuration +# customize /beans endpoint +endpoints.beans.id=springbeans +endpoints.beans.sensitive=false +endpoints.beans.enabled=true +# for the Spring Boot version 1.5.0 and above, we have to disable security to expose the health endpoint fully for unauthorized access. +# see: https://docs.spring.io/spring-boot/docs/1.5.x/reference/html/production-ready-monitoring.html +management.security.enabled=false +endpoints.health.sensitive=false +# customize /info endpoint +info.app.name=Spring Sample Application +info.app.description=This is my first spring boot application +info.app.version=1.0.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/CustomEndpointIntegrationTest.java b/spring-4/src/test/java/com/baeldung/actuator/CustomEndpointIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/CustomEndpointIntegrationTest.java rename to spring-4/src/test/java/com/baeldung/actuator/CustomEndpointIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/HealthCheckIntegrationTest.java b/spring-4/src/test/java/com/baeldung/actuator/HealthCheckIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/HealthCheckIntegrationTest.java rename to spring-4/src/test/java/com/baeldung/actuator/HealthCheckIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/HealthCheckUnitTest.java b/spring-4/src/test/java/com/baeldung/actuator/HealthCheckUnitTest.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/HealthCheckUnitTest.java rename to spring-4/src/test/java/com/baeldung/actuator/HealthCheckUnitTest.java diff --git a/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/LoginServiceIntegrationTest.java b/spring-4/src/test/java/com/baeldung/actuator/LoginServiceIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/LoginServiceIntegrationTest.java rename to spring-4/src/test/java/com/baeldung/actuator/LoginServiceIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/LoginServiceUnitTest.java b/spring-4/src/test/java/com/baeldung/actuator/LoginServiceUnitTest.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/actuator/LoginServiceUnitTest.java rename to spring-4/src/test/java/com/baeldung/actuator/LoginServiceUnitTest.java diff --git a/spring-5/src/test/java/com/baeldung/Example1IntegrationTest.java b/spring-5/src/test/java/com/baeldung/Example1ManualTest.java similarity index 93% rename from spring-5/src/test/java/com/baeldung/Example1IntegrationTest.java rename to spring-5/src/test/java/com/baeldung/Example1ManualTest.java index 8b9e66213f..c3330b4213 100644 --- a/spring-5/src/test/java/com/baeldung/Example1IntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/Example1ManualTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class Example1IntegrationTest { +public class Example1ManualTest { @Test public void test1a() { diff --git a/spring-5/src/test/java/com/baeldung/Example2IntegrationTest.java b/spring-5/src/test/java/com/baeldung/Example2ManualTest.java similarity index 93% rename from spring-5/src/test/java/com/baeldung/Example2IntegrationTest.java rename to spring-5/src/test/java/com/baeldung/Example2ManualTest.java index 6ed53ca4e9..9c47b17fdb 100644 --- a/spring-5/src/test/java/com/baeldung/Example2IntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/Example2ManualTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class Example2IntegrationTest { +public class Example2ManualTest { @Test public void test1a() { diff --git a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/ParallelManualTest.java similarity index 62% rename from spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java rename to spring-5/src/test/java/com/baeldung/ParallelManualTest.java index 1ce96de4ef..5c3a111c62 100644 --- a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/ParallelManualTest.java @@ -5,18 +5,18 @@ import org.junit.experimental.ParallelComputer; import org.junit.runner.Computer; import org.junit.runner.JUnitCore; -public class ParallelIntegrationTest { +public class ParallelManualTest { @Test public void runTests() { - final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; + final Class[] classes = { Example1ManualTest.class, Example2ManualTest.class }; JUnitCore.runClasses(new Computer(), classes); } @Test public void runTestsInParallel() { - final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; + final Class[] classes = { Example1ManualTest.class, Example2ManualTest.class }; JUnitCore.runClasses(new ParallelComputer(true, true), classes); } diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelManualTest.java similarity index 60% rename from spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java rename to spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelManualTest.java index 55b0fcf267..b9ed87ed73 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelManualTest.java @@ -1,24 +1,24 @@ package com.baeldung.jupiter; -import com.baeldung.Example1IntegrationTest; -import com.baeldung.Example2IntegrationTest; +import com.baeldung.Example1ManualTest; +import com.baeldung.Example2ManualTest; import org.junit.experimental.ParallelComputer; import org.junit.jupiter.api.Test; import org.junit.runner.Computer; import org.junit.runner.JUnitCore; -class Spring5JUnit5ParallelIntegrationTest { +class Spring5JUnit5ParallelManualTest { @Test void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() { - final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; + final Class[] classes = { Example1ManualTest.class, Example2ManualTest.class }; JUnitCore.runClasses(new ParallelComputer(true, true), classes); } @Test void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() { - final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; + final Class[] classes = { Example1ManualTest.class, Example2ManualTest.class }; JUnitCore.runClasses(new Computer(), classes); } diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index fabd54aa92..29685b0eb8 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -6,8 +6,8 @@ com.baeldung.spring-boot-modules spring-boot-modules 1.0.0-SNAPSHOT - pom spring-boot-modules + pom com.baeldung @@ -17,9 +17,6 @@ - spring-boot - spring-boot-1 - spring-boot-2 spring-boot-admin spring-boot-angular spring-boot-annotations @@ -47,7 +44,7 @@ spring-boot-groovy spring-boot-jasypt - + spring-boot-keycloak spring-boot-libraries spring-boot-libraries-2 spring-boot-libraries-comparison @@ -56,6 +53,7 @@ spring-boot-mvc spring-boot-mvc-2 spring-boot-mvc-3 + spring-boot-mvc-4 spring-boot-mvc-birt spring-boot-mvc-jersey spring-boot-nashorn @@ -64,6 +62,7 @@ spring-boot-properties spring-boot-properties-2 spring-boot-properties-3 + spring-boot-properties-migrator-demo spring-boot-property-exp spring-boot-runtime spring-boot-runtime-2 @@ -99,4 +98,4 @@ - + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-1/.mvn/wrapper/maven-wrapper.properties b/spring-boot-modules/spring-boot-1/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 9dda3b659b..0000000000 --- a/spring-boot-modules/spring-boot-1/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip diff --git a/spring-boot-modules/spring-boot-1/README.md b/spring-boot-modules/spring-boot-1/README.md deleted file mode 100644 index 8e5214c69a..0000000000 --- a/spring-boot-modules/spring-boot-1/README.md +++ /dev/null @@ -1,11 +0,0 @@ -## Spring Boot 1.x Actuator - -This module contains articles about Spring Boot Actuator in Spring Boot version 1.x. - -## Relevant articles: -- [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators) -- [A Quick Intro to the SpringBootServletInitializer](https://www.baeldung.com/spring-boot-servlet-initializer) -- [Spring Shutdown Callbacks](https://www.baeldung.com/spring-shutdown-callbacks) -- [Dynamic DTO Validation Config Retrieved from the Database](https://www.baeldung.com/spring-dynamic-dto-validation) - - diff --git a/spring-boot-modules/spring-boot-1/mvnw b/spring-boot-modules/spring-boot-1/mvnw deleted file mode 100755 index b74391fdf4..0000000000 --- a/spring-boot-modules/spring-boot-1/mvnw +++ /dev/null @@ -1,234 +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 -# -# 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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 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 Migwn, 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 - ))" - # TODO classpath? -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 - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -echo $MAVEN_PROJECTBASEDIR -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 - -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/spring-boot-modules/spring-boot-1/mvnw.cmd b/spring-boot-modules/spring-boot-1/mvnw.cmd deleted file mode 100644 index 019bd74d76..0000000000 --- a/spring-boot-modules/spring-boot-1/mvnw.cmd +++ /dev/null @@ -1,143 +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 http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 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 key stroke 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 enable echoing my 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 - -%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/spring-boot-modules/spring-boot-1/src/main/resources/application.properties b/spring-boot-modules/spring-boot-1/src/main/resources/application.properties deleted file mode 100644 index ac095e1cab..0000000000 --- a/spring-boot-modules/spring-boot-1/src/main/resources/application.properties +++ /dev/null @@ -1,19 +0,0 @@ -### server port -server.port=8080 -#port used to expose actuator -management.port=8081 -#CIDR allowed to hit actuator -management.address=127.0.0.1 -# Actuator Configuration -# customize /beans endpoint -endpoints.beans.id=springbeans -endpoints.beans.sensitive=false -endpoints.beans.enabled=true -# for the Spring Boot version 1.5.0 and above, we have to disable security to expose the health endpoint fully for unauthorized access. -# see: https://docs.spring.io/spring-boot/docs/1.5.x/reference/html/production-ready-monitoring.html -management.security.enabled=false -endpoints.health.sensitive=false -# customize /info endpoint -info.app.name=Spring Sample Application -info.app.description=This is my first spring boot application -info.app.version=1.0.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-2/.mvn/wrapper/MavenWrapperDownloader.java b/spring-boot-modules/spring-boot-2/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index b901097f2d..0000000000 --- a/spring-boot-modules/spring-boot-2/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/spring-boot-modules/spring-boot-2/.mvn/wrapper/maven-wrapper.properties b/spring-boot-modules/spring-boot-2/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 642d572ce9..0000000000 --- a/spring-boot-modules/spring-boot-2/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/spring-boot-modules/spring-boot-2/README.md b/spring-boot-modules/spring-boot-2/README.md deleted file mode 100644 index 7ea97f80c5..0000000000 --- a/spring-boot-modules/spring-boot-2/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: - -- [Speed up Spring Boot Startup Time](https://www.baeldung.com/spring-boot-startup-speed) diff --git a/spring-boot-modules/spring-boot-2/mvnw b/spring-boot-modules/spring-boot-2/mvnw deleted file mode 100644 index 41c0f0c23d..0000000000 --- a/spring-boot-modules/spring-boot-2/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 -# -# 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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# 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/spring-boot-modules/spring-boot-2/mvnw.cmd b/spring-boot-modules/spring-boot-2/mvnw.cmd deleted file mode 100644 index 86115719e5..0000000000 --- a/spring-boot-modules/spring-boot-2/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 http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM 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/spring-boot-modules/spring-boot-2/pom.xml b/spring-boot-modules/spring-boot-2/pom.xml deleted file mode 100644 index 0da07eaf00..0000000000 --- a/spring-boot-modules/spring-boot-2/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - 4.0.0 - spring-boot-2 - jar - Module for Spring Boot version 2.x - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../../parent-boot-2 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-security - - - org.apache.logging.log4j - log4j-core - ${log4j2.version} - - - org.springframework - spring-context-indexer - ${spring-core.version} - true - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - springStartupApp - com.baeldung.springStart.SpringStartApplication - - - - - repackage - - - - - - - - - 2.17.1 - 5.3.15 - 11 - 11 - - - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-2/src/main/resources/application.properties deleted file mode 100644 index 4a5f46a7b1..0000000000 --- a/spring-boot-modules/spring-boot-2/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -spring.main.lazy-initialization=true -logging.level.org.springframework.boot.autoconfigure=DEBUG -spring.jmx.enabled=false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-artifacts/pom.xml b/spring-boot-modules/spring-boot-artifacts/pom.xml index 0292dc95cf..7709c6a316 100644 --- a/spring-boot-modules/spring-boot-artifacts/pom.xml +++ b/spring-boot-modules/spring-boot-artifacts/pom.xml @@ -101,7 +101,7 @@ maven-failsafe-plugin 2.18 - integration-tests @@ -110,7 +110,7 @@ verify - **/ExternalPropertyFileLoaderIntegrationTest.java @@ -195,4 +195,4 @@ 4.5.8 - + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-2/README.md b/spring-boot-modules/spring-boot-basic-customization-2/README.md index 9488618ca5..0f4167d25b 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/README.md +++ b/spring-boot-modules/spring-boot-basic-customization-2/README.md @@ -8,3 +8,6 @@ This module contains articles about Spring Boot customization 2 - [XML Defined Beans in Spring Boot](https://www.baeldung.com/spring-boot-xml-beans) - [What Is OncePerRequestFilter?](https://www.baeldung.com/spring-onceperrequestfilter) - [Spring Boot Exit Codes](https://www.baeldung.com/spring-boot-exit-codes) + - [Guide to Spring Type Conversions](https://www.baeldung.com/spring-type-conversions) + - [Container Configuration in Spring Boot 2](https://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot) + - [Speed up Spring Boot Startup Time](https://www.baeldung.com/spring-boot-startup-speed) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-2/pom.xml b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml index b615947de7..439051c7e6 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization-2/pom.xml @@ -19,10 +19,47 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-actuator + + + com.h2database + h2 + org.springframework.boot spring-boot-starter-test + + com.google.guava + guava + ${guava.version} + + + + + org.springframework.boot + spring-boot-maven-plugin + + springStartupApp + com.baeldung.springStart.SpringStartApplication + + + + + repackage + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/CustomContainer.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/container/CustomContainer.java similarity index 93% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/CustomContainer.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/container/CustomContainer.java index aaa3188010..6ebd4d5c62 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/CustomContainer.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/container/CustomContainer.java @@ -1,4 +1,4 @@ -package com.baeldung.rss; +package com.baeldung.container; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; diff --git a/spring-boot-modules/spring-boot-2/src/main/java/com/baeldung/springStart/SpringStartApplication.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/springStart/SpringStartApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-2/src/main/java/com/baeldung/springStart/SpringStartApplication.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/springStart/SpringStartApplication.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/Application.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/Application.java similarity index 91% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/Application.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/Application.java index cb0d0c1532..1313032bbe 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/Application.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/Application.java @@ -1,4 +1,4 @@ -package com.baeldung.boot; +package com.baeldung.typeconversion; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/config/WebConfig.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/config/WebConfig.java similarity index 67% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/config/WebConfig.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/config/WebConfig.java index b23c910a04..bad84edf88 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/config/WebConfig.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/config/WebConfig.java @@ -1,12 +1,13 @@ -package com.baeldung.boot.config; +package com.baeldung.typeconversion.config; -import com.baeldung.boot.converter.StringToEmployeeConverter; -import com.baeldung.boot.converter.StringToEnumConverterFactory; -import com.baeldung.boot.converter.GenericBigDecimalConverter; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.baeldung.typeconversion.converter.GenericBigDecimalConverter; +import com.baeldung.typeconversion.converter.StringToEmployeeConverter; +import com.baeldung.typeconversion.converter.StringToEnumConverterFactory; + @Configuration public class WebConfig implements WebMvcConfigurer { diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/GenericBigDecimalConverter.java similarity index 96% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/GenericBigDecimalConverter.java index fc73cfee5f..440ffba5ee 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/GenericBigDecimalConverter.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/GenericBigDecimalConverter.java @@ -1,4 +1,4 @@ -package com.baeldung.boot.converter; +package com.baeldung.typeconversion.converter; import com.google.common.collect.ImmutableSet; import org.springframework.core.convert.TypeDescriptor; diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/StringToEmployeeConverter.java similarity index 76% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/StringToEmployeeConverter.java index ac635532ea..9703ed2514 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/StringToEmployeeConverter.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/StringToEmployeeConverter.java @@ -1,8 +1,8 @@ -package com.baeldung.boot.converter; +package com.baeldung.typeconversion.converter; import org.springframework.core.convert.converter.Converter; -import com.baeldung.toggle.Employee; +import com.baeldung.typeconversion.entity.Employee; public class StringToEmployeeConverter implements Converter { diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/StringToEnumConverterFactory.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/StringToEnumConverterFactory.java similarity index 94% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/StringToEnumConverterFactory.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/StringToEnumConverterFactory.java index a2dce11a6a..dc15f83d6d 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/StringToEnumConverterFactory.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/StringToEnumConverterFactory.java @@ -1,4 +1,4 @@ -package com.baeldung.boot.converter; +package com.baeldung.typeconversion.converter; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/controller/StringToEmployeeConverterController.java similarity index 81% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/controller/StringToEmployeeConverterController.java index 260b1c734b..5c3f93f346 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/converter/controller/StringToEmployeeConverterController.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/converter/controller/StringToEmployeeConverterController.java @@ -1,11 +1,11 @@ -package com.baeldung.boot.converter.controller; +package com.baeldung.typeconversion.converter.controller; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.toggle.Employee; +import com.baeldung.typeconversion.entity.Employee; @RestController public class StringToEmployeeConverterController { diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/domain/Modes.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/domain/Modes.java new file mode 100644 index 0000000000..d905faacac --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/domain/Modes.java @@ -0,0 +1,6 @@ +package com.baeldung.typeconversion.domain; + +public enum Modes { + + ALPHA, BETA; +} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/toggle/Employee.java b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java similarity index 92% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/toggle/Employee.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java index 64a8b3ce5b..e1897de877 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/toggle/Employee.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/java/com/baeldung/typeconversion/entity/Employee.java @@ -1,4 +1,4 @@ -package com.baeldung.toggle; +package com.baeldung.typeconversion.entity; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties index ab9de92c82..370ea40d73 100644 --- a/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/main/resources/application.properties @@ -1 +1,6 @@ -sample=string loaded from properties! \ No newline at end of file +sample=string loaded from properties! + +#startup time properties +spring.main.lazy-initialization=true +logging.level.org.springframework.boot.autoconfigure=DEBUG +spring.jmx.enabled=false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/converter/CustomConverterIntegrationTest.java b/spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/typeconversion/converter/CustomConverterIntegrationTest.java similarity index 90% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/converter/CustomConverterIntegrationTest.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/typeconversion/converter/CustomConverterIntegrationTest.java index 4619964783..3e12e3c58d 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/converter/CustomConverterIntegrationTest.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/typeconversion/converter/CustomConverterIntegrationTest.java @@ -1,9 +1,9 @@ -package com.baeldung.converter; +package com.baeldung.typeconversion.converter; -import com.baeldung.toggle.Employee; +import com.baeldung.typeconversion.Application; +import com.baeldung.typeconversion.domain.Modes; +import com.baeldung.typeconversion.entity.Employee; -import com.baeldung.boot.Application; -import com.baeldung.boot.domain.Modes; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java b/spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/typeconversion/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java similarity index 92% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/typeconversion/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java index 52dc542ebf..8632eebda3 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-basic-customization-2/src/test/java/com/baeldung/typeconversion/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.converter.controller; +package com.baeldung.typeconversion.converter.controller; import org.junit.Test; import org.junit.runner.RunWith; @@ -8,14 +8,14 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; +import com.baeldung.typeconversion.Application; + import static org.hamcrest.CoreMatchers.is; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 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; -import com.baeldung.boot.Application; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = Application.class) @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java index 50d5f4ea71..9ef1fcbc8e 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java @@ -27,8 +27,8 @@ public class UserController { LOG.info("Fetching all the users"); return Arrays.asList( new User(UUID.randomUUID().toString(), "User1", "user1@test.com"), - new User(UUID.randomUUID().toString(), "User1", "user1@test.com"), - new User(UUID.randomUUID().toString(), "User1", "user1@test.com")); + new User(UUID.randomUUID().toString(), "User2", "user2@test.com"), + new User(UUID.randomUUID().toString(), "User3", "user3@test.com")); } } diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/DemoApplication.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/DemoApplication.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/DemoApplication.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/DemoApplication.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/components/FooService.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/components/FooService.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/components/FooService.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/components/FooService.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/exceptions/CommonException.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/exceptions/CommonException.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/exceptions/CommonException.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/exceptions/CommonException.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/exceptions/FooNotFoundException.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/exceptions/FooNotFoundException.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/exceptions/FooNotFoundException.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/exceptions/FooNotFoundException.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/model/Foo.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/model/Foo.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/model/Foo.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/model/Foo.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/repository/FooRepository.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/repository/FooRepository.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/repository/FooRepository.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/repository/FooRepository.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/service/FooController.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/service/FooController.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/demo/service/FooController.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/demo/service/FooController.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/session/exception/Application.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/session/exception/Application.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/session/exception/Application.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/session/exception/Application.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/session/exception/repository/FooRepository.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/session/exception/repository/FooRepository.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/session/exception/repository/FooRepository.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/session/exception/repository/FooRepository.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/session/exception/repository/FooRepositoryImpl.java b/spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/session/exception/repository/FooRepositoryImpl.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/session/exception/repository/FooRepositoryImpl.java rename to spring-boot-modules/spring-boot-crud/src/main/java/com/baeldung/session/exception/repository/FooRepositoryImpl.java diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/ApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/ApplicationIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/ApplicationIntegrationTest.java rename to spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/ApplicationIntegrationTest.java index 462291e0ac..88ff8c75f1 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/ApplicationIntegrationTest.java +++ b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/ApplicationIntegrationTest.java @@ -1,12 +1,13 @@ package com.baeldung.boot; -import com.baeldung.session.exception.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.session.exception.Application; + @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) @TestPropertySource("classpath:exception.properties") diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/FooRepositoryIntegrationTest.java b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/FooRepositoryIntegrationTest.java similarity index 94% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/FooRepositoryIntegrationTest.java rename to spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/FooRepositoryIntegrationTest.java index 1772739d20..9de1f56af0 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/FooRepositoryIntegrationTest.java +++ b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/FooRepositoryIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung.boot.repository; -import com.baeldung.boot.DemoApplicationIntegrationTest; +import com.baeldung.demo.DemoApplicationIntegrationTest; import com.baeldung.demo.model.Foo; import com.baeldung.demo.repository.FooRepository; import org.junit.Before; diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/HibernateSessionIntegrationTest.java b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/HibernateSessionIntegrationTest.java similarity index 94% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/HibernateSessionIntegrationTest.java rename to spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/HibernateSessionIntegrationTest.java index 2fe072bb67..63b4734cf0 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/HibernateSessionIntegrationTest.java +++ b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/HibernateSessionIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung.boot.repository; -import com.baeldung.boot.DemoApplicationIntegrationTest; +import com.baeldung.demo.DemoApplicationIntegrationTest; import com.baeldung.demo.model.Foo; import com.baeldung.demo.repository.FooRepository; import org.junit.Test; diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java rename to spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java index 2e3326e6b1..ae20b15cb3 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java +++ b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung.boot.repository; import com.baeldung.boot.ApplicationIntegrationTest; import com.baeldung.demo.model.Foo; import com.baeldung.session.exception.repository.FooRepository; + import org.hibernate.HibernateException; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/DemoApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/demo/DemoApplicationIntegrationTest.java similarity index 95% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/DemoApplicationIntegrationTest.java rename to spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/demo/DemoApplicationIntegrationTest.java index aaf4f1f780..3d72ec0140 100644 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/boot/DemoApplicationIntegrationTest.java +++ b/spring-boot-modules/spring-boot-crud/src/test/java/com/baeldung/demo/DemoApplicationIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.boot; +package com.baeldung.demo; import com.baeldung.demo.DemoApplication; import org.junit.Test; diff --git a/spring-boot-modules/spring-boot/src/test/resources/exception-hibernate.properties b/spring-boot-modules/spring-boot-crud/src/test/resources/exception-hibernate.properties similarity index 100% rename from spring-boot-modules/spring-boot/src/test/resources/exception-hibernate.properties rename to spring-boot-modules/spring-boot-crud/src/test/resources/exception-hibernate.properties diff --git a/spring-boot-modules/spring-boot/src/test/resources/exception.properties b/spring-boot-modules/spring-boot-crud/src/test/resources/exception.properties similarity index 100% rename from spring-boot-modules/spring-boot/src/test/resources/exception.properties rename to spring-boot-modules/spring-boot-crud/src/test/resources/exception.properties diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md index b99356492b..9ff2b2caf8 100644 --- a/spring-boot-modules/spring-boot-data-2/README.md +++ b/spring-boot-modules/spring-boot-data-2/README.md @@ -4,3 +4,7 @@ - [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper) - [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found) - [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository) +- [Using JaVers for Data Model Auditing in Spring Data](https://www.baeldung.com/spring-data-javers-audit) +- [BootstrapMode for JPA Repositories](https://www.baeldung.com/jpa-bootstrap-mode) +- [Dynamic DTO Validation Config Retrieved from the Database](https://www.baeldung.com/spring-dynamic-dto-validation) + diff --git a/spring-boot-modules/spring-boot-data-2/pom.xml b/spring-boot-modules/spring-boot-data-2/pom.xml index a3c2430497..cd03d1b9b1 100644 --- a/spring-boot-modules/spring-boot-data-2/pom.xml +++ b/spring-boot-modules/spring-boot-data-2/pom.xml @@ -16,10 +16,23 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-validation + org.springframework.boot spring-boot-starter-data-jpa + + org.javers + javers-spring-boot-starter-sql + ${javers.version} + com.h2database h2 @@ -27,4 +40,8 @@ + + 6.5.3 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/Application.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/Application.java new file mode 100644 index 0000000000..0bb1884f23 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/Application.java @@ -0,0 +1,50 @@ +package com.baeldung.boot.bootstrapmode; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; + +import javax.sql.DataSource; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + AsyncTaskExecutor delayedTaskExecutor() { + return new ThreadPoolTaskExecutor() { + @Override + public Future submit(Callable task) { + return super.submit(() -> { + Thread.sleep(5000); + return task.call(); + }); + } + }; + } + + @Bean + LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, AsyncTaskExecutor delayedTaskExecutor) { + LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); + factory.setPackagesToScan("com.baeldung.boot.bootstrapmode"); + factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + factory.setDataSource(dataSource); + factory.setBootstrapExecutor(delayedTaskExecutor); + Map properties = new HashMap<>(); + properties.put("hibernate.hbm2ddl.auto", "create-drop"); + factory.setJpaPropertyMap(properties); + return factory; + } +} + diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java new file mode 100644 index 0000000000..8d6ab3cfb8 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/domain/Todo.java @@ -0,0 +1,37 @@ +package com.baeldung.boot.bootstrapmode.domain; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Todo { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String label; + + public Todo() { + } + + public Todo(String label) { + this.label = label; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/repository/TodoRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/repository/TodoRepository.java new file mode 100644 index 0000000000..b32d1c5085 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/bootstrapmode/repository/TodoRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.boot.bootstrapmode.repository; + +import org.springframework.data.repository.CrudRepository; + +import com.baeldung.boot.bootstrapmode.domain.Todo; + +public interface TodoRepository extends CrudRepository { +} diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/SpringBootJaVersApplication.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/SpringBootJaVersApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/SpringBootJaVersApplication.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/SpringBootJaVersApplication.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/config/JaversConfiguration.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/config/JaversConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/config/JaversConfiguration.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/config/JaversConfiguration.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/domain/Address.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Address.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/domain/Address.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Address.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/domain/Product.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Product.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/domain/Product.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Product.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/domain/Store.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Store.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/domain/Store.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/domain/Store.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/repo/ProductRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/repo/ProductRepository.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/repo/ProductRepository.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/repo/ProductRepository.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/repo/StoreRepository.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/repo/StoreRepository.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/repo/StoreRepository.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/repo/StoreRepository.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/service/StoreService.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/service/StoreService.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/service/StoreService.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/service/StoreService.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/web/RebrandStoreDto.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/web/RebrandStoreDto.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/web/RebrandStoreDto.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/web/RebrandStoreDto.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/web/StoreController.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/web/StoreController.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/web/StoreController.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/web/StoreController.java diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/web/UpdatePriceDto.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/web/UpdatePriceDto.java similarity index 100% rename from spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/javers/web/UpdatePriceDto.java rename to spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/javers/web/UpdatePriceDto.java diff --git a/spring-boot-modules/spring-boot-data-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-data-2/src/main/resources/application.properties new file mode 100644 index 0000000000..60a6e0fed5 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/resources/application.properties @@ -0,0 +1,22 @@ +spring.h2.console.path=/h2 +spring.h2.console.enabled=true +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= +javers.mappingStyle=FIELD +javers.algorithm=SIMPLE +javers.commitIdGenerator=synchronized_sequence +javers.prettyPrint=true +javers.typeSafeValues=false +javers.newObjectSnapshot=true +javers.packagesToScan= +javers.auditableAspectEnabled=true +javers.springDataAuditableRepositoryAspectEnabled=true +javers.sqlSchema= +javers.sqlSchemaManagementEnabled=true +javers.prettyPrintDateFormats.localDateTime=dd MMM yyyy, HH:mm:ss +javers.prettyPrintDateFormats.zonedDateTime=dd MMM yyyy, HH:mm:ssZ +javers.prettyPrintDateFormats.localDate=dd MMM yyyy +javers.prettyPrintDateFormats.localTime=HH:mm:ss + diff --git a/spring-boot-modules/spring-boot-data-2/src/main/resources/data-expressions.sql b/spring-boot-modules/spring-boot-data-2/src/main/resources/data-expressions.sql new file mode 100644 index 0000000000..5a16ceceb9 --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/main/resources/data-expressions.sql @@ -0,0 +1,6 @@ +insert into contact_info_expression values ('email', + '[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?') +insert into contact_info_expression values ('phone', + '^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$') +insert into contact_info_expression values ('website', + '^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$') \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/schema-expressions.sql b/spring-boot-modules/spring-boot-data-2/src/main/resources/schema-expressions.sql similarity index 72% rename from spring-boot-modules/spring-boot/src/main/resources/schema-expressions.sql rename to spring-boot-modules/spring-boot-data-2/src/main/resources/schema-expressions.sql index 59f6ab05eb..532faefde1 100644 --- a/spring-boot-modules/spring-boot/src/main/resources/schema-expressions.sql +++ b/spring-boot-modules/spring-boot-data-2/src/main/resources/schema-expressions.sql @@ -1,4 +1,4 @@ -create table contact_info_expression( +CREATE TABLE contact_info_expression( expression_type varchar(50) not null, pattern varchar(500) not null, PRIMARY KEY ( expression_type ) diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/customer.html b/spring-boot-modules/spring-boot-data-2/src/main/resources/templates/customer.html similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/templates/customer.html rename to spring-boot-modules/spring-boot-data-2/src/main/resources/templates/customer.html diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeDefaultIntegrationTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeDefaultIntegrationTest.java new file mode 100644 index 0000000000..3ff743299b --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeDefaultIntegrationTest.java @@ -0,0 +1,24 @@ +package com.baeldung.boot.bootstrapmode; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import com.baeldung.boot.bootstrapmode.domain.Todo; +import com.baeldung.boot.bootstrapmode.repository.TodoRepository; + +@DataJpaTest +class BootstrapmodeDefaultIntegrationTest { + + @Autowired + private TodoRepository todoRepository; + + @Test + void givenBootstrapmodeValueIsDefault_whenCreatingTodo_shouldSuccess() { + Todo todo = new Todo("Something to be done"); + + assertThat(todoRepository.save(todo)).hasNoNullFieldsOrProperties(); + } +} diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeDeferredIntegrationTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeDeferredIntegrationTest.java new file mode 100644 index 0000000000..02110519df --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeDeferredIntegrationTest.java @@ -0,0 +1,25 @@ +package com.baeldung.boot.bootstrapmode; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.repository.config.BootstrapMode; + +import com.baeldung.boot.bootstrapmode.domain.Todo; +import com.baeldung.boot.bootstrapmode.repository.TodoRepository; + +@DataJpaTest(bootstrapMode = BootstrapMode.DEFERRED) +class BootstrapmodeDeferredIntegrationTest { + + @Autowired + private TodoRepository todoRepository; + + @Test + void givenBootstrapmodeValueIsDeferred_whenCreatingTodo_shouldSuccess() { + Todo todo = new Todo("Something to be done"); + + assertThat(todoRepository.save(todo)).hasNoNullFieldsOrProperties(); + } +} diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeLazyIntegrationTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeLazyIntegrationTest.java new file mode 100644 index 0000000000..eb5ddfa6ca --- /dev/null +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/bootstrapmode/BootstrapmodeLazyIntegrationTest.java @@ -0,0 +1,25 @@ +package com.baeldung.boot.bootstrapmode; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.repository.config.BootstrapMode; + +import com.baeldung.boot.bootstrapmode.domain.Todo; +import com.baeldung.boot.bootstrapmode.repository.TodoRepository; + +@DataJpaTest(bootstrapMode = BootstrapMode.LAZY) +class BootstrapmodeLazyIntegrationTest { + + @Autowired + private TodoRepository todoRepository; + + @Test + void givenBootstrapmodeValueIsLazy_whenCreatingTodo_shouldSuccess() { + Todo todo = new Todo("Something to be done"); + + assertThat(todoRepository.save(todo)).hasNoNullFieldsOrProperties(); + } +} diff --git a/spring-boot-modules/spring-boot-1/src/test/resources/application.properties b/spring-boot-modules/spring-boot-data-2/src/test/resources/application.properties similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/resources/application.properties rename to spring-boot-modules/spring-boot-data-2/src/test/resources/application.properties diff --git a/spring-boot-modules/spring-boot-data/README.md b/spring-boot-modules/spring-boot-data/README.md index f72864e6d9..c56c87014d 100644 --- a/spring-boot-modules/spring-boot-data/README.md +++ b/spring-boot-modules/spring-boot-data/README.md @@ -11,4 +11,4 @@ This module contains articles about Spring Boot with Spring Data - [Spring Custom Property Editor](https://www.baeldung.com/spring-mvc-custom-property-editor) - [Using @JsonComponent in Spring Boot](https://www.baeldung.com/spring-boot-jsoncomponent) - [Guide To Running Logic on Startup in Spring](https://www.baeldung.com/running-setup-logic-on-startup-in-spring) -- [Using JaVers for Data Model Auditing in Spring Data](https://www.baeldung.com/spring-data-javers-audit) + diff --git a/spring-boot-modules/spring-boot-data/pom.xml b/spring-boot-modules/spring-boot-data/pom.xml index 18360bbd8b..b69d0e093a 100644 --- a/spring-boot-modules/spring-boot-data/pom.xml +++ b/spring-boot-modules/spring-boot-data/pom.xml @@ -19,11 +19,6 @@ org.springframework.boot spring-boot-starter-data-redis - - org.javers - javers-spring-boot-starter-sql - ${javers.version} - org.springframework.boot spring-boot-starter-data-mongodb @@ -164,7 +159,6 @@ - 5.14.0 2.2.4 1.8 1.8 diff --git a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/disableautoconfig/SpringDataJPA.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/disableautoconfig/SpringDataJPA.java index 87656f66a6..8554076612 100644 --- a/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/disableautoconfig/SpringDataJPA.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/disableautoconfig/SpringDataJPA.java @@ -1,6 +1,5 @@ package com.baeldung.disableautoconfig; -import org.javers.spring.boot.sql.JaversSqlAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration; @@ -9,8 +8,8 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, - JaversSqlAutoConfiguration.class, SpringDataWebAutoConfiguration.class, - DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) + SpringDataWebAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, + HibernateJpaAutoConfiguration.class}) public class SpringDataJPA { public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-data/src/main/resources/application.properties b/spring-boot-modules/spring-boot-data/src/main/resources/application.properties index 969464a41c..cee5701cb5 100644 --- a/spring-boot-modules/spring-boot-data/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-data/src/main/resources/application.properties @@ -6,19 +6,5 @@ spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.password= -javers.mappingStyle=FIELD -javers.algorithm=SIMPLE -javers.commitIdGenerator=synchronized_sequence -javers.prettyPrint=true -javers.typeSafeValues=false -javers.newObjectSnapshot=true -javers.packagesToScan= -javers.auditableAspectEnabled=true -javers.springDataAuditableRepositoryAspectEnabled=true -javers.sqlSchema= -javers.sqlSchemaManagementEnabled=true -javers.prettyPrintDateFormats.localDateTime=dd MMM yyyy, HH:mm:ss -javers.prettyPrintDateFormats.zonedDateTime=dd MMM yyyy, HH:mm:ssZ -javers.prettyPrintDateFormats.localDate=dd MMM yyyy -javers.prettyPrintDateFormats.localTime=HH:mm:ss + diff --git a/spring-boot-modules/spring-boot-deployment/README.md b/spring-boot-modules/spring-boot-deployment/README.md index 85f288d33b..125de43a88 100644 --- a/spring-boot-modules/spring-boot-deployment/README.md +++ b/spring-boot-modules/spring-boot-deployment/README.md @@ -7,3 +7,4 @@ This module contains articles about deployment of a Spring Boot Application - [Spring Boot Console Application](https://www.baeldung.com/spring-boot-console-app) - [Comparing Embedded Servlet Containers in Spring Boot](https://www.baeldung.com/spring-boot-servlet-containers) - [Graceful Shutdown of a Spring Boot Application](https://www.baeldung.com/spring-boot-graceful-shutdown) + - [Spring Shutdown Callbacks](https://www.baeldung.com/spring-shutdown-callbacks) diff --git a/spring-boot-modules/spring-boot-deployment/pom.xml b/spring-boot-modules/spring-boot-deployment/pom.xml index 7a9c2096f1..47b1a0f0d5 100644 --- a/spring-boot-modules/spring-boot-deployment/pom.xml +++ b/spring-boot-modules/spring-boot-deployment/pom.xml @@ -41,6 +41,11 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + spring-boot-starter-tomcat + provided + com.h2database h2 diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java b/spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java rename to spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/ShutdownHookApplication.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java b/spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java rename to spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/beans/Bean1.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java b/spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java rename to spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/beans/Bean2.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java b/spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java rename to spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/beans/Bean3.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java b/spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java rename to spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/config/ExampleServletContextListener.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java b/spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java rename to spring-boot-modules/spring-boot-deployment/src/main/java/com/baeldung/shutdownhooks/config/ShutdownHookConfiguration.java diff --git a/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java b/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java index 8873f1214c..5d3cbe35cb 100644 --- a/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java +++ b/spring-boot-modules/spring-boot-di/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java @@ -13,6 +13,10 @@ import org.springframework.context.annotation.Configuration; // @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class)) // @ComponentScan(basePackages = "com.baeldung.componentscan.springapp") // @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals") +// @ComponentScan(basePackages = {"com.baeldung.componentscan.springapp.animals","com.baeldung.componentscan.springapp.flowers"}) +// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals;com.baeldung.componentscan.springapp.flowers") +// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals,com.baeldung.componentscan.springapp.flowers") +// @ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals com.baeldung.componentscan.springapp.flowers") // @ComponentScan (excludeFilters = @ComponentScan.Filter(type=FilterType.REGEX,pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*")) public class SpringComponentScanApp { diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/displayallbeans.html b/spring-boot-modules/spring-boot-di/src/main/resources/templates/displayallbeans.html similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/templates/displayallbeans.html rename to spring-boot-modules/spring-boot-di/src/main/resources/templates/displayallbeans.html diff --git a/spring-boot-modules/spring-boot-keycloak/README.md b/spring-boot-modules/spring-boot-keycloak/README.md index 7a1323d10e..cde11df0fa 100644 --- a/spring-boot-modules/spring-boot-keycloak/README.md +++ b/spring-boot-modules/spring-boot-keycloak/README.md @@ -9,3 +9,4 @@ This module contains articles about Keycloak in Spring Boot projects. - [Keycloak User Self-Registration](https://www.baeldung.com/keycloak-user-registration) - [Customizing Themes for Keycloak](https://www.baeldung.com/spring-keycloak-custom-themes) - [Securing SOAP Web Services With Keycloak](https://www.baeldung.com/soap-keycloak) +- [Get Keycloak User ID in Spring](https://www.baeldung.com/spring-keycloak-get-user-id) diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index 09ddcaa724..9e39176765 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -89,7 +89,7 @@ org.codehaus.mojo jaxb2-maven-plugin - 2.5.0 + 2.3.1 xjc diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java index 1959590e5a..5b267ae19e 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java +++ b/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/keycloak/CustomUserAttrController.java @@ -24,6 +24,8 @@ public class CustomUserAttrController { final Principal principal = (Principal) authentication.getPrincipal(); String dob = ""; + String userIdByToken = ""; + String userIdByMapper = ""; if (principal instanceof KeycloakPrincipal) { @@ -31,6 +33,9 @@ public class CustomUserAttrController { IDToken token = kPrincipal.getKeycloakSecurityContext() .getIdToken(); + userIdByToken = token.getSubject(); + userIdByMapper = token.getOtherClaims().get("user_id").toString(); + Map customClaims = token.getOtherClaims(); if (customClaims.containsKey("DOB")) { @@ -39,6 +44,8 @@ public class CustomUserAttrController { } model.addAttribute("username", principal.getName()); + model.addAttribute("userIDByToken", userIdByToken); + model.addAttribute("userIDByMapper", userIdByMapper); model.addAttribute("dob", dob); return "userInfo"; } diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-embedded.properties b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-embedded.properties new file mode 100644 index 0000000000..7e1985f0ad --- /dev/null +++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-embedded.properties @@ -0,0 +1,9 @@ +### server port +server.port=8080 + +#Keycloak Configuration +keycloak.auth-server-url=http://localhost:8083/auth +keycloak.realm=baeldung +keycloak.resource=customerClient +keycloak.public-client=true +keycloak.principal-attribute=preferred_username \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html b/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html index 1446fe2124..7f772398c1 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html +++ b/spring-boot-modules/spring-boot-keycloak/src/main/resources/templates/userInfo.html @@ -7,6 +7,12 @@

Hello, --name--.

+

+ User ID By Token: --userID--. +

+

+ User ID By Mapper: --userID--. +

Your Date of Birth as per our records is .

diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java similarity index 96% rename from spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java rename to spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java index e0de897044..0327915399 100644 --- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapIntegrationTest.java +++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloaksoap/KeycloakSoapLiveTest.java @@ -26,29 +26,35 @@ import java.util.Objects; import static org.assertj.core.api.Assertions.assertThat; /** - * The class contains Live/Integration tests. + * The class contains Live tests. * These tests expect that the Keycloak server is up and running on port 8080. - * The tests may fail without a Keycloak server. */ -@DisplayName("Keycloak SOAP Webservice Unit Tests") +@DisplayName("Keycloak SOAP Webservice Live Tests") @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") @AutoConfigureMockMvc -class KeycloakSoapIntegrationTest { +class KeycloakSoapLiveTest { + + private static final Logger logger = LoggerFactory.getLogger(KeycloakSoapLiveTest.class); - private static final Logger logger = LoggerFactory.getLogger(KeycloakSoapIntegrationTest.class); @LocalServerPort private int port; + @Autowired private TestRestTemplate restTemplate; + @Autowired private ObjectMapper objectMapper; + @Value("${grant.type}") private String grantType; + @Value("${client.id}") private String clientId; + @Value("${client.secret}") private String clientSecret; + @Value("${url}") private String keycloakUrl; diff --git a/spring-boot-modules/spring-boot-libraries/src/test/resources/GraphQL collection.postman_collection.json b/spring-boot-modules/spring-boot-libraries/src/test/resources/GraphQL collection.postman_collection.json new file mode 100644 index 0000000000..8245152bdd --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries/src/test/resources/GraphQL collection.postman_collection.json @@ -0,0 +1,169 @@ +{ + "info": { + "_postman_id": "910d9690-f629-4491-bbbd-adb30982a386", + "name": "GraphQL collection", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "mutations", + "item": [ + { + "name": "writePost", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "graphql", + "graphql": { + "query": "mutation writePost ($title: String!, $text: String!, $category: String) {\n writePost (title: $title, text: $text, category: $category) {\n id\n title\n text\n category\n }\n}", + "variables": "{\n \"title\": \"\",\n \"text\": \"\",\n \"category\": \"\"\n}" + }, + "options": { + "graphql": {} + } + }, + "url": { + "raw": "http://localhost:9090/springbootapp/graphql", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "9090", + "path": [ + "springbootapp", + "graphql" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "queries", + "item": [ + { + "name": "get recent posts", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "graphql", + "graphql": { + "query": "{\r\n recentPosts(count: 10, offset: 0) {\r\n id\r\n title\r\n category\r\n text\r\n author {\r\n id\r\n name\r\n thumbnail\r\n }\r\n }\r\n}", + "variables": "" + } + }, + "url": { + "raw": "http://localhost:9090/springbootapp/graphql", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "9090", + "path": [ + "springbootapp", + "graphql" + ] + } + }, + "response": [] + }, + { + "name": "recentPosts - variables", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "graphql", + "graphql": { + "query": "query recentPosts ($count: Int, $offset: Int) {\n recentPosts (count: $count, offset: $offset) {\n id\n title\n text\n category\n }\n}", + "variables": "{\n \"count\": 1,\n \"offset\": 0\n}" + }, + "options": { + "graphql": {} + } + }, + "url": { + "raw": "http://localhost:9090/springbootapp/graphql", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "9090", + "path": [ + "springbootapp", + "graphql" + ] + } + }, + "response": [] + }, + { + "name": "get recent posts - raw", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/graphql", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "query {\r\n recentPosts(count: 10, offset: 0) {\r\n id\r\n title\r\n category\r\n author {\r\n id\r\n name\r\n thumbnail\r\n }\r\n }\r\n}" + }, + "url": { + "raw": "http://localhost:9090/springbootapp/graphql", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "9090", + "path": [ + "springbootapp", + "graphql" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "b54f267b-c450-4f2d-8105-2f23bab4c922", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "00b575be-03d4-4b29-b137-733ead139638", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "id": "20a274e5-6d51-40d6-81cb-af9eb115b21b", + "key": "url", + "value": "", + "type": "string" + } + ], + "protocolProfileBehavior": {} +} diff --git a/spring-boot-modules/spring-boot-mvc-2/README.md b/spring-boot-modules/spring-boot-mvc-2/README.md index 0d0e05daf0..30e6d71a30 100644 --- a/spring-boot-modules/spring-boot-mvc-2/README.md +++ b/spring-boot-modules/spring-boot-mvc-2/README.md @@ -11,4 +11,5 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections) - [Spring Boot Consuming and Producing JSON](https://www.baeldung.com/spring-boot-json) - [Serve Static Resources with Spring](https://www.baeldung.com/spring-mvc-static-resources) +- [Add Header to Every Request in Postman](https://www.baeldung.com/postman-add-headers-pre-request) - More articles: [[prev -->]](/spring-boot-modules/spring-boot-mvc) diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/resources/Student_API_Collection.postman_collection.json b/spring-boot-modules/spring-boot-mvc-2/src/main/resources/Student_API_Collection.postman_collection.json new file mode 100644 index 0000000000..1cce92b7dc --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-2/src/main/resources/Student_API_Collection.postman_collection.json @@ -0,0 +1,101 @@ +{ + "info": { + "_postman_id": "2dd2d46e-cb0a-4fcd-a1a3-461930df0c38", + "name": "Student API Collection", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "http://localhost:8080/students/", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "", + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "image/*", + "type": "text", + "disabled": true + }, + { + "key": "Accept", + "value": "application/json", + "type": "text", + "disabled": true + } + ], + "url": { + "raw": "http://localhost:8080/students/", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "students", + "" + ] + } + }, + "response": [] + }, + { + "name": "http://localhost:8080/students/2", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/students/3", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "students", + "3" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "pm.request.headers.add({ ", + " key: \"Accept\",", + " value: \"application/json\" ", + "});", + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-3/README.md b/spring-boot-modules/spring-boot-mvc-3/README.md index fa24ac11ed..e4b0a73bda 100644 --- a/spring-boot-modules/spring-boot-mvc-3/README.md +++ b/spring-boot-modules/spring-boot-mvc-3/README.md @@ -11,4 +11,4 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [CharacterEncodingFilter In SpringBoot](https://www.baeldung.com/spring-boot-characterencodingfilter) - [HandlerInterceptors vs. Filters in Spring MVC](https://www.baeldung.com/spring-mvc-handlerinterceptor-vs-filter) - [ETags for REST with Spring](https://www.baeldung.com/etags-for-rest-with-spring) -- More articles: [[prev -->]](/spring-boot-modules/spring-boot-mvc-2) +- More articles: [[<-- Prev]](/spring-boot-modules/spring-boot-mvc-2)[[Next -->]](/spring-boot-modules/spring-boot-mvc-4) diff --git a/spring-boot-modules/spring-boot-mvc-4/README.md b/spring-boot-modules/spring-boot-mvc-4/README.md new file mode 100644 index 0000000000..a7a341deee --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-4/README.md @@ -0,0 +1,12 @@ +## Spring Boot MVC + +This module contains articles about Spring Web MVC in Spring Boot projects. + +### Relevant Articles: + +- [How to Register a Servlet in Java](https://www.baeldung.com/register-servlet) +- [Guide to Spring WebUtils and ServletRequestUtils](https://www.baeldung.com/spring-webutils-servletrequestutils) +- [Configure a Spring Boot Web Application](https://www.baeldung.com/spring-boot-application-configuration) +- [A Quick Intro to the SpringBootServletInitializer](https://www.baeldung.com/spring-boot-servlet-initializer) +- [A Guide to Spring in Eclipse STS](https://www.baeldung.com/eclipse-sts-spring) +- [Hide a Request Field in Swagger API](https://www.baeldung.com/spring-swagger-hide-field) diff --git a/spring-boot-modules/spring-boot-1/pom.xml b/spring-boot-modules/spring-boot-mvc-4/pom.xml similarity index 57% rename from spring-boot-modules/spring-boot-1/pom.xml rename to spring-boot-modules/spring-boot-mvc-4/pom.xml index 594e6459a4..b1c079b715 100644 --- a/spring-boot-modules/spring-boot-1/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-4/pom.xml @@ -3,22 +3,21 @@ 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-1 + spring-boot-mvc-4 + spring-boot-mvc-4 jar - Module for Spring Boot version 1.x + Module For Spring Boot MVC Web - - com.baeldung - parent-boot-1 - 0.0.1-SNAPSHOT - ../../parent-boot-1 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT org.springframework.boot - spring-boot-starter + spring-boot-starter-web org.springframework.boot @@ -26,34 +25,34 @@ org.springframework.boot - spring-boot-starter-web + spring-boot-starter-validation org.springframework.boot - spring-boot-starter-tomcat + spring-boot-devtools + true - org.springframework.boot - spring-boot-starter-actuator + io.springfox + springfox-boot-starter + ${spring.fox.version} + + + com.fasterxml.jackson.core + jackson-databind org.springframework.boot spring-boot-starter-data-jpa - - org.apache.logging.log4j - log4j-core - ${log4j2.version} - com.h2database h2 - test - org.springframework.boot - spring-boot-starter-test - test + commons-io + commons-io + ${commons-io.version} @@ -62,13 +61,17 @@ org.springframework.boot spring-boot-maven-plugin - ${spring-boot.version} + + ${start-class} + JAR +
- 2.17.1 + 3.0.0 + com.baeldung.springboot.swagger.ArticleApplication \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/controller/servlet/HelloWorldServlet.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/boot/controller/servlet/HelloWorldServlet.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/controller/servlet/HelloWorldServlet.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/boot/controller/servlet/HelloWorldServlet.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/error/MyCustomErrorController.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/error/MyCustomErrorController.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/error/MyCustomErrorController.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/error/MyCustomErrorController.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/error/SpringHelloServletRegistrationBean.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/error/SpringHelloServletRegistrationBean.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/error/SpringHelloServletRegistrationBean.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/error/SpringHelloServletRegistrationBean.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/error/controller/ErrorController.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/error/controller/ErrorController.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/error/controller/ErrorController.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/error/controller/ErrorController.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/properties/MyServletContainerCustomizationBean.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/properties/MyServletContainerCustomizationBean.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/properties/MyServletContainerCustomizationBean.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/properties/MyServletContainerCustomizationBean.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/main/SpringBootApplication.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/main/SpringBootApplication.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/main/SpringBootApplication.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/main/SpringBootApplication.java diff --git a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java similarity index 93% rename from spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java index 0aa0f0ae0b..5b9ce1271e 100644 --- a/spring-boot-modules/spring-boot-1/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java @@ -5,7 +5,7 @@ import java.time.LocalDateTime; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/ApplicationMain.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/ApplicationMain.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/ApplicationMain.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/ApplicationMain.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/props/Constants.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/props/Constants.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/props/Constants.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/props/Constants.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/props/PropertyLoader.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/props/PropertyLoader.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/props/PropertyLoader.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/props/PropertyLoader.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.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-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java similarity index 91% rename from spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java index 568d31e8bc..8be380baa0 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java @@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.spi.DocumentationType; @@ -12,6 +13,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @SpringBootApplication @EnableSwagger2 +@EnableWebMvc public class ArticleApplication { public static void main(String[] args) { 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-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java similarity index 91% rename from spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java index 96812e367a..c4336a7cfe 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java @@ -21,7 +21,7 @@ public class ArticlesController { } @PostMapping("") - public void addArticle(@RequestBody Article article) { + public void addArticle(@ModelAttribute 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-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java similarity index 97% rename from spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/model/Article.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java index 6512b4e1a7..f6318c04b3 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/model/Article.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java @@ -15,6 +15,7 @@ public class Article { //@ApiModelProperty(hidden = true) //@ApiParam(hidden = true) //@ApiModelProperty(readOnly = true) + @ApiParam(hidden = true) private int id; private String title; private int 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-4/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java similarity index 99% rename from spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java index 04f6e6c6e3..3fd0279988 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/service/ArticleService.java @@ -20,6 +20,6 @@ public class ArticleService { article.setId(articles.size() + 1); articles.add(article); } - + } diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/utils/UtilsApplication.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/utils/UtilsApplication.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/utils/UtilsApplication.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/utils/UtilsApplication.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/utils/controller/UtilsController.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/utils/controller/UtilsController.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/utils/controller/UtilsController.java rename to spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/utils/controller/UtilsController.java diff --git a/spring-boot-modules/spring-boot/src/main/resources/application.properties b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/application.properties similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/application.properties rename to spring-boot-modules/spring-boot-mvc-4/src/main/resources/application.properties diff --git a/spring-boot-modules/spring-boot/src/main/resources/custom.properties b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/custom.properties similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/custom.properties rename to spring-boot-modules/spring-boot-mvc-4/src/main/resources/custom.properties diff --git a/spring-boot-modules/spring-boot/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/logback.xml similarity index 55% rename from spring-boot-modules/spring-boot/src/main/resources/logback.xml rename to spring-boot-modules/spring-boot-mvc-4/src/main/resources/logback.xml index 56af2d397e..7d900d8ea8 100644 --- a/spring-boot-modules/spring-boot/src/main/resources/logback.xml +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/logback.xml @@ -7,12 +7,6 @@ - - - - - - diff --git a/spring-boot-modules/spring-boot/src/main/resources/shutdown/shutdown.bat b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/shutdown/shutdown.bat similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/shutdown/shutdown.bat rename to spring-boot-modules/spring-boot-mvc-4/src/main/resources/shutdown/shutdown.bat diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/resources/static/index.html b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/static/index.html new file mode 100644 index 0000000000..9f55d12685 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/static/index.html @@ -0,0 +1 @@ +Welcome to Baeldung \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/other.html b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/templates/other.html similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/templates/other.html rename to spring-boot-modules/spring-boot-mvc-4/src/main/resources/templates/other.html diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/utils.html b/spring-boot-modules/spring-boot-mvc-4/src/main/resources/templates/utils.html similarity index 100% rename from spring-boot-modules/spring-boot/src/main/resources/templates/utils.html rename to spring-boot-modules/spring-boot-mvc-4/src/main/resources/templates/utils.html diff --git a/spring-boot-modules/spring-boot/src/main/webapp/WEB-INF/context.xml b/spring-boot-modules/spring-boot-mvc-4/src/main/webapp/WEB-INF/context.xml similarity index 100% rename from spring-boot-modules/spring-boot/src/main/webapp/WEB-INF/context.xml rename to spring-boot-modules/spring-boot-mvc-4/src/main/webapp/WEB-INF/context.xml diff --git a/spring-boot-modules/spring-boot/src/main/webapp/WEB-INF/dispatcher.xml b/spring-boot-modules/spring-boot-mvc-4/src/main/webapp/WEB-INF/dispatcher.xml similarity index 100% rename from spring-boot-modules/spring-boot/src/main/webapp/WEB-INF/dispatcher.xml rename to spring-boot-modules/spring-boot-mvc-4/src/main/webapp/WEB-INF/dispatcher.xml diff --git a/spring-boot-modules/spring-boot/src/main/webapp/WEB-INF/web.xml b/spring-boot-modules/spring-boot-mvc-4/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from spring-boot-modules/spring-boot/src/main/webapp/WEB-INF/web.xml rename to spring-boot-modules/spring-boot-mvc-4/src/main/webapp/WEB-INF/web.xml diff --git a/spring-boot-modules/spring-boot/src/main/webapp/annotationservlet.jsp b/spring-boot-modules/spring-boot-mvc-4/src/main/webapp/annotationservlet.jsp similarity index 100% rename from spring-boot-modules/spring-boot/src/main/webapp/annotationservlet.jsp rename to spring-boot-modules/spring-boot-mvc-4/src/main/webapp/annotationservlet.jsp diff --git a/spring-boot-modules/spring-boot/src/main/webapp/index.jsp b/spring-boot-modules/spring-boot-mvc-4/src/main/webapp/index.jsp similarity index 100% rename from spring-boot-modules/spring-boot/src/main/webapp/index.jsp rename to spring-boot-modules/spring-boot-mvc-4/src/main/webapp/index.jsp diff --git a/spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-mvc-4/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-1/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java rename to spring-boot-modules/spring-boot-mvc-4/src/test/java/com/baeldung/servletinitializer/WarInitializerApplicationIntegrationTest.java diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java b/spring-boot-modules/spring-boot-mvc-4/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-mvc-4/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-mvc/README.md b/spring-boot-modules/spring-boot-mvc/README.md index 5e9ecded10..fdd7c70af2 100644 --- a/spring-boot-modules/spring-boot-mvc/README.md +++ b/spring-boot-modules/spring-boot-mvc/README.md @@ -7,8 +7,9 @@ This module contains articles about Spring Web MVC in Spring Boot projects. - [Custom Validation MessageSource in Spring Boot](https://www.baeldung.com/spring-custom-validation-message-source) - [Display RSS Feed with Spring MVC](https://www.baeldung.com/spring-mvc-rss-feed) - [A Controller, Service and DAO Example with Spring Boot and JSF](https://www.baeldung.com/jsf-spring-boot-controller-service-dao) -- [Setting Up Swagger 2 with a Spring REST API](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) +- [Setting Up Swagger 2 with a Spring REST API Using Springfox](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) - [Using Spring ResponseEntity to Manipulate the HTTP Response](https://www.baeldung.com/spring-response-entity) - [The @ServletComponentScan Annotation in Spring Boot](https://www.baeldung.com/spring-servletcomponentscan) - [Guide to Internationalization in Spring Boot](https://www.baeldung.com/spring-boot-internationalization) +- [Hide a Request Field in Swagger API](https://www.baeldung.com/spring-swagger-hide-field) - More articles: [[next -->]](/spring-boot-modules/spring-boot-mvc-2) diff --git a/spring-boot-modules/spring-boot-properties-migrator-demo/README.md b/spring-boot-modules/spring-boot-properties-migrator-demo/README.md new file mode 100644 index 0000000000..c00eae2681 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-migrator-demo/README.md @@ -0,0 +1,3 @@ + +### Relevant Articles: +- [Spring Boot Configuration Properties Migrator](https://www.baeldung.com/spring-boot-properties-migrator) diff --git a/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml b/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml new file mode 100644 index 0000000000..95dc06b155 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-migrator-demo/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + spring-boot-properties-migrator-demo + 1.0-SNAPSHOT + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + ../pom.xml + + + + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-properties-migrator + runtime + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + 8 + 8 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/intro/App.java b/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/java/com/baeldung/spring/boot/properties/migrator/Main.java similarity index 61% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/intro/App.java rename to spring-boot-modules/spring-boot-properties-migrator-demo/src/main/java/com/baeldung/spring/boot/properties/migrator/Main.java index 77cdf4ddb9..848b9680a0 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/intro/App.java +++ b/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/java/com/baeldung/spring/boot/properties/migrator/Main.java @@ -1,11 +1,11 @@ -package com.baeldung.intro; +package com.baeldung.spring.boot.properties.migrator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class App { +public class Main { public static void main(String[] args) { - SpringApplication.run(App.class, args); + SpringApplication.run(Main.class, args); } } diff --git a/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/resources/application-dev.yaml b/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/resources/application-dev.yaml new file mode 100644 index 0000000000..6eadac798b --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/resources/application-dev.yaml @@ -0,0 +1,16 @@ +# Deprecated Properties for Demonstration +#spring: +# resources: +# cache: +# period: 31536000 +# chain: +# compressed: true +# html-application-cache: true + +spring: + web: + resources: + cache: + period: 31536000 + chain: + compressed: false diff --git a/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/resources/application.properties b/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/resources/application.properties new file mode 100644 index 0000000000..15199b7710 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-migrator-demo/src/main/resources/application.properties @@ -0,0 +1,7 @@ +# Deprecated Properties for Demonstration +#spring.resources.cache.period=31536000 +#spring.resources.chain.compressed=false +#spring.resources.chain.html-application-cache=false +spring.web.resources.cache.period=31536000 +spring.web.resources.chain.compressed=false +banner.image.location="myBanner.txt" diff --git a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadIntegrationTest.java b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java similarity index 99% rename from spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadIntegrationTest.java rename to spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java index 0c28cb085b..88e22af4ba 100644 --- a/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadIntegrationTest.java +++ b/spring-boot-modules/spring-boot-properties/src/test/java/com/baeldung/properties/reloading/PropertiesReloadManualTest.java @@ -24,7 +24,7 @@ import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = SpringBootPropertiesTestApplication.class) -public class PropertiesReloadIntegrationTest { +public class PropertiesReloadManualTest { protected MockMvc mvc; diff --git a/spring-boot-modules/spring-boot-springdoc/README.md b/spring-boot-modules/spring-boot-springdoc/README.md index 4ac4147da6..5daca79bd2 100644 --- a/spring-boot-modules/spring-boot-springdoc/README.md +++ b/spring-boot-modules/spring-boot-springdoc/README.md @@ -4,3 +4,4 @@ - [Spring REST Docs vs OpenAPI](https://www.baeldung.com/spring-rest-docs-vs-openapi) - [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints) - [Swagger @Api Description Is Deprecated](https://www.baeldung.com/java-swagger-api-description-deprecated) +- [Set List of Objects in Swagger API Response](https://www.baeldung.com/java-swagger-set-list-response) 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 deleted file mode 100644 index a7ff3285ee..0000000000 --- a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/swaggerresponseapi/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: - -- [Set List of Objects in Swagger API Response](https://www.baeldung.com/java-swagger-set-list-response) diff --git a/spring-boot-modules/spring-boot-validation/README.md b/spring-boot-modules/spring-boot-validation/README.md index 8c3c8b9305..93b6e7d2d1 100644 --- a/spring-boot-modules/spring-boot-validation/README.md +++ b/spring-boot-modules/spring-boot-validation/README.md @@ -1,3 +1,4 @@ ### Relevant Articles - [Spring Validation in the Service Layer](https://www.baeldung.com/spring-service-layer-validation) +- [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation) diff --git a/spring-boot-modules/spring-boot-validation/pom.xml b/spring-boot-modules/spring-boot-validation/pom.xml index fa4e8439e6..1412a57e2a 100644 --- a/spring-boot-modules/spring-boot-validation/pom.xml +++ b/spring-boot-modules/spring-boot-validation/pom.xml @@ -22,6 +22,14 @@ org.hibernate.validator hibernate-validator + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/Application.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/Application.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/Application.java rename to spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/Application.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java rename to spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/controllers/UserController.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/entities/User.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/entities/User.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/entities/User.java rename to spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/entities/User.java diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/repositories/UserRepository.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/repositories/UserRepository.java similarity index 100% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/beanvalidation/application/repositories/UserRepository.java rename to spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/beanvalidation/application/repositories/UserRepository.java diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java b/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/beanvalidation/application/UserControllerIntegrationTest.java diff --git a/spring-boot-modules/spring-boot/.gitignore b/spring-boot-modules/spring-boot/.gitignore deleted file mode 100644 index da7c2c5c0a..0000000000 --- a/spring-boot-modules/spring-boot/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -.settings/ -.classpath -.project - diff --git a/spring-boot-modules/spring-boot/.mvn/wrapper/maven-wrapper.properties b/spring-boot-modules/spring-boot/.mvn/wrapper/maven-wrapper.properties deleted file mode 100755 index a447c9fa81..0000000000 --- a/spring-boot-modules/spring-boot/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/README.md b/spring-boot-modules/spring-boot/README.md deleted file mode 100644 index fdc8093806..0000000000 --- a/spring-boot-modules/spring-boot/README.md +++ /dev/null @@ -1,16 +0,0 @@ -## Spring Boot - -This module contains articles about Spring Boot - -### The Course -The "REST With Spring" Classes: http://bit.ly/restwithspring - -### Relevant Articles: - -- [A Guide to Spring in Eclipse STS](https://www.baeldung.com/eclipse-sts-spring) -- [Guide to Spring Type Conversions](https://www.baeldung.com/spring-type-conversions) -- [Spring Boot: Configuring a Main Class](https://www.baeldung.com/spring-boot-main-class) -- [Container Configuration in Spring Boot 2](https://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot) -- [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation) -- [How to Register a Servlet in Java](https://www.baeldung.com/register-servlet) -- [Guide to Spring WebUtils and ServletRequestUtils](https://www.baeldung.com/spring-webutils-servletrequestutils) diff --git a/spring-boot-modules/spring-boot/mvnw b/spring-boot-modules/spring-boot/mvnw deleted file mode 100755 index e96ccd5fbb..0000000000 --- a/spring-boot-modules/spring-boot/mvnw +++ /dev/null @@ -1,227 +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 -# -# 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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 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)`" - # TODO classpath? -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 - -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 - -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/spring-boot-modules/spring-boot/mvnw.cmd b/spring-boot-modules/spring-boot/mvnw.cmd deleted file mode 100755 index 6a6eec39ba..0000000000 --- a/spring-boot-modules/spring-boot/mvnw.cmd +++ /dev/null @@ -1,145 +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 http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 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 key stroke 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 my 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 - -%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/spring-boot-modules/spring-boot/pom.xml b/spring-boot-modules/spring-boot/pom.xml deleted file mode 100644 index 3afccef925..0000000000 --- a/spring-boot-modules/spring-boot/pom.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - 4.0.0 - spring-boot - 0.0.1-SNAPSHOT - spring-boot - war - This is simple boot application for Spring boot actuator test - - - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT - - - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-validation - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.ehcache - ehcache - - - org.hibernate - hibernate-ehcache - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-tomcat - - - org.springframework.boot - spring-boot-starter-test - test - - - io.dropwizard.metrics - metrics-core - - - com.h2database - h2 - - - org.springframework.boot - spring-boot-starter - - - com.jayway.jsonpath - json-path - test - - - com.google.guava - guava - ${guava.version} - - - org.apache.tomcat - tomcat-servlet-api - ${tomee-servlet-api.version} - provided - - - org.apache.activemq - artemis-server - - - com.rometools - rome - ${rome.version} - - - - - spring-boot - - - src/main/resources - true - - - - - org.apache.maven.plugins - maven-war-plugin - - - org.apache.maven.plugins - maven-resources-plugin - - - @ - - false - - - - - - - - autoconfiguration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*IntTest.java - - - **/AutoconfigurationTest.java - - - - - - - json - - - - - - - - - - - com.baeldung.intro.App - 8.5.11 - 1.9.0 - @ - - - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/config/H2JpaConfig.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/config/H2JpaConfig.java deleted file mode 100644 index 928928c9a5..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/config/H2JpaConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.baeldung.boot.config; - -import java.util.Properties; - -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -@Configuration -@EnableJpaRepositories(basePackages = { "com.baeldung.boot.repository", "com.baeldung.boot.boottest", "com.baeldung.repository" }) -@PropertySource("classpath:persistence-generic-entity.properties") -@EnableTransactionManagement -public class H2JpaConfig { - - @Autowired - private Environment env; - - @Bean - public DataSource dataSource() { - final DriverManagerDataSource dataSource = new DriverManagerDataSource(); - 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 LocalContainerEntityManagerFactoryBean entityManagerFactory() { - final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "com.baeldung.boot.domain", "com.baeldung.boot.model", "com.baeldung.boot.boottest", "com.baeldung.model" }); - em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - em.setJpaProperties(additionalProperties()); - return em; - } - - @Bean - JpaTransactionManager transactionManager(final EntityManagerFactory entityManagerFactory) { - final JpaTransactionManager transactionManager = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory(entityManagerFactory); - return transactionManager; - } - - final Properties additionalProperties() { - 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", env.getProperty("hibernate.show_sql")); - - return hibernateProperties; - } - -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/domain/Modes.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/domain/Modes.java deleted file mode 100644 index 7717294996..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/boot/domain/Modes.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.baeldung.boot.domain; - -public enum Modes { - - ALPHA, BETA; -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/buildproperties/Application.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/buildproperties/Application.java deleted file mode 100644 index 405cec3eac..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/buildproperties/Application.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.buildproperties; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.PropertySource; - -@SpringBootApplication -@ComponentScan(basePackages = "com.baeldung.buildproperties") -@PropertySource("classpath:build.properties") -//@PropertySource("classpath:build.yml") -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/buildproperties/BuildInfoService.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/buildproperties/BuildInfoService.java deleted file mode 100644 index 2a0d27188e..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/buildproperties/BuildInfoService.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.buildproperties; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -@Service -public class BuildInfoService { - @Value("${application-description}") - private String applicationDescription; - - @Value("${application-version}") - private String applicationVersion; - - public String getApplicationDescription() { - return applicationDescription; - } - - public String getApplicationVersion() { - return applicationVersion; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java deleted file mode 100644 index 4797d6e593..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.intro.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class HomeController { - - @GetMapping("/") - public String root() { - return "Index Page"; - } - - @GetMapping("/local") - public String local() { - return "/local"; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/Contact.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/Contact.java deleted file mode 100644 index f131d17196..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/Contact.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.baeldung.jsondateformat; - -import com.fasterxml.jackson.annotation.JsonFormat; - -import java.time.LocalDate; -import java.time.LocalDateTime; - -public class Contact { - - private String name; - private String address; - private String phone; - - @JsonFormat(pattern="yyyy-MM-dd") - private LocalDate birthday; - - @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") - private LocalDateTime lastUpdate; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public LocalDate getBirthday() { - return birthday; - } - - public void setBirthday(LocalDate birthday) { - this.birthday = birthday; - } - - public LocalDateTime getLastUpdate() { - return lastUpdate; - } - - public void setLastUpdate(LocalDateTime lastUpdate) { - this.lastUpdate = lastUpdate; - } - - public Contact() { - } - - public Contact(String name, String address, String phone, LocalDate birthday, LocalDateTime lastUpdate) { - this.name = name; - this.address = address; - this.phone = phone; - this.birthday = birthday; - this.lastUpdate = lastUpdate; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactAppConfig.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactAppConfig.java deleted file mode 100644 index 7a20ebfa51..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactAppConfig.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baeldung.jsondateformat; - -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; - -import java.time.format.DateTimeFormatter; - -@Configuration -public class ContactAppConfig { - - private static final String dateFormat = "yyyy-MM-dd"; - - private static final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; - - @Bean - @ConditionalOnProperty(value = "spring.jackson.date-format", matchIfMissing = true, havingValue = "none") - public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { - return new Jackson2ObjectMapperBuilderCustomizer() { - @Override - public void customize(Jackson2ObjectMapperBuilder builder) { - builder.simpleDateFormat(dateTimeFormat); - builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat))); - builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimeFormat))); - } - }; - } - -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactController.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactController.java deleted file mode 100644 index 8894d82fc7..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactController.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.baeldung.jsondateformat; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -@RestController -@RequestMapping(value = "/contacts") -public class ContactController { - - @GetMapping - public List getContacts() { - List contacts = new ArrayList<>(); - - Contact contact1 = new Contact("John Doe", "123 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now()); - Contact contact2 = new Contact("John Doe 2", "124 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now()); - Contact contact3 = new Contact("John Doe 3", "125 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now()); - - contacts.add(contact1); - contacts.add(contact2); - contacts.add(contact3); - - return contacts; - } - - @GetMapping("/javaUtilDate") - public List getContactsWithJavaUtilDate() { - List contacts = new ArrayList<>(); - - ContactWithJavaUtilDate contact1 = new ContactWithJavaUtilDate("John Doe", "123 Sesame Street", "123-456-789", new Date(), new Date()); - ContactWithJavaUtilDate contact2 = new ContactWithJavaUtilDate("John Doe 2", "124 Sesame Street", "123-456-789", new Date(), new Date()); - ContactWithJavaUtilDate contact3 = new ContactWithJavaUtilDate("John Doe 3", "125 Sesame Street", "123-456-789", new Date(), new Date()); - - contacts.add(contact1); - contacts.add(contact2); - contacts.add(contact3); - - return contacts; - } - - @GetMapping("/plain") - public List getPlainContacts() { - List contacts = new ArrayList<>(); - - PlainContact contact1 = new PlainContact("John Doe", "123 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now()); - PlainContact contact2 = new PlainContact("John Doe 2", "124 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now()); - PlainContact contact3 = new PlainContact("John Doe 3", "125 Sesame Street", "123-456-789", LocalDate.now(), LocalDateTime.now()); - - contacts.add(contact1); - contacts.add(contact2); - contacts.add(contact3); - - return contacts; - } - - @GetMapping("/plainWithJavaUtilDate") - public List getPlainContactsWithJavaUtilDate() { - List contacts = new ArrayList<>(); - - PlainContactWithJavaUtilDate contact1 = new PlainContactWithJavaUtilDate("John Doe", "123 Sesame Street", "123-456-789", new Date(), new Date()); - PlainContactWithJavaUtilDate contact2 = new PlainContactWithJavaUtilDate("John Doe 2", "124 Sesame Street", "123-456-789", new Date(), new Date()); - PlainContactWithJavaUtilDate contact3 = new PlainContactWithJavaUtilDate("John Doe 3", "125 Sesame Street", "123-456-789", new Date(), new Date()); - - contacts.add(contact1); - contacts.add(contact2); - contacts.add(contact3); - - return contacts; - } - -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactWithJavaUtilDate.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactWithJavaUtilDate.java deleted file mode 100644 index 5a1c508098..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactWithJavaUtilDate.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.baeldung.jsondateformat; - -import com.fasterxml.jackson.annotation.JsonFormat; - -import java.util.Date; - -public class ContactWithJavaUtilDate { - - private String name; - private String address; - private String phone; - - @JsonFormat(pattern="yyyy-MM-dd") - private Date birthday; - - @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") - private Date lastUpdate; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public Date getBirthday() { - return birthday; - } - - public void setBirthday(Date birthday) { - this.birthday = birthday; - } - - public Date getLastUpdate() { - return lastUpdate; - } - - public void setLastUpdate(Date lastUpdate) { - this.lastUpdate = lastUpdate; - } - - public ContactWithJavaUtilDate() { - } - - public ContactWithJavaUtilDate(String name, String address, String phone, Date birthday, Date lastUpdate) { - this.name = name; - this.address = address; - this.phone = phone; - this.birthday = birthday; - this.lastUpdate = lastUpdate; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/PlainContact.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/PlainContact.java deleted file mode 100644 index 7e9e53d205..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/PlainContact.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.baeldung.jsondateformat; - -import java.time.LocalDate; -import java.time.LocalDateTime; - -public class PlainContact { - - private String name; - private String address; - private String phone; - - private LocalDate birthday; - - private LocalDateTime lastUpdate; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public LocalDate getBirthday() { - return birthday; - } - - public void setBirthday(LocalDate birthday) { - this.birthday = birthday; - } - - public LocalDateTime getLastUpdate() { - return lastUpdate; - } - - public void setLastUpdate(LocalDateTime lastUpdate) { - this.lastUpdate = lastUpdate; - } - - public PlainContact() { - } - - public PlainContact(String name, String address, String phone, LocalDate birthday, LocalDateTime lastUpdate) { - this.name = name; - this.address = address; - this.phone = phone; - this.birthday = birthday; - this.lastUpdate = lastUpdate; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/PlainContactWithJavaUtilDate.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/PlainContactWithJavaUtilDate.java deleted file mode 100644 index daefb15543..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/PlainContactWithJavaUtilDate.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.baeldung.jsondateformat; - -import com.fasterxml.jackson.annotation.JsonFormat; - -import java.util.Date; - -public class PlainContactWithJavaUtilDate { - - private String name; - private String address; - private String phone; - - @JsonFormat(pattern="yyyy-MM-dd") - private Date birthday; - - @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") - private Date lastUpdate; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone; - } - - public Date getBirthday() { - return birthday; - } - - public void setBirthday(Date birthday) { - this.birthday = birthday; - } - - public Date getLastUpdate() { - return lastUpdate; - } - - public void setLastUpdate(Date lastUpdate) { - this.lastUpdate = lastUpdate; - } - - public PlainContactWithJavaUtilDate() { - } - - public PlainContactWithJavaUtilDate(String name, String address, String phone, Date birthday, Date lastUpdate) { - this.name = name; - this.address = address; - this.phone = phone; - this.birthday = birthday; - this.lastUpdate = lastUpdate; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/model/User.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/model/User.java deleted file mode 100644 index cc5f27f38c..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/model/User.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.model; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "users") -public class User { - - @Id - @GeneratedValue - private Integer id; - private String name; - private Integer status; - - public User() { - } - - public User(String name, Integer status) { - this.name = name; - this.status = status; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getStatus() { - return status; - } - - public void setStatus(Integer status) { - this.status = status; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/repository/UserRepository.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/repository/UserRepository.java deleted file mode 100644 index 4dd863fb17..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/repository/UserRepository.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.baeldung.repository; - -import com.baeldung.model.User; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Repository; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -@Repository("userRepository") -public interface UserRepository extends JpaRepository { - - int countByStatus(int status); - - Optional findOneByName(String name); - - @Async - CompletableFuture findOneByStatus(Integer status); - - @Query("SELECT u FROM User u WHERE u.status = 1") - Collection findAllActiveUsers(); - - @Query(value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true) - Collection findAllActiveUsersNative(); - - @Query("SELECT u FROM User u WHERE u.status = ?1") - User findUserByStatus(Integer status); - - @Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true) - User findUserByStatusNative(Integer status); - - @Query("SELECT u FROM User u WHERE u.status = ?1 and u.name = ?2") - User findUserByStatusAndName(Integer status, String name); - - @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") - User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name); - - @Query(value = "SELECT * FROM Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true) - User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name); - - @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") - User findUserByUserStatusAndUserName(@Param("status") Integer userStatus, @Param("name") String userName); - - @Query("SELECT u FROM User u WHERE u.name like ?1%") - User findUserByNameLike(String name); - - @Query("SELECT u FROM User u WHERE u.name like :name%") - User findUserByNameLikeNamedParam(@Param("name") String name); - - @Query(value = "SELECT * FROM users u WHERE u.name LIKE ?1%", nativeQuery = true) - User findUserByNameLikeNative(String name); - - @Query(value = "SELECT u FROM User u") - List findAllUsers(Sort sort); - - @Query(value = "SELECT u FROM User u ORDER BY id") - Page findAllUsersWithPagination(Pageable pageable); - - @Query(value = "SELECT * FROM Users ORDER BY id \n-- #pageable\n", countQuery = "SELECT count(*) FROM Users", nativeQuery = true) - Page findAllUsersWithPaginationNative(Pageable pageable); - - @Modifying - @Query("update User u set u.status = :status where u.name = :name") - int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name); - - @Modifying - @Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true) - int updateUserSetStatusForNameNative(Integer status, String name); - -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/ArticleFeedView.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/ArticleFeedView.java deleted file mode 100644 index 3efa619409..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/ArticleFeedView.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.rss; - -import com.rometools.rome.feed.rss.Channel; -import com.rometools.rome.feed.rss.Description; -import com.rometools.rome.feed.rss.Item; -import org.springframework.stereotype.Service; -import org.springframework.web.servlet.view.feed.AbstractRssFeedView; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -@Service("articleFeedView") -public class ArticleFeedView extends AbstractRssFeedView { - - protected Channel newFeed() { - Channel channel = new Channel("rss_2.0"); - channel.setLink("http://localhost:8080/rss"); - channel.setTitle("Article Feed"); - channel.setDescription("Article Feed Description"); - channel.setPubDate(new Date()); - return channel; - } - - @Override - protected List buildFeedItems(Map map, HttpServletRequest httpStRequest, HttpServletResponse httpStResponse) throws Exception { - List list = new ArrayList(); - - Item item1 = new Item(); - item1.setLink("http://www.baeldung.com/netty-exception-handling"); - item1.setTitle("Exceptions in Netty"); - Description description1 = new Description(); - description1.setValue("In this quick article, we’ll be looking at exception handling in Netty."); - item1.setDescription(description1); - item1.setPubDate(new Date()); - item1.setAuthor("Carlos"); - - Item item2 = new Item(); - item2.setLink("http://www.baeldung.com/cockroachdb-java"); - item2.setTitle("Guide to CockroachDB in Java"); - Description description2 = new Description(); - description2.setValue("This tutorial is an introductory guide to using CockroachDB with Java."); - item2.setDescription(description2); - item2.setPubDate(new Date()); - item2.setAuthor("Baeldung"); - - list.add(item1); - list.add(item2); - return list; - } -} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/RssApp.java b/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/RssApp.java deleted file mode 100644 index e067d3cfd1..0000000000 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/RssApp.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.rss; - -import javax.annotation.security.RolesAllowed; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; - -@SpringBootApplication -@ComponentScan(basePackages = "com.baeldung.rss") -public class RssApp { - - @RolesAllowed("*") - public static void main(String[] args) { - SpringApplication.run(RssApp.class, args); - } - -} diff --git a/spring-boot-modules/spring-boot/src/main/resources/application-errorhandling.properties b/spring-boot-modules/spring-boot/src/main/resources/application-errorhandling.properties deleted file mode 100644 index 270e86d443..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/application-errorhandling.properties +++ /dev/null @@ -1,4 +0,0 @@ -#server -server.port=9000 -server.servlet-path=/ -server.context-path=/ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/build.properties b/spring-boot-modules/spring-boot/src/main/resources/build.properties deleted file mode 100644 index 1612b8086d..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -application-description=@project.description@ -application-version=@project.version@ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/build.yml b/spring-boot-modules/spring-boot/src/main/resources/build.yml deleted file mode 100644 index 528d2e3440..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/build.yml +++ /dev/null @@ -1,2 +0,0 @@ -application-description: ^project.description^ -application-version: ^project.version^ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/data-expressions.sql b/spring-boot-modules/spring-boot/src/main/resources/data-expressions.sql deleted file mode 100644 index 3e702a759d..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/data-expressions.sql +++ /dev/null @@ -1,3 +0,0 @@ -insert into contact_info_expression values ('email','[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?') -insert into contact_info_expression values ('phone','^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$') -insert into contact_info_expression values ('website','^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$') \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/data.sql b/spring-boot-modules/spring-boot/src/main/resources/data.sql deleted file mode 100644 index c44034c739..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/data.sql +++ /dev/null @@ -1,5 +0,0 @@ -insert into users values (1, 'Alex', 1); -insert into users values (2, 'Bob', 1); -insert into users values (3, 'John', 0); -insert into users values (4, 'Harry', 0); -insert into users values (5, 'Smith', 1); \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/demo.properties b/spring-boot-modules/spring-boot/src/main/resources/demo.properties deleted file mode 100644 index 6b4cbeb7a0..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/demo.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.output.ansi.enabled=never -server.port=7070 diff --git a/spring-boot-modules/spring-boot/src/main/resources/persistence-generic-entity.properties b/spring-boot-modules/spring-boot/src/main/resources/persistence-generic-entity.properties deleted file mode 100644 index b19304cb1f..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/persistence-generic-entity.properties +++ /dev/null @@ -1,8 +0,0 @@ -jdbc.driverClassName=org.h2.Driver -jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 -jdbc.user=sa -jdbc.pass=sa - -hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=true -hibernate.hbm2ddl.auto=create-drop diff --git a/spring-boot-modules/spring-boot/src/main/resources/public/error/404.html b/spring-boot-modules/spring-boot/src/main/resources/public/error/404.html deleted file mode 100644 index df83ce219b..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/public/error/404.html +++ /dev/null @@ -1,8 +0,0 @@ - - - RESOURCE NOT FOUND - - -

404 RESOURCE NOT FOUND

- - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/schema.sql b/spring-boot-modules/spring-boot/src/main/resources/schema.sql deleted file mode 100644 index 4cd345c762..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/schema.sql +++ /dev/null @@ -1,8 +0,0 @@ -drop table if exists USERS; - -create table USERS( - ID int not null AUTO_INCREMENT, - NAME varchar(100) not null, - STATUS int, - PRIMARY KEY ( ID ) -); \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/customers.html b/spring-boot-modules/spring-boot/src/main/resources/templates/customers.html deleted file mode 100644 index 5a060d31da..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/templates/customers.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -
-

- Hello, --name--. -

- - - - - - - - - - - - - - - - - -
IDNameAddressService Rendered
Text ...Text ...Text ...Text...
- -
- - - diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/error.html b/spring-boot-modules/spring-boot/src/main/resources/templates/error.html deleted file mode 100644 index bc517913b2..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/templates/error.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -
-
-

Something went wrong!

- -

Our Engineers are on it.

-

Go Home

-
- - diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/error/404.html b/spring-boot-modules/spring-boot/src/main/resources/templates/error/404.html deleted file mode 100644 index df83ce219b..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/templates/error/404.html +++ /dev/null @@ -1,8 +0,0 @@ - - - RESOURCE NOT FOUND - - -

404 RESOURCE NOT FOUND

- - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/external.html b/spring-boot-modules/spring-boot/src/main/resources/templates/external.html deleted file mode 100644 index 2f9cc76961..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/templates/external.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - -
-
-

Customer Portal

-
-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam - erat lectus, vehicula feugiat ultricies at, tempus sed ante. Cras - arcu erat, lobortis vitae quam et, mollis pharetra odio. Nullam sit - amet congue ipsum. Nunc dapibus odio ut ligula venenatis porta non - id dui. Duis nec tempor tellus. Suspendisse id blandit ligula, sit - amet varius mauris. Nulla eu eros pharetra, tristique dui quis, - vehicula libero. Aenean a neque sit amet tellus porttitor rutrum nec - at leo.

- -

Existing Customers

-
- Enter the intranet: customers -
-
- -
- - - - diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/index.html b/spring-boot-modules/spring-boot/src/main/resources/templates/index.html deleted file mode 100644 index c1314558f6..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/templates/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - WebJars Demo - - - -

Welcome Home

-

-
- × - Success! It is working as we expected. -
-
- - - - - - diff --git a/spring-boot-modules/spring-boot/src/main/resources/templates/layout.html b/spring-boot-modules/spring-boot/src/main/resources/templates/layout.html deleted file mode 100644 index bab0c2982b..0000000000 --- a/spring-boot-modules/spring-boot/src/main/resources/templates/layout.html +++ /dev/null @@ -1,18 +0,0 @@ - - - -Customer Portal - - - - - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java b/spring-boot-modules/spring-boot/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java deleted file mode 100644 index cb056fe56d..0000000000 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/buildproperties/BuildInfoServiceIntegrationTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.buildproperties; - -import static org.junit.Assert.assertThat; - -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -class BuildInfoServiceIntegrationTest { - - @Autowired - private BuildInfoService service; - - @Test - void whenGetApplicationDescription_thenSuccess() { - assertThat(service.getApplicationDescription(), Matchers.is("This is simple boot application for Spring boot actuator test")); - assertThat(service.getApplicationVersion(), Matchers.is("0.0.1-SNAPSHOT")); - } -} diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java b/spring-boot-modules/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java deleted file mode 100644 index 2785054153..0000000000 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.baeldung.intro; - -import static org.hamcrest.Matchers.equalTo; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -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 org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) -@AutoConfigureMockMvc -public class AppLiveTest { - - @Autowired - private MockMvc mvc; - - @Test - public void getIndex() throws Exception { - mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(content().string(equalTo("Index Page"))); - } - - @Test - public void getLocal() throws Exception { - mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(content().string(equalTo("/local"))); - } - -} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/jsondateformat/ContactAppUnitTest.java b/spring-boot-modules/spring-boot/src/test/java/com/baeldung/jsondateformat/ContactAppUnitTest.java deleted file mode 100644 index 7be85b5e4f..0000000000 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/jsondateformat/ContactAppUnitTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.baeldung.jsondateformat; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - -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.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -import java.io.IOException; -import java.text.ParseException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, classes = ContactApp.class) -@TestPropertySource(properties = { - "spring.jackson.date-format=yyyy-MM-dd HH:mm:ss" -}) -public class ContactAppUnitTest { - - private final ObjectMapper mapper = new ObjectMapper(); - - @Autowired - TestRestTemplate restTemplate; - - @LocalServerPort - int port; - - String url; - - @Before - public void before() { - url=String.format("http://localhost:%s", port); - } - - @Test - public void givenJsonFormatAnnotationAndJava8DateType_whenGet_thenReturnExpectedDateFormat() throws IOException, ParseException { - ResponseEntity response = restTemplate.getForEntity(url + "/contacts", String.class); - - assertEquals(200, response.getStatusCodeValue()); - - List> respMap = mapper.readValue(response.getBody(), new TypeReference>>(){}); - - LocalDate birthdayDate = LocalDate.parse(respMap.get(0).get("birthday"), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - LocalDateTime lastUpdateTime = LocalDateTime.parse(respMap.get(0).get("lastUpdate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - - assertNotNull(birthdayDate); - assertNotNull(lastUpdateTime); - } - - @Test - public void givenJsonFormatAnnotationAndLegacyDateType_whenGet_thenReturnExpectedDateFormat() throws IOException { - ResponseEntity response = restTemplate.getForEntity(url + "/contacts/javaUtilDate", String.class); - - assertEquals(200, response.getStatusCodeValue()); - - List> respMap = mapper.readValue(response.getBody(), new TypeReference>>(){}); - - LocalDate birthdayDate = LocalDate.parse(respMap.get(0).get("birthday"), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - LocalDateTime lastUpdateTime = LocalDateTime.parse(respMap.get(0).get("lastUpdate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - - assertNotNull(birthdayDate); - assertNotNull(lastUpdateTime); - } - - @Test - public void givenDefaultDateFormatInAppPropertiesAndLegacyDateType_whenGet_thenReturnExpectedDateFormat() throws IOException { - ResponseEntity response = restTemplate.getForEntity(url + "/contacts/plainWithJavaUtilDate", String.class); - - assertEquals(200, response.getStatusCodeValue()); - - List> respMap = mapper.readValue(response.getBody(), new TypeReference>>(){}); - - LocalDate birthdayDate = LocalDate.parse(respMap.get(0).get("birthday"), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - LocalDateTime lastUpdateTime = LocalDateTime.parse(respMap.get(0).get("lastUpdate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - - assertNotNull(birthdayDate); - assertNotNull(lastUpdateTime); - } - - @Test(expected = DateTimeParseException.class) - public void givenDefaultDateFormatInAppPropertiesAndJava8DateType_whenGet_thenNotApplyFormat() throws IOException { - ResponseEntity response = restTemplate.getForEntity(url + "/contacts/plain", String.class); - - assertEquals(200, response.getStatusCodeValue()); - - List> respMap = mapper.readValue(response.getBody(), new TypeReference>>(){}); - - LocalDate birthdayDate = LocalDate.parse(respMap.get(0).get("birthday"), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - LocalDateTime lastUpdateTime = LocalDateTime.parse(respMap.get(0).get("lastUpdate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - } - -} diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/jsondateformat/ContactAppWithObjectMapperCustomizerUnitTest.java b/spring-boot-modules/spring-boot/src/test/java/com/baeldung/jsondateformat/ContactAppWithObjectMapperCustomizerUnitTest.java deleted file mode 100644 index 114f9bfc1a..0000000000 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/jsondateformat/ContactAppWithObjectMapperCustomizerUnitTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.baeldung.jsondateformat; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; - -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.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; - -import java.io.IOException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, classes = ContactApp.class) -public class ContactAppWithObjectMapperCustomizerUnitTest { - - private final ObjectMapper mapper = new ObjectMapper(); - - @Autowired - TestRestTemplate restTemplate; - - @LocalServerPort - int port; - - String url; - - @Before - public void before() { - url=String.format("http://localhost:%s", port); - } - - @Test - public void givenDefaultDateFormatInAppPropertiesAndLegacyDateType_whenGet_thenReturnExpectedDateFormat() throws IOException { - ResponseEntity response = restTemplate.getForEntity(url + "/contacts/plainWithJavaUtilDate", String.class); - - assertEquals(200, response.getStatusCodeValue()); - - List> respMap = mapper.readValue(response.getBody(), new TypeReference>>(){}); - - LocalDate birthdayDate = LocalDate.parse(respMap.get(0).get("birthday"), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - LocalDateTime lastUpdateTime = LocalDateTime.parse(respMap.get(0).get("lastUpdate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - - assertNotNull(birthdayDate); - assertNotNull(lastUpdateTime); - } - - @Test - public void givenDefaultDateFormatInAppPropertiesAndJava8DateType_whenGet_thenReturnExpectedDateFormat() throws IOException { - ResponseEntity response = restTemplate.getForEntity(url + "/contacts/plain", String.class); - - assertEquals(200, response.getStatusCodeValue()); - - List> respMap = mapper.readValue(response.getBody(), new TypeReference>>(){}); - - LocalDate birthdayDate = LocalDate.parse(respMap.get(0).get("birthday"), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - LocalDateTime lastUpdateTime = LocalDateTime.parse(respMap.get(0).get("lastUpdate"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - - assertNotNull(birthdayDate); - assertNotNull(lastUpdateTime); - } - -} diff --git a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/repository/UserRepositoryIntegrationTest.java b/spring-boot-modules/spring-boot/src/test/java/com/baeldung/repository/UserRepositoryIntegrationTest.java deleted file mode 100644 index a1318949f3..0000000000 --- a/spring-boot-modules/spring-boot/src/test/java/com/baeldung/repository/UserRepositoryIntegrationTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.baeldung.repository; - -import com.baeldung.boot.config.H2JpaConfig; -import com.baeldung.model.User; -import com.baeldung.repository.UserRepository; -import org.junit.After; -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.test.context.junit4.SpringRunner; - -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Created by adam. - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = H2JpaConfig.class) -public class UserRepositoryIntegrationTest { - - private final String USER_NAME_ADAM = "Adam"; - private final Integer ACTIVE_STATUS = 1; - - @Autowired - private UserRepository userRepository; - - @Test - public void givenEmptyDBWhenFindOneByNameThenReturnEmptyOptional() { - Optional foundUser = userRepository.findOneByName(USER_NAME_ADAM); - - assertThat(foundUser.isPresent()).isEqualTo(false); - } - - @Test - public void givenUserInDBWhenFindOneByNameThenReturnOptionalWithUser() { - User user = new User(); - user.setName(USER_NAME_ADAM); - userRepository.save(user); - - Optional foundUser = userRepository.findOneByName(USER_NAME_ADAM); - - assertThat(foundUser.isPresent()).isEqualTo(true); - - assertThat(foundUser - .get() - .getName()).isEqualTo(USER_NAME_ADAM); - } - - @Test - public void givenUserInDBWhenFindOneByStatusAsyncThenReturnCompletableFutureUser() throws ExecutionException, InterruptedException { - User user = new User(); - user.setName(USER_NAME_ADAM); - user.setStatus(ACTIVE_STATUS); - userRepository.save(user); - - CompletableFuture userByStatus = userRepository.findOneByStatus(ACTIVE_STATUS); - - assertThat(userByStatus - .get() - .getName()).isEqualTo(USER_NAME_ADAM); - } - - @After - public void cleanUp() { - userRepository.deleteAll(); - } - -} diff --git a/spring-boot-modules/spring-boot/src/test/resources/README.md b/spring-boot-modules/spring-boot/src/test/resources/README.md deleted file mode 100644 index 51c95afd9d..0000000000 --- a/spring-boot-modules/spring-boot/src/test/resources/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: - -- [How to Test GraphQL Using Postman](https://www.baeldung.com/graphql-postman) diff --git a/spring-boot-modules/spring-boot/src/test/resources/application.properties b/spring-boot-modules/spring-boot/src/test/resources/application.properties deleted file mode 100644 index 9ad65e1815..0000000000 --- a/spring-boot-modules/spring-boot/src/test/resources/application.properties +++ /dev/null @@ -1,19 +0,0 @@ -spring.mail.host=localhost -spring.mail.port=8025 -spring.mail.properties.mail.smtp.auth=false - - -# spring.datasource.x -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 -spring.datasource.username=sa -spring.datasource.password=sa - -# hibernate.X -spring.jpa.hibernate.dialect=org.hibernate.dialect.H2Dialect -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.hibernate.show_sql=true -spring.jpa.hibernate.hbm2ddl.auto=create-drop -spring.jpa.hibernate.cache.use_second_level_cache=true -spring.jpa.hibernate.cache.use_query_cache=true -spring.jpa.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory diff --git a/spring-boot-modules/spring-boot/src/test/resources/conversion.properties b/spring-boot-modules/spring-boot/src/test/resources/conversion.properties deleted file mode 100644 index 640442ec33..0000000000 --- a/spring-boot-modules/spring-boot/src/test/resources/conversion.properties +++ /dev/null @@ -1,11 +0,0 @@ -###### time unit -conversion.timeInDefaultUnit=10 -conversion.timeInNano=9ns -conversion.timeInDays=2 - -###### data size -conversion.sizeInDefaultUnit=300 -conversion.sizeInGB=2GB -conversion.sizeInTB=4 - -conversion.employee=john,2000 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/test/resources/import.sql b/spring-boot-modules/spring-boot/src/test/resources/import.sql deleted file mode 100644 index 9095b9468c..0000000000 --- a/spring-boot-modules/spring-boot/src/test/resources/import.sql +++ /dev/null @@ -1 +0,0 @@ ---insert into Foo values(1,'Foo_Name'); \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/test/resources/org/baeldung/boot/expected.json b/spring-boot-modules/spring-boot/src/test/resources/org/baeldung/boot/expected.json deleted file mode 100644 index f5409421a6..0000000000 --- a/spring-boot-modules/spring-boot/src/test/resources/org/baeldung/boot/expected.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "id":3, - "name":"Foo_Name_3" -} \ No newline at end of file diff --git a/spring-boot-rest-2/README.md b/spring-boot-rest-2/README.md deleted file mode 100644 index 985aa97a86..0000000000 --- a/spring-boot-rest-2/README.md +++ /dev/null @@ -1,5 +0,0 @@ -### Relevant Article: - -- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints) -- [HTTP PUT vs. POST in REST API](https://www.baeldung.com/rest-http-put-vs-post) -- [415 Unsupported MediaType in Spring Application](https://www.baeldung.com/spring-415-unsupported-mediatype) diff --git a/spring-boot-rest-2/pom.xml b/spring-boot-rest-2/pom.xml deleted file mode 100644 index b75e93577a..0000000000 --- a/spring-boot-rest-2/pom.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - 4.0.0 - com.baeldung.web - spring-boot-rest-2 - spring-boot-rest-2 - war - Spring Boot Rest Module - - - com.baeldung - parent-boot-2 - 0.0.1-SNAPSHOT - ../parent-boot-2 - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - io.springfox - springfox-boot-starter - ${springfox.version} - - - org.springframework.boot - spring-boot-starter-data-jpa - - - com.h2database - h2 - runtime - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - 3.0.0 - - - \ No newline at end of file diff --git a/spring-boot-rest-2/src/main/resources/application.properties b/spring-boot-rest-2/src/main/resources/application.properties deleted file mode 100644 index 5046c9660f..0000000000 --- a/spring-boot-rest-2/src/main/resources/application.properties +++ /dev/null @@ -1,2 +0,0 @@ - -management.endpoints.web.exposure.include=mappings diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index a2c4b3509f..f58e1aec5c 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -45,7 +45,7 @@ spring-cloud-ribbon-retry spring-cloud-circuit-breaker spring-cloud-eureka-self-preservation - + spring-cloud-openfeign spring-cloud-netflix-feign spring-cloud-sentinel spring-cloud-dapr @@ -92,4 +92,4 @@ 3.1.3 - + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/README.md b/spring-cloud/spring-cloud-eureka/README.md index 5fc96256f4..0029ea60f6 100644 --- a/spring-cloud/spring-cloud-eureka/README.md +++ b/spring-cloud/spring-cloud-eureka/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Introduction to Spring Cloud Netflix – Eureka](http://www.baeldung.com/spring-cloud-netflix-eureka) - [Integration Tests With Spring Cloud Netflix and Feign](https://www.baeldung.com/spring-cloud-feign-integration-tests) +- [Spring Cloud – Disable Discovery Clients with Profiles](https://www.baeldung.com/spring-cloud-disable-discovery-clients) diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml new file mode 100644 index 0000000000..23e06a55f9 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + spring-cloud-eureka-client-profiles + 1.0.0-SNAPSHOT + spring-cloud-eureka-client-profiles + jar + Spring Cloud Eureka Sample Client + + + com.baeldung.spring.cloud + spring-cloud-eureka + 1.0.0-SNAPSHOT + + + + + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + + + org.springframework.cloud + spring-cloud-starter-parent + ${spring-cloud-dependencies.version} + pom + import + + + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.boot + spring-boot-starter-web + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java new file mode 100644 index 0000000000..854bab97e7 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/java/com/baeldung/spring/cloud/eureka/client/EurekaClientApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.eureka.client; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class EurekaClientApplication { + + public static void main(String[] args) { + SpringApplication.run(EurekaClientApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/java/com/baeldung/spring/cloud/eureka/client/controller/HelloWorldController.java b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/java/com/baeldung/spring/cloud/eureka/client/controller/HelloWorldController.java new file mode 100644 index 0000000000..d0d0a6ec9f --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/java/com/baeldung/spring/cloud/eureka/client/controller/HelloWorldController.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.eureka.client.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloWorldController { + + @RequestMapping("/hello") + public String hello() { + return "Hello World!"; + } +} diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/resources/application-dev.properties b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/resources/application-dev.properties new file mode 100644 index 0000000000..c565e42678 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/resources/application-dev.properties @@ -0,0 +1,2 @@ +server.port=8080 +spring.cloud.discovery.enabled=false \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/resources/application.properties b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/resources/application.properties new file mode 100644 index 0000000000..3cfecbbf08 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/main/resources/application.properties @@ -0,0 +1,9 @@ +server.port=8080 + +eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8761/eureka} +eureka.instance.preferIpAddress=false + +spring.application.name=spring-cloud-eureka-client +#--- +spring.config.activate.on-profile=dev +spring.cloud.discovery.enabled=false \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/test/java/com/baeldung/spring/cloud/eureka/client/SpringContextTest.java b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/test/java/com/baeldung/spring/cloud/eureka/client/SpringContextTest.java new file mode 100644 index 0000000000..a3ed012abb --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client-profiles/src/test/java/com/baeldung/spring/cloud/eureka/client/SpringContextTest.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.eureka.client; + +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 { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } + +} diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/EmployeeClient.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/EmployeeClient.java new file mode 100644 index 0000000000..569401bdcf --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/client/EmployeeClient.java @@ -0,0 +1,12 @@ +package com.baeldung.cloud.openfeign.client; + +import com.baeldung.cloud.openfeign.model.Employee; +import feign.Headers; +import feign.Param; +import feign.RequestLine; + +public interface EmployeeClient { + @RequestLine("GET /empployee/{id}?active={isActive}") + @Headers("Content-Type: application/json") + Employee getEmployee(@Param long id, @Param boolean isActive); +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/controller/EmployeeController.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/controller/EmployeeController.java new file mode 100644 index 0000000000..65897ad48e --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/controller/EmployeeController.java @@ -0,0 +1,22 @@ +package com.baeldung.cloud.openfeign.controller; + +import com.baeldung.cloud.openfeign.client.EmployeeClient; +import com.baeldung.cloud.openfeign.model.Employee; +import feign.Feign; +import feign.form.spring.SpringFormEncoder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class EmployeeController { + + private static final String HTTP_FILE_EMPLOYEE_URL = "http://localhost:8081"; + + @GetMapping("/employee/{id}") + public Employee getEmployee(@RequestParam("id") long id) { + EmployeeClient employeeResource = Feign.builder().encoder(new SpringFormEncoder()) + .target(EmployeeClient.class, HTTP_FILE_EMPLOYEE_URL); + return employeeResource.getEmployee(id, true); + } +} diff --git a/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/model/Employee.java b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/model/Employee.java new file mode 100644 index 0000000000..7b8ed1232b --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/model/Employee.java @@ -0,0 +1,15 @@ +package com.baeldung.cloud.openfeign.model; + +public class Employee { + + private Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenfeignManualTest.java b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignManualTest.java similarity index 96% rename from spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenfeignManualTest.java rename to spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignManualTest.java index 8ae6883519..4eb014de96 100644 --- a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenfeignManualTest.java +++ b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignManualTest.java @@ -15,7 +15,7 @@ import static org.junit.Assert.assertNotNull; @RunWith(SpringRunner.class) @SpringBootTest -public class OpenfeignManualTest { +public class OpenFeignManualTest { @Autowired private JSONPlaceHolderService jsonPlaceHolderService; diff --git a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignOAuth2ManualTest.java b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignOAuth2ManualTest.java new file mode 100644 index 0000000000..8084fd23cd --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/OpenFeignOAuth2ManualTest.java @@ -0,0 +1,44 @@ +package com.baeldung.cloud.openfeign; + +import com.baeldung.cloud.openfeign.client.PaymentClient; +import com.baeldung.cloud.openfeign.model.Payment; +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.test.context.junit4.SpringRunner; + +import java.util.List; + +import static org.junit.Assert.assertFalse; + +/** + * This test can be used to verify OAuth2 Token functionality with Feign client + * (https://www.baeldung.com/spring-cloud-feign-oauth-token). + * + * The following components should be setup and running, as described in the article, prior to running this test. + * + * Authorization Server - embedded Keycloak server with the correct client and client-secret defined in the master realm. + * This will issue the auth tokens used by Feign client. + * Further details are available at: https://www.baeldung.com/keycloak-embedded-in-spring-boot-app + * + * Resource Server - OAuth resource server requiring valid JWT token (issued by the Authorization Server). + * Further details are available at: https://www.baeldung.com/spring-security-oauth-resource-server + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class OpenFeignOAuth2ManualTest { + + @Autowired + private PaymentClient paymentClient; + + @Test + public void whenGetPayment_thenListPayments() { + + List payments = paymentClient.getPayments(); + + assertFalse(payments.isEmpty()); + } + +} diff --git a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/PaymentClientUnitTest.java b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/PaymentClientUnitTest.java deleted file mode 100644 index 0372728515..0000000000 --- a/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/PaymentClientUnitTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.baeldung.cloud.openfeign; - -import com.baeldung.cloud.openfeign.client.PaymentClient; -import com.baeldung.cloud.openfeign.model.Payment; -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.test.context.junit4.SpringRunner; - -import java.util.List; - -import static org.junit.Assert.assertFalse; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class PaymentClientUnitTest { - - @Autowired - private PaymentClient paymentClient; - - @Test - public void whenGetPayment_thenListPayments() { - - List payments = paymentClient.getPayments(); - - assertFalse(payments.isEmpty()); - } - -} diff --git a/spring-cloud/spring-cloud-security/auth-client/pom.xml b/spring-cloud/spring-cloud-security/auth-client/pom.xml index cdbb056a45..1ec56ce9ef 100644 --- a/spring-cloud/spring-cloud-security/auth-client/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-client/pom.xml @@ -9,7 +9,7 @@ Spring Cloud Security APP Client Module - com.baeldung + com.baeldung.spring.cloud spring-cloud-security 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-security/auth-resource/pom.xml b/spring-cloud/spring-cloud-security/auth-resource/pom.xml index c999030c07..9362a71931 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-resource/pom.xml @@ -9,7 +9,7 @@ Spring Cloud Security APP Resource Module - com.baeldung + com.baeldung.spring.cloud spring-cloud-security 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-security/auth-server/pom.xml b/spring-cloud/spring-cloud-security/auth-server/pom.xml index c0330aad43..234d9cde78 100644 --- a/spring-cloud/spring-cloud-security/auth-server/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-server/pom.xml @@ -8,7 +8,7 @@ Spring Cloud Security APP Server Module - com.baeldung + com.baeldung.spring.cloud spring-cloud-security 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/schema/Employee.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/schema/Employee.java new file mode 100644 index 0000000000..a805491cea --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/schema/Employee.java @@ -0,0 +1,517 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.baeldung.schema; + +import org.apache.avro.specific.SpecificData; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@SuppressWarnings("all") +@org.apache.avro.specific.AvroGenerated +public class Employee extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = 7340575283344282036L; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"Employee\",\"namespace\":\"com.baeldung.schema\",\"fields\":[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"firstName\",\"type\":\"string\"},{\"name\":\"lastName\",\"type\":\"string\"},{\"name\":\"department\",\"type\":\"string\",\"default\":\"IT \"},{\"name\":\"designation\",\"type\":\"string\",\"default\":\"Software Engineer\"}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static SpecificData MODEL$ = new SpecificData(); + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** Serializes this Employee to a ByteBuffer. */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** Deserializes a Employee from a ByteBuffer. */ + public static Employee fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + @Deprecated public int id; + @Deprecated public java.lang.CharSequence firstName; + @Deprecated public java.lang.CharSequence lastName; + @Deprecated public java.lang.CharSequence department; + @Deprecated public java.lang.CharSequence designation; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public Employee() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param firstName The new value for firstName + * @param lastName The new value for lastName + * @param department The new value for department + * @param designation The new value for designation + */ + public Employee(java.lang.Integer id, java.lang.CharSequence firstName, java.lang.CharSequence lastName, java.lang.CharSequence department, java.lang.CharSequence designation) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.department = department; + this.designation = designation; + } + + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return firstName; + case 2: return lastName; + case 3: return department; + case 4: return designation; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = (java.lang.Integer)value$; break; + case 1: firstName = (java.lang.CharSequence)value$; break; + case 2: lastName = (java.lang.CharSequence)value$; break; + case 3: department = (java.lang.CharSequence)value$; break; + case 4: designation = (java.lang.CharSequence)value$; break; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.Integer getId() { + return id; + } + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.Integer value) { + this.id = value; + } + + /** + * Gets the value of the 'firstName' field. + * @return The value of the 'firstName' field. + */ + public java.lang.CharSequence getFirstName() { + return firstName; + } + + /** + * Sets the value of the 'firstName' field. + * @param value the value to set. + */ + public void setFirstName(java.lang.CharSequence value) { + this.firstName = value; + } + + /** + * Gets the value of the 'lastName' field. + * @return The value of the 'lastName' field. + */ + public java.lang.CharSequence getLastName() { + return lastName; + } + + /** + * Sets the value of the 'lastName' field. + * @param value the value to set. + */ + public void setLastName(java.lang.CharSequence value) { + this.lastName = value; + } + + /** + * Gets the value of the 'department' field. + * @return The value of the 'department' field. + */ + public java.lang.CharSequence getDepartment() { + return department; + } + + /** + * Sets the value of the 'department' field. + * @param value the value to set. + */ + public void setDepartment(java.lang.CharSequence value) { + this.department = value; + } + + /** + * Gets the value of the 'designation' field. + * @return The value of the 'designation' field. + */ + public java.lang.CharSequence getDesignation() { + return designation; + } + + /** + * Sets the value of the 'designation' field. + * @param value the value to set. + */ + public void setDesignation(java.lang.CharSequence value) { + this.designation = value; + } + + /** + * Creates a new Employee RecordBuilder. + * @return A new Employee RecordBuilder + */ + public static com.baeldung.schema.Employee.Builder newBuilder() { + return new com.baeldung.schema.Employee.Builder(); + } + + /** + * Creates a new Employee RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new Employee RecordBuilder + */ + public static com.baeldung.schema.Employee.Builder newBuilder(com.baeldung.schema.Employee.Builder other) { + return new com.baeldung.schema.Employee.Builder(other); + } + + /** + * Creates a new Employee RecordBuilder by copying an existing Employee instance. + * @param other The existing instance to copy. + * @return A new Employee RecordBuilder + */ + public static com.baeldung.schema.Employee.Builder newBuilder(com.baeldung.schema.Employee other) { + return new com.baeldung.schema.Employee.Builder(other); + } + + /** + * RecordBuilder for Employee instances. + */ + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private int id; + private java.lang.CharSequence firstName; + private java.lang.CharSequence lastName; + private java.lang.CharSequence department; + private java.lang.CharSequence designation; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.baeldung.schema.Employee.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.firstName)) { + this.firstName = data().deepCopy(fields()[1].schema(), other.firstName); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.lastName)) { + this.lastName = data().deepCopy(fields()[2].schema(), other.lastName); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.department)) { + this.department = data().deepCopy(fields()[3].schema(), other.department); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.designation)) { + this.designation = data().deepCopy(fields()[4].schema(), other.designation); + fieldSetFlags()[4] = true; + } + } + + /** + * Creates a Builder by copying an existing Employee instance + * @param other The existing instance to copy. + */ + private Builder(com.baeldung.schema.Employee other) { + super(SCHEMA$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.firstName)) { + this.firstName = data().deepCopy(fields()[1].schema(), other.firstName); + fieldSetFlags()[1] = true; + } + if (isValidValue(fields()[2], other.lastName)) { + this.lastName = data().deepCopy(fields()[2].schema(), other.lastName); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.department)) { + this.department = data().deepCopy(fields()[3].schema(), other.department); + fieldSetFlags()[3] = true; + } + if (isValidValue(fields()[4], other.designation)) { + this.designation = data().deepCopy(fields()[4].schema(), other.designation); + fieldSetFlags()[4] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.Integer getId() { + return id; + } + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder setId(int value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder clearId() { + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'firstName' field. + * @return The value. + */ + public java.lang.CharSequence getFirstName() { + return firstName; + } + + /** + * Sets the value of the 'firstName' field. + * @param value The value of 'firstName'. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder setFirstName(java.lang.CharSequence value) { + validate(fields()[1], value); + this.firstName = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'firstName' field has been set. + * @return True if the 'firstName' field has been set, false otherwise. + */ + public boolean hasFirstName() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'firstName' field. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder clearFirstName() { + firstName = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'lastName' field. + * @return The value. + */ + public java.lang.CharSequence getLastName() { + return lastName; + } + + /** + * Sets the value of the 'lastName' field. + * @param value The value of 'lastName'. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder setLastName(java.lang.CharSequence value) { + validate(fields()[2], value); + this.lastName = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'lastName' field has been set. + * @return True if the 'lastName' field has been set, false otherwise. + */ + public boolean hasLastName() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'lastName' field. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder clearLastName() { + lastName = null; + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'department' field. + * @return The value. + */ + public java.lang.CharSequence getDepartment() { + return department; + } + + /** + * Sets the value of the 'department' field. + * @param value The value of 'department'. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder setDepartment(java.lang.CharSequence value) { + validate(fields()[3], value); + this.department = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'department' field has been set. + * @return True if the 'department' field has been set, false otherwise. + */ + public boolean hasDepartment() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'department' field. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder clearDepartment() { + department = null; + fieldSetFlags()[3] = false; + return this; + } + + /** + * Gets the value of the 'designation' field. + * @return The value. + */ + public java.lang.CharSequence getDesignation() { + return designation; + } + + /** + * Sets the value of the 'designation' field. + * @param value The value of 'designation'. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder setDesignation(java.lang.CharSequence value) { + validate(fields()[4], value); + this.designation = value; + fieldSetFlags()[4] = true; + return this; + } + + /** + * Checks whether the 'designation' field has been set. + * @return True if the 'designation' field has been set, false otherwise. + */ + public boolean hasDesignation() { + return fieldSetFlags()[4]; + } + + + /** + * Clears the value of the 'designation' field. + * @return This builder. + */ + public com.baeldung.schema.Employee.Builder clearDesignation() { + designation = null; + fieldSetFlags()[4] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public Employee build() { + try { + Employee record = new Employee(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.Integer) defaultValue(fields()[0]); + record.firstName = fieldSetFlags()[1] ? this.firstName : (java.lang.CharSequence) defaultValue(fields()[1]); + record.lastName = fieldSetFlags()[2] ? this.lastName : (java.lang.CharSequence) defaultValue(fields()[2]); + record.department = fieldSetFlags()[3] ? this.department : (java.lang.CharSequence) defaultValue(fields()[3]); + record.designation = fieldSetFlags()[4] ? this.designation : (java.lang.CharSequence) defaultValue(fields()[4]); + return record; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/schema/EmployeeKey.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/schema/EmployeeKey.java new file mode 100644 index 0000000000..bfd87751a4 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-kafka/src/main/java/com/baeldung/schema/EmployeeKey.java @@ -0,0 +1,307 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.baeldung.schema; + +import org.apache.avro.specific.SpecificData; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@SuppressWarnings("all") +@org.apache.avro.specific.AvroGenerated +public class EmployeeKey extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = 5288483459411046896L; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"EmployeeKey\",\"namespace\":\"com.baeldung.schema\",\"fields\":[{\"name\":\"id\",\"type\":\"int\"},{\"name\":\"departmentName\",\"type\":\"string\"}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static SpecificData MODEL$ = new SpecificData(); + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** Serializes this EmployeeKey to a ByteBuffer. */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** Deserializes a EmployeeKey from a ByteBuffer. */ + public static EmployeeKey fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + @Deprecated public int id; + @Deprecated public java.lang.CharSequence departmentName; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public EmployeeKey() {} + + /** + * All-args constructor. + * @param id The new value for id + * @param departmentName The new value for departmentName + */ + public EmployeeKey(java.lang.Integer id, java.lang.CharSequence departmentName) { + this.id = id; + this.departmentName = departmentName; + } + + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return id; + case 1: return departmentName; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: id = (java.lang.Integer)value$; break; + case 1: departmentName = (java.lang.CharSequence)value$; break; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + /** + * Gets the value of the 'id' field. + * @return The value of the 'id' field. + */ + public java.lang.Integer getId() { + return id; + } + + /** + * Sets the value of the 'id' field. + * @param value the value to set. + */ + public void setId(java.lang.Integer value) { + this.id = value; + } + + /** + * Gets the value of the 'departmentName' field. + * @return The value of the 'departmentName' field. + */ + public java.lang.CharSequence getDepartmentName() { + return departmentName; + } + + /** + * Sets the value of the 'departmentName' field. + * @param value the value to set. + */ + public void setDepartmentName(java.lang.CharSequence value) { + this.departmentName = value; + } + + /** + * Creates a new EmployeeKey RecordBuilder. + * @return A new EmployeeKey RecordBuilder + */ + public static com.baeldung.schema.EmployeeKey.Builder newBuilder() { + return new com.baeldung.schema.EmployeeKey.Builder(); + } + + /** + * Creates a new EmployeeKey RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new EmployeeKey RecordBuilder + */ + public static com.baeldung.schema.EmployeeKey.Builder newBuilder(com.baeldung.schema.EmployeeKey.Builder other) { + return new com.baeldung.schema.EmployeeKey.Builder(other); + } + + /** + * Creates a new EmployeeKey RecordBuilder by copying an existing EmployeeKey instance. + * @param other The existing instance to copy. + * @return A new EmployeeKey RecordBuilder + */ + public static com.baeldung.schema.EmployeeKey.Builder newBuilder(com.baeldung.schema.EmployeeKey other) { + return new com.baeldung.schema.EmployeeKey.Builder(other); + } + + /** + * RecordBuilder for EmployeeKey instances. + */ + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private int id; + private java.lang.CharSequence departmentName; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(com.baeldung.schema.EmployeeKey.Builder other) { + super(other); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.departmentName)) { + this.departmentName = data().deepCopy(fields()[1].schema(), other.departmentName); + fieldSetFlags()[1] = true; + } + } + + /** + * Creates a Builder by copying an existing EmployeeKey instance + * @param other The existing instance to copy. + */ + private Builder(com.baeldung.schema.EmployeeKey other) { + super(SCHEMA$); + if (isValidValue(fields()[0], other.id)) { + this.id = data().deepCopy(fields()[0].schema(), other.id); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.departmentName)) { + this.departmentName = data().deepCopy(fields()[1].schema(), other.departmentName); + fieldSetFlags()[1] = true; + } + } + + /** + * Gets the value of the 'id' field. + * @return The value. + */ + public java.lang.Integer getId() { + return id; + } + + /** + * Sets the value of the 'id' field. + * @param value The value of 'id'. + * @return This builder. + */ + public com.baeldung.schema.EmployeeKey.Builder setId(int value) { + validate(fields()[0], value); + this.id = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'id' field has been set. + * @return True if the 'id' field has been set, false otherwise. + */ + public boolean hasId() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'id' field. + * @return This builder. + */ + public com.baeldung.schema.EmployeeKey.Builder clearId() { + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'departmentName' field. + * @return The value. + */ + public java.lang.CharSequence getDepartmentName() { + return departmentName; + } + + /** + * Sets the value of the 'departmentName' field. + * @param value The value of 'departmentName'. + * @return This builder. + */ + public com.baeldung.schema.EmployeeKey.Builder setDepartmentName(java.lang.CharSequence value) { + validate(fields()[1], value); + this.departmentName = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'departmentName' field has been set. + * @return True if the 'departmentName' field has been set, false otherwise. + */ + public boolean hasDepartmentName() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'departmentName' field. + * @return This builder. + */ + public com.baeldung.schema.EmployeeKey.Builder clearDepartmentName() { + departmentName = null; + fieldSetFlags()[1] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public EmployeeKey build() { + try { + EmployeeKey record = new EmployeeKey(); + record.id = fieldSetFlags()[0] ? this.id : (java.lang.Integer) defaultValue(fields()[0]); + record.departmentName = fieldSetFlags()[1] ? this.departmentName : (java.lang.CharSequence) defaultValue(fields()[1]); + return record; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} diff --git a/spring-core-5/README.md b/spring-core-5/README.md index b6c9ba606a..ebf62ac24f 100644 --- a/spring-core-5/README.md +++ b/spring-core-5/README.md @@ -10,4 +10,5 @@ This module contains articles about core Spring functionality. - [AliasFor Annotation in Spring](https://www.baeldung.com/spring-aliasfor-annotation) - [A Quick Guide to the Spring @Lazy Annotation](https://www.baeldung.com/spring-lazy-annotation) - [Finding the Spring Version](https://www.baeldung.com/spring-find-version) +- [How Does the Spring Singleton Bean Serve Concurrent Requests?](https://www.baeldung.com/spring-singleton-concurrent-requests) - More articles: [[<-- prev]](../spring-core-4) diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java new file mode 100644 index 0000000000..21d031555b --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java @@ -0,0 +1,11 @@ +package com.baeldung.concurrentrequest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConcurrentRequestApplication { + public static void main(String[] args) { + SpringApplication.run(ConcurrentRequestApplication.class, args); + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Product.java b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Product.java new file mode 100644 index 0000000000..30a47d27bc --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Product.java @@ -0,0 +1,26 @@ +package com.baeldung.concurrentrequest; + +public class Product { + + private final int id; + private final String name; + private final Stock stock; + + public Product(int id, String name, Stock stock) { + this.id = id; + this.name = name; + this.stock = stock; + } + + public Stock getStock() { + return stock; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductController.java b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductController.java new file mode 100644 index 0000000000..11f824ddda --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductController.java @@ -0,0 +1,30 @@ +package com.baeldung.concurrentrequest; + +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; + +@RestController() +@RequestMapping("product") +public class ProductController { + + private final ProductService productService; + + public ProductController(ProductService productService) { + this.productService = productService; + } + + @GetMapping("/{id}") + public Product getProductDetails(@PathVariable("id") int productId) { + return productService.getProductById(productId) + .orElse(null); + } + + @GetMapping("{id}/stock") + public Stock getProductStock(@PathVariable("id") int productId) { + return productService.getProductById(productId) + .map(Product::getStock) + .orElse(null); + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductService.java b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductService.java new file mode 100644 index 0000000000..447c450213 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/ProductService.java @@ -0,0 +1,32 @@ +package com.baeldung.concurrentrequest; + +import static java.lang.Thread.currentThread; +import static java.util.Arrays.asList; + +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +@Service +public class ProductService { + + // @formatter:off + private final static List productRepository = asList( + new Product(1, "Product 1", new Stock(100)), + new Product(2, "Product 2", new Stock(50)) + ); + // @formatter:on + + public Optional getProductById(int id) { + Optional product = productRepository.stream() + .filter(p -> p.getId() == id) + .findFirst(); + String productName = product.map(Product::getName) + .orElse(null); + + System.out.printf("Thread: %s; bean instance: %s; product id: %s has the name: %s%n", currentThread().getName(), this, id, productName); + + return product; + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Stock.java b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Stock.java new file mode 100644 index 0000000000..bb7860f5be --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/concurrentrequest/Stock.java @@ -0,0 +1,13 @@ +package com.baeldung.concurrentrequest; + +public class Stock { + private final int inStockItems; + + public Stock(int inStockItems) { + this.inStockItems = inStockItems; + } + + public int getInStockItems() { + return inStockItems; + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestUnitTest.java b/spring-core-5/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestUnitTest.java new file mode 100644 index 0000000000..76a0d764e1 --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/concurrentrequest/ConcurrentRequestUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung.concurrentrequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +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.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultMatcher; + +@SpringBootTest +@AutoConfigureMockMvc +public class ConcurrentRequestUnitTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ProductController controller; + + @Test + public void givenContextLoads_thenProductControllerIsAvailable() { + assertThat(controller).isNotNull(); + } + + @Test + public void givenMultipleCallsRunInParallel_thenAllCallsReturn200() throws Exception { + ExecutorService executor = Executors.newFixedThreadPool(2); + + executor.submit(() -> performCall("/product/1", status().isOk())); + executor.submit(() -> performCall("/product/2/stock", status().isOk())); + + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } + + private void performCall(String url, ResultMatcher expect) { + try { + this.mockMvc.perform(get(url)) + .andExpect(expect); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/spring-di-3/README.md b/spring-di-3/README.md index 4246069616..3ddd720af5 100644 --- a/spring-di-3/README.md +++ b/spring-di-3/README.md @@ -6,4 +6,5 @@ This module contains articles about dependency injection with Spring - [@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) +- [Finding All Beans with a Custom Annotation](https://www.baeldung.com/spring-injecting-all-annotated-beans) - More articles: [[<-- prev]](../spring-di-2) diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java index b4a03a12b0..0b6b7cce8b 100644 --- a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java @@ -1,7 +1,6 @@ package com.baeldung.kafka.embedded; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication diff --git a/spring-kafka/src/main/resources/application.properties b/spring-kafka/src/main/resources/application.properties index e1a983339b..9a614cbafd 100644 --- a/spring-kafka/src/main/resources/application.properties +++ b/spring-kafka/src/main/resources/application.properties @@ -13,4 +13,5 @@ monitor.topic.name=baeldung # monitoring - simulation monitor.producer.simulate=true monitor.consumer.simulate=true -monitor.kafka.consumer.groupid.simulate=baeldungGrpSimulate \ No newline at end of file +monitor.kafka.consumer.groupid.simulate=baeldungGrpSimulate +test.topic=testtopic1 diff --git a/spring-reactive/pom.xml b/spring-reactive/pom.xml index 37df1a820d..396fa3ee4a 100644 --- a/spring-reactive/pom.xml +++ b/spring-reactive/pom.xml @@ -59,7 +59,6 @@ integration-lite-first - @@ -76,7 +75,6 @@ integration-lite-second - diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java index c40db74003..50579d8721 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java @@ -3,23 +3,16 @@ package com.baeldung.reactive.errorhandling; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -@SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class) +@SpringBootApplication(exclude = { + MongoReactiveAutoConfiguration.class, + ReactiveSecurityAutoConfiguration.class, + ReactiveUserDetailsServiceAutoConfiguration.class }) public class ErrorHandlingApplication { public static void main(String[] args) { SpringApplication.run(ErrorHandlingApplication.class, args); } - - @Bean - public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { - http.authorizeExchange() - .anyExchange() - .permitAll(); - http.csrf().disable(); - return http.build(); - } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java index 0a96a8593c..3458a175e4 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java @@ -9,44 +9,14 @@ import org.springframework.web.reactive.function.server.ServerRequest; import java.util.Map; @Component -public class GlobalErrorAttributes extends DefaultErrorAttributes{ - - private HttpStatus status = HttpStatus.BAD_REQUEST; - private String message = "please provide a name"; +public class GlobalErrorAttributes extends DefaultErrorAttributes { @Override public Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { Map map = super.getErrorAttributes(request, options); - map.put("status", getStatus()); - map.put("message", getMessage()); + map.put("status", HttpStatus.BAD_REQUEST); + map.put("message", "please provide a name"); return map; } - /** - * @return the status - */ - public HttpStatus getStatus() { - return status; - } - - /** - * @param status the status to set - */ - public void setStatus(HttpStatus status) { - this.status = status; - } - - /** - * @return the message - */ - public String getMessage() { - return message; - } - - /** - * @param message the message to set - */ - public void setMessage(String message) { - this.message = message; - } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Handler.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Handler.java new file mode 100644 index 0000000000..d49d9b4be2 --- /dev/null +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Handler.java @@ -0,0 +1,67 @@ +package com.baeldung.reactive.errorhandling; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler { + + public Mono handleWithErrorReturn(ServerRequest request) { + return sayHello(request) + .onErrorReturn("Hello, Stranger") + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s)); + } + + public Mono handleWithErrorResumeAndDynamicFallback(ServerRequest request) { + return sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s)) + .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + e.getMessage())) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s))); + } + + public Mono handleWithErrorResumeAndFallbackMethod(ServerRequest request) { + return sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s)) + .onErrorResume(e -> sayHelloFallback() + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s))); + } + + public Mono handleWithErrorResumeAndCustomException(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request) + .onErrorResume(e -> Mono.error(new NameRequiredException( + HttpStatus.BAD_REQUEST, + "please provide a name", e))), String.class); + } + + public Mono handleWithGlobalErrorHandler(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request), String.class); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name").get()); + } catch (Exception e) { + return Mono.error(e); + } + } + + private Mono sayHelloFallback() { + return Mono.just("Hello, Stranger"); + } +} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Router.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Router.java new file mode 100644 index 0000000000..5f130ec035 --- /dev/null +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Router.java @@ -0,0 +1,26 @@ +package com.baeldung.reactive.errorhandling; + +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import static org.springframework.http.MediaType.TEXT_PLAIN; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.accept; + +@Component +public class Router { + + @Bean + public RouterFunction routes(Handler handler) { + return RouterFunctions + .route(GET("/api/endpoint1").and(accept(TEXT_PLAIN)), handler::handleWithErrorReturn) + .andRoute(GET("/api/endpoint2").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndFallbackMethod) + .andRoute(GET("/api/endpoint3").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndDynamicFallback) + .andRoute(GET("/api/endpoint4").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndCustomException) + .andRoute(GET("/api/endpoint5").and(accept(TEXT_PLAIN)), handler::handleWithGlobalErrorHandler); + } + +} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java deleted file mode 100644 index 32f2f1c3a2..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler1 { - - public Mono handleRequest1(ServerRequest request) { - return sayHello(request).onErrorReturn("Hello, Stranger") - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s)); - } - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name") - .get()); - } catch (Exception e) { - return Mono.error(e); - } - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java deleted file mode 100644 index 093120c92b..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler2 { - -public Mono handleRequest2(ServerRequest request) { - return - sayHello(request) - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s)) - .onErrorResume(e -> sayHelloFallback() - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s))); -} - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name") - .get()); - } catch (Exception e) { - return Mono.error(e); - } - } - - private Mono sayHelloFallback() { - return Mono.just("Hello, Stranger"); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java deleted file mode 100644 index 44842e0539..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler3 { - - public Mono handleRequest3(ServerRequest request) { - return - sayHello(request) - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s)) - .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + - e.getMessage())).flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s))); - } - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name") - .get()); - } catch (Exception e) { - return Mono.error(e); - } - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java deleted file mode 100644 index 2d391a42a7..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import com.baeldung.reactive.errorhandling.NameRequiredException; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler4 { - -public Mono handleRequest4(ServerRequest request) { - return ServerResponse.ok() - .body(sayHello(request) - .onErrorResume(e -> - Mono.error(new NameRequiredException( - HttpStatus.BAD_REQUEST, "please provide a name", e))), String.class); -} - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name").get()); - } catch (Exception e) { - return Mono.error(e); - } - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java deleted file mode 100644 index a466982865..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler5 { - - public Mono handleRequest5(ServerRequest request) { - return ServerResponse.ok() - .body(sayHello(request), String.class); - - } - - private Mono sayHello(ServerRequest request) { - return Mono.just("Hello, " + request.queryParam("name").get()); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java deleted file mode 100644 index caf779b456..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler1; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router1 { - - @Bean - public RouterFunction routeRequest1(Handler1 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint1") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest1); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java deleted file mode 100644 index b965257c30..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler2; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router2 { - - @Bean - public RouterFunction routeRequest2(Handler2 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint2") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest2); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java deleted file mode 100644 index b8f7f983cc..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler3; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router3 { - - @Bean - public RouterFunction routeRequest3(Handler3 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint3") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest3); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java deleted file mode 100644 index 03c65fec67..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler4; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router4 { - - @Bean - public RouterFunction routeRequest4(Handler4 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint4") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest4); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java deleted file mode 100644 index c68e04659f..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler5; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router5 { - - @Bean - public RouterFunction routeRequest5(Handler5 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint5") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest5); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetController.java b/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetController.java deleted file mode 100644 index 99b79d88ea..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetController.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.reactive.security; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import reactor.core.publisher.Mono; - -import java.security.Principal; - -@RestController -public class GreetController { - - private GreetService greetService; - - public GreetController(GreetService greetService) { - this.greetService = greetService; - } - - @GetMapping("/") - public Mono greet(Mono principal) { - return principal - .map(Principal::getName) - .map(name -> String.format("Hello, %s", name)); - } - - @GetMapping("/admin") - public Mono greetAdmin(Mono principal) { - return principal - .map(Principal::getName) - .map(name -> String.format("Admin access: %s", name)); - } - - @GetMapping("/greetService") - public Mono greetService() { - return greetService.greet(); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetingController.java b/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetingController.java new file mode 100644 index 0000000000..10d6cf4df7 --- /dev/null +++ b/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetingController.java @@ -0,0 +1,37 @@ +package com.baeldung.reactive.security; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +import java.security.Principal; + +@RestController +public class GreetingController { + + private final GreetingService greetingService; + + public GreetingController(GreetingService greetingService) { + this.greetingService = greetingService; + } + + @GetMapping("/") + public Mono greet(Mono principal) { + return principal + .map(Principal::getName) + .map(name -> String.format("Hello, %s", name)); + } + + @GetMapping("/admin") + public Mono greetAdmin(Mono principal) { + return principal + .map(Principal::getName) + .map(name -> String.format("Admin access: %s", name)); + } + + @GetMapping("/greetingService") + public Mono greetingService() { + return greetingService.greet(); + } + +} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetService.java b/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetingService.java similarity index 91% rename from spring-reactive/src/main/java/com/baeldung/reactive/security/GreetService.java rename to spring-reactive/src/main/java/com/baeldung/reactive/security/GreetingService.java index 93df64bced..b512f12bae 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetService.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/security/GreetingService.java @@ -5,7 +5,7 @@ import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; @Service -public class GreetService { +public class GreetingService { @PreAuthorize("hasRole('ADMIN')") public Mono greet() { diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java b/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java index bb2f2d50e1..67e54ad26a 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java @@ -16,40 +16,37 @@ import org.springframework.security.web.server.SecurityWebFilterChain; public class SecurityConfig { @Bean - public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { + public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { return http.authorizeExchange() - .pathMatchers("/admin") - .hasAuthority("ROLE_ADMIN") - .anyExchange() - .authenticated() - .and() - .formLogin() - .and() - .csrf() - .disable() - .build(); + .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") + .anyExchange().authenticated() + .and() + .formLogin() + .and() + .csrf().disable() + .build(); } @Bean public MapReactiveUserDetailsService userDetailsService() { UserDetails user = User - .withUsername("user") - .password(passwordEncoder().encode("password")) - .roles("USER") - .build(); + .withUsername("user") + .password(passwordEncoder().encode("password")) + .roles("USER") + .build(); UserDetails admin = User - .withUsername("admin") - .password(passwordEncoder().encode("password")) - .roles("ADMIN") - .build(); + .withUsername("admin") + .password(passwordEncoder().encode("password")) + .roles("ADMIN") + .build(); return new MapReactiveUserDetailsService(user, admin); } - + @Bean public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + return new BCryptPasswordEncoder(); } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webclient/Foo.java b/spring-reactive/src/main/java/com/baeldung/reactive/webclient/Foo.java index a58d672686..246ba30667 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webclient/Foo.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webclient/Foo.java @@ -1,24 +1,14 @@ package com.baeldung.reactive.webclient; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor public class Foo { private String name; - public Foo() { - super(); - } - - public Foo(String name) { - super(); - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java b/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java index fd1cb8aff1..3a62e7b8a5 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java @@ -15,11 +15,10 @@ public class WebClientApplication { } @Bean - public SecurityWebFilterChain functionalValidationsSpringSecurityFilterChain(ServerHttpSecurity http) { - http.authorizeExchange() - .anyExchange() - .permitAll(); - http.csrf().disable(); + public SecurityWebFilterChain filterChain(ServerHttpSecurity http) { + http.csrf().disable() + .authorizeExchange() + .anyExchange().permitAll(); return http.build(); } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/Employee.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/Employee.java index d41a4f2791..dd88dcb668 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/Employee.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/Employee.java @@ -11,7 +11,5 @@ public class Employee { private String id; private String name; - - // standard getters and setters - + } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/EmployeeRepository.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/EmployeeRepository.java index 9aebc577b0..01d32ea57a 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/EmployeeRepository.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/EmployeeRepository.java @@ -10,46 +10,32 @@ import java.util.Map; @Repository public class EmployeeRepository { - static Map employeeData; - - static Map employeeAccessData; + private static final Map EMPLOYEE_DATA; static { - employeeData = new HashMap<>(); - employeeData.put("1", new Employee("1", "Employee 1")); - employeeData.put("2", new Employee("2", "Employee 2")); - employeeData.put("3", new Employee("3", "Employee 3")); - employeeData.put("4", new Employee("4", "Employee 4")); - employeeData.put("5", new Employee("5", "Employee 5")); - employeeData.put("6", new Employee("6", "Employee 6")); - employeeData.put("7", new Employee("7", "Employee 7")); - employeeData.put("8", new Employee("8", "Employee 8")); - employeeData.put("9", new Employee("9", "Employee 9")); - employeeData.put("10", new Employee("10", "Employee 10")); - - employeeAccessData = new HashMap<>(); - employeeAccessData.put("1", "Employee 1 Access Key"); - employeeAccessData.put("2", "Employee 2 Access Key"); - employeeAccessData.put("3", "Employee 3 Access Key"); - employeeAccessData.put("4", "Employee 4 Access Key"); - employeeAccessData.put("5", "Employee 5 Access Key"); - employeeAccessData.put("6", "Employee 6 Access Key"); - employeeAccessData.put("7", "Employee 7 Access Key"); - employeeAccessData.put("8", "Employee 8 Access Key"); - employeeAccessData.put("9", "Employee 9 Access Key"); - employeeAccessData.put("10", "Employee 10 Access Key"); + EMPLOYEE_DATA = new HashMap<>(); + EMPLOYEE_DATA.put("1", new Employee("1", "Employee 1")); + EMPLOYEE_DATA.put("2", new Employee("2", "Employee 2")); + EMPLOYEE_DATA.put("3", new Employee("3", "Employee 3")); + EMPLOYEE_DATA.put("4", new Employee("4", "Employee 4")); + EMPLOYEE_DATA.put("5", new Employee("5", "Employee 5")); + EMPLOYEE_DATA.put("6", new Employee("6", "Employee 6")); + EMPLOYEE_DATA.put("7", new Employee("7", "Employee 7")); + EMPLOYEE_DATA.put("8", new Employee("8", "Employee 8")); + EMPLOYEE_DATA.put("9", new Employee("9", "Employee 9")); + EMPLOYEE_DATA.put("10", new Employee("10", "Employee 10")); } public Mono findEmployeeById(String id) { - return Mono.just(employeeData.get(id)); + return Mono.just(EMPLOYEE_DATA.get(id)); } public Flux findAllEmployees() { - return Flux.fromIterable(employeeData.values()); + return Flux.fromIterable(EMPLOYEE_DATA.values()); } public Mono updateEmployee(Employee employee) { - Employee existingEmployee = employeeData.get(employee.getId()); + Employee existingEmployee = EMPLOYEE_DATA.get(employee.getId()); if (existingEmployee != null) { existingEmployee.setName(employee.getName()); } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeSpringApplication.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeSpringApplication.java index f1d21bdc77..0e3cc6bf99 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeSpringApplication.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeSpringApplication.java @@ -1,12 +1,19 @@ package com.baeldung.reactive.webflux.annotation; +import com.baeldung.reactive.webflux.EmployeeRepository; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.context.annotation.Bean; @SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class) public class EmployeeSpringApplication { + @Bean + EmployeeRepository employeeRepository() { + return new EmployeeRepository(); + } + public static void main(String[] args) { SpringApplication.run(EmployeeSpringApplication.class, args); diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebClient.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebClient.java index 611a261a1b..5ae193dc7c 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebClient.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebClient.java @@ -10,23 +10,23 @@ import reactor.core.publisher.Mono; public class EmployeeWebClient { private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeWebClient.class); - + WebClient client = WebClient.create("http://localhost:8080"); - + public void consume() { Mono employeeMono = client.get() - .uri("/employees/{id}", "1") - .retrieve() - .bodyToMono(Employee.class); + .uri("/employees/{id}", "1") + .retrieve() + .bodyToMono(Employee.class); + + employeeMono.subscribe(employee -> LOGGER.info("Employee: {}", employee)); - employeeMono.subscribe(employee -> LOGGER.debug("Employee: {}", employee)); - Flux employeeFlux = client.get() - .uri("/employees") - .retrieve() - .bodyToFlux(Employee.class); - - employeeFlux.subscribe(employee -> LOGGER.debug("Employee: {}", employee)); + .uri("/employees") + .retrieve() + .bodyToFlux(Employee.class); + + employeeFlux.subscribe(employee -> LOGGER.info("Employee: {}", employee)); } -} \ No newline at end of file +} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java index 8dfa455ce3..fc98b70c0f 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java @@ -13,33 +13,31 @@ import org.springframework.security.web.server.SecurityWebFilterChain; @EnableWebFluxSecurity public class EmployeeWebSecurityConfig { - + @Bean public MapReactiveUserDetailsService userDetailsService() { UserDetails user = User - .withUsername("admin") - .password(passwordEncoder().encode("password")) - .roles("ADMIN") - .build(); + .withUsername("admin") + .password(passwordEncoder().encode("password")) + .roles("ADMIN") + .build(); return new MapReactiveUserDetailsService(user); } @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { - http.csrf() - .disable() - .authorizeExchange() - .pathMatchers(HttpMethod.POST, "/employees/update") - .hasRole("ADMIN") - .pathMatchers("/**") - .permitAll() - .and() - .httpBasic(); + http + .csrf().disable() + .authorizeExchange() + .pathMatchers(HttpMethod.POST, "/employees/update").hasRole("ADMIN") + .pathMatchers("/**").permitAll() + .and() + .httpBasic(); return http.build(); } - + @Bean public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + return new BCryptPasswordEncoder(); } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java index f97d40e4e7..8b5c7233d6 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java @@ -25,50 +25,49 @@ public class EmployeeFunctionalConfig { @Bean RouterFunction getAllEmployeesRoute() { - return route(GET("/employees"), - req -> ok().body( - employeeRepository().findAllEmployees(), Employee.class)); + return route(GET("/employees"), + req -> ok().body( + employeeRepository().findAllEmployees(), Employee.class)); } @Bean RouterFunction getEmployeeByIdRoute() { - return route(GET("/employees/{id}"), - req -> ok().body( - employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); + return route(GET("/employees/{id}"), + req -> ok().body( + employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); } @Bean RouterFunction updateEmployeeRoute() { - return route(POST("/employees/update"), - req -> req.body(toMono(Employee.class)) - .doOnNext(employeeRepository()::updateEmployee) - .then(ok().build())); + return route(POST("/employees/update"), + req -> req.body(toMono(Employee.class)) + .doOnNext(employeeRepository()::updateEmployee) + .then(ok().build())); } @Bean RouterFunction composedRoutes() { - return - route(GET("/employees"), + return + route(GET("/employees"), req -> ok().body( employeeRepository().findAllEmployees(), Employee.class)) - - .and(route(GET("/employees/{id}"), - req -> ok().body( - employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class))) - - .and(route(POST("/employees/update"), - req -> req.body(toMono(Employee.class)) - .doOnNext(employeeRepository()::updateEmployee) - .then(ok().build()))); + + .and(route(GET("/employees/{id}"), + req -> ok().body( + employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class))) + + .and(route(POST("/employees/update"), + req -> req.body(toMono(Employee.class)) + .doOnNext(employeeRepository()::updateEmployee) + .then(ok().build()))); } @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { - http.csrf() - .disable() - .authorizeExchange() - .anyExchange() - .permitAll(); + http + .csrf().disable() + .authorizeExchange() + .anyExchange().permitAll(); return http.build(); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java index 1167792542..bbcab179eb 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java @@ -7,19 +7,13 @@ import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWeb import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -import java.io.IOException; - -import static org.junit.Assert.assertEquals; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @DirtiesContext -@WithMockUser @AutoConfigureWebTestClient(timeout = "10000") public class ErrorHandlingIntegrationTest { @@ -27,150 +21,107 @@ public class ErrorHandlingIntegrationTest { private WebTestClient webTestClient; @Test - public void givenErrorReturn_whenUsernamePresent_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint1?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - - } - - @Test - public void givenErrorReturn_whenNoUsername_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint1") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Stranger", s); - } - - @Test - public void givenResumeFallback_whenUsernamePresent_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint2?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenResumeFallback_whenNoUsername_thenOk() throws IOException { - String s = webTestClient.get() - .uri("/api/endpoint2") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Stranger", s); - - } - - @Test - public void givenResumeDynamicValue_whenUsernamePresent_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint3?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenResumeDynamicValue_whenNoUsername_thenOk() throws IOException { - String s = webTestClient.get() - .uri("/api/endpoint3") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hi, I looked around for your name but found: No value present", s); - } - - @Test - public void givenResumeRethrow_whenUsernamePresent_thenOk() throws IOException { - String s = webTestClient.get() - .uri("/api/endpoint4?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenResumeRethrow_whenNoUsername_thenOk() throws IOException { + public void givenErrorReturn_whenUsernamePresent_thenOk() { webTestClient.get() - .uri("/api/endpoint4") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isBadRequest() - .expectHeader() - .contentType(MediaType.APPLICATION_JSON) - .expectBody() - .jsonPath("$.message") - .isNotEmpty() - .jsonPath("$.message") - .isEqualTo("please provide a name"); + .uri("/api/endpoint1?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); } @Test - public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() throws IOException { + public void givenErrorReturn_whenNoUsername_thenOk() { - String s = webTestClient.get() - .uri("/api/endpoint5?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenGlobalErrorHandling_whenNoUsername_thenOk() throws IOException { webTestClient.get() - .uri("/api/endpoint5") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isBadRequest() - .expectHeader() - .contentType(MediaType.APPLICATION_JSON) - .expectBody() - .jsonPath("$.message") - .isNotEmpty() - .jsonPath("$.message") - .isEqualTo("please provide a name"); + .uri("/api/endpoint1") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Stranger"); + } + @Test + public void givenResumeFallback_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint2?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenResumeFallback_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint2") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Stranger"); + } + + @Test + public void givenResumeDynamicValue_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint3?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenResumeDynamicValue_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint3") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hi, I looked around for your name but found: No value present"); + } + + @Test + public void givenResumeRethrow_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint4?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenResumeRethrow_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint4") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus().isBadRequest() + .expectHeader().contentType(MediaType.APPLICATION_JSON) + .expectBody().jsonPath("$.message").isEqualTo("please provide a name"); + } + + @Test + public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint5?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenGlobalErrorHandling_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint5") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus().isBadRequest() + .expectHeader().contentType(MediaType.APPLICATION_JSON) + .expectBody().jsonPath("$.message").isEqualTo("please provide a name"); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java index 06644fbf77..0ef828df5a 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java @@ -15,23 +15,32 @@ import org.springframework.test.web.reactive.server.WebTestClient; public class SecurityIntegrationTest { @Autowired - ApplicationContext context; + private ApplicationContext context; - private WebTestClient rest; + private WebTestClient webTestClient; @BeforeEach public void setup() { - this.rest = WebTestClient.bindToApplicationContext(this.context).configureClient().build(); + webTestClient = WebTestClient.bindToApplicationContext(context) + .configureClient() + .build(); } @Test public void whenNoCredentials_thenRedirectToLogin() { - this.rest.get().uri("/").exchange().expectStatus().is3xxRedirection(); + webTestClient.get() + .uri("/") + .exchange() + .expectStatus().is3xxRedirection(); } @Test @WithMockUser public void whenHasCredentials_thenSeesGreeting() { - this.rest.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello, user"); + webTestClient.get() + .uri("/") + .exchange() + .expectStatus().isOk() + .expectBody(String.class).isEqualTo("Hello, user"); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java index 28b4c19a10..22c545c362 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java @@ -45,41 +45,41 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(classes = WebClientApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class WebClientIntegrationTest { - @LocalServerPort - private int port; - private static final String BODY_VALUE = "bodyValue"; private static final ParameterizedTypeReference> MAP_RESPONSE_REF = new ParameterizedTypeReference>() { }; + @LocalServerPort + private int port; + @Test public void givenDifferentWebClientCreationMethods_whenUsed_thenObtainExpectedResponse() { // WebClient creation WebClient client1 = WebClient.create(); WebClient client2 = WebClient.create("http://localhost:" + port); WebClient client3 = WebClient.builder() - .baseUrl("http://localhost:" + port) - .defaultCookie("cookieKey", "cookieValue") - .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080")) - .build(); + .baseUrl("http://localhost:" + port) + .defaultCookie("cookieKey", "cookieValue") + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080")) + .build(); // response assertions StepVerifier.create(retrieveResponse(client1.post() .uri("http://localhost:" + port + "/resource"))) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(client2)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(client3)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); // assert response without specifying URI StepVerifier.create(retrieveResponse(client1)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); + .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() + .contains("Connection refused")) + .verify(); } @Test @@ -91,60 +91,64 @@ public class WebClientIntegrationTest { // response assertions StepVerifier.create(retrieveResponse(uriSpecPost1)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(uriSpecPost2)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveGetResponse(requestGet)) - .expectNextMatches(nextMap -> nextMap.get("field") - .equals("value")) - .verifyComplete(); + .expectNextMatches(nextMap -> nextMap.get("field") + .equals("value")) + .verifyComplete(); } @Test public void givenDifferentUriSpecifications_whenUsed_thenObtainExpectedResponse() { // uri specification RequestBodySpec bodySpecUsingString = createDefaultPostRequest().uri("/resource"); - RequestBodySpec bodySpecUsingUriBuilder = createDefaultPostRequest().uri(uriBuilder -> uriBuilder.pathSegment("resource") + RequestBodySpec bodySpecUsingUriBuilder = createDefaultPostRequest().uri( + uriBuilder -> uriBuilder.pathSegment("resource") .build()); - RequestBodySpec bodySpecusingURI = createDefaultPostRequest().uri(URI.create("http://localhost:" + port + "/resource")); + RequestBodySpec bodySpecusingURI = createDefaultPostRequest().uri( + URI.create("http://localhost:" + port + "/resource")); RequestBodySpec bodySpecOverridenBaseUri = createDefaultPostRequest().uri(URI.create("/resource")); RequestBodySpec bodySpecOverridenBaseUri2 = WebClient.builder() - .baseUrl("http://localhost:" + port) - .build() - .post() - .uri(URI.create("/resource")); + .baseUrl("http://localhost:" + port) + .build() + .post() + .uri(URI.create("/resource")); // response assertions StepVerifier.create(retrieveResponse(bodySpecUsingString)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(bodySpecUsingUriBuilder)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(bodySpecusingURI)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); // assert sending request overriding base URI StepVerifier.create(retrieveResponse(bodySpecOverridenBaseUri)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); + .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() + .contains("Connection refused")) + .verify(); StepVerifier.create(retrieveResponse(bodySpecOverridenBaseUri2)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() - .contains("Connection refused")) - .verify(); + .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ex.getMessage() + .contains("Connection refused")) + .verify(); } @Test public void givenDifferentBodySpecifications_whenUsed_thenObtainExpectedResponse() { // request body specifications - RequestHeadersSpec headersSpecPost1 = createDefaultPostResourceRequest().body(BodyInserters.fromPublisher(Mono.just(BODY_VALUE), String.class)); - RequestHeadersSpec headersSpecPost2 = createDefaultPostResourceRequest().body(BodyInserters.fromValue(BODY_VALUE)); + RequestHeadersSpec headersSpecPost1 = createDefaultPostResourceRequest().body( + BodyInserters.fromPublisher(Mono.just(BODY_VALUE), String.class)); + RequestHeadersSpec headersSpecPost2 = createDefaultPostResourceRequest().body( + BodyInserters.fromValue(BODY_VALUE)); RequestHeadersSpec headersSpecPost3 = createDefaultPostResourceRequest().bodyValue(BODY_VALUE); RequestHeadersSpec headersSpecFooPost = createDefaultPostRequest().uri("/resource-foo") - .body(Mono.just(new Foo("fooName")), Foo.class); + .body(Mono.just(new Foo("fooName")), Foo.class); BodyInserter inserterPlainObject = BodyInserters.fromValue(new Object()); RequestHeadersSpec headersSpecPlainObject = createDefaultPostResourceRequest().body(inserterPlainObject); @@ -152,54 +156,57 @@ public class WebClientIntegrationTest { LinkedMultiValueMap map = new LinkedMultiValueMap<>(); map.add("key1", "multipartValue1"); map.add("key2", "multipartValue2"); - BodyInserter, ClientHttpRequest> inserterMultipart = BodyInserters.fromMultipartData(map); + BodyInserter, ClientHttpRequest> inserterMultipart = BodyInserters.fromMultipartData( + map); RequestHeadersSpec headersSpecInserterMultipart = createDefaultPostRequest().uri("/resource-multipart") - .body(inserterMultipart); + .body(inserterMultipart); // response assertions StepVerifier.create(retrieveResponse(headersSpecPost1)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(headersSpecPost2)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(headersSpecPost3)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(retrieveResponse(headersSpecFooPost)) - .expectNext("processedFoo-fooName") - .verifyComplete(); + .expectNext("processedFoo-fooName") + .verifyComplete(); StepVerifier.create(retrieveResponse(headersSpecInserterMultipart)) - .expectNext("processed-multipartValue1-multipartValue2") - .verifyComplete(); + .expectNext("processed-multipartValue1-multipartValue2") + .verifyComplete(); // assert error plain `new Object()` as request body StepVerifier.create(retrieveResponse(headersSpecPlainObject)) - .expectError(CodecException.class) - .verify(); + .expectError(CodecException.class) + .verify(); // assert response for request with no body - Mono> responsePostWithNoBody = createDefaultPostResourceRequest().exchangeToMono(responseHandler -> { - assertThat(responseHandler.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - return responseHandler.bodyToMono(MAP_RESPONSE_REF); - }); + Mono> responsePostWithNoBody = createDefaultPostResourceRequest().exchangeToMono( + responseHandler -> { + assertThat(responseHandler.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + return responseHandler.bodyToMono(MAP_RESPONSE_REF); + }); StepVerifier.create(responsePostWithNoBody) - .expectNextMatches(nextMap -> nextMap.get("error") - .equals("Bad Request")) - .verifyComplete(); + .expectNextMatches(nextMap -> nextMap.get("error") + .equals("Bad Request")) + .verifyComplete(); } @Test public void givenPostSpecifications_whenHeadersAdded_thenObtainExpectedResponse() { // request header specification - RequestHeadersSpec headersSpecInserterStringWithHeaders = createDefaultPostResourceRequestResponse().header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) - .acceptCharset(StandardCharsets.UTF_8) - .ifNoneMatch("*") - .ifModifiedSince(ZonedDateTime.now()); + RequestHeadersSpec headersSpecInserterStringWithHeaders = createDefaultPostResourceRequestResponse().header( + HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) + .acceptCharset(StandardCharsets.UTF_8) + .ifNoneMatch("*") + .ifModifiedSince(ZonedDateTime.now()); // response assertions StepVerifier.create(retrieveResponse(headersSpecInserterStringWithHeaders)) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); } @Test @@ -209,68 +216,66 @@ public class WebClientIntegrationTest { Mono responsePostString2 = createDefaultPostResourceRequestResponse().exchangeToMono(response -> { if (response.statusCode() == HttpStatus.OK) { return response.bodyToMono(String.class); - } else if (response.statusCode() - .is4xxClientError()) { + } else if (response.statusCode().is4xxClientError()) { return Mono.just("Error response"); } else { return response.createException() - .flatMap(Mono::error); + .flatMap(Mono::error); } }); Mono responsePostNoBody = createDefaultPostResourceRequest().exchangeToMono(response -> { if (response.statusCode() == HttpStatus.OK) { return response.bodyToMono(String.class); - } else if (response.statusCode() - .is4xxClientError()) { + } else if (response.statusCode().is4xxClientError()) { return Mono.just("Error response"); } else { return response.createException() - .flatMap(Mono::error); + .flatMap(Mono::error); } }); Mono> responseGet = createDefaultClient().get() - .uri("/resource") - .retrieve() - .bodyToMono(MAP_RESPONSE_REF); + .uri("/resource") + .retrieve() + .bodyToMono(MAP_RESPONSE_REF); // response assertions StepVerifier.create(responsePostString) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(responsePostString2) - .expectNext("processed-bodyValue") - .verifyComplete(); + .expectNext("processed-bodyValue") + .verifyComplete(); StepVerifier.create(responsePostNoBody) - .expectNext("Error response") - .verifyComplete(); + .expectNext("Error response") + .verifyComplete(); StepVerifier.create(responseGet) - .expectNextMatches(nextMap -> nextMap.get("field") - .equals("value")) - .verifyComplete(); + .expectNextMatches(nextMap -> nextMap.get("field") + .equals("value")) + .verifyComplete(); } @Test public void givenWebClientWithTimeoutConfigurations_whenRequestUsingWronglyConfiguredPublisher_thenObtainTimeout() { HttpClient httpClient = HttpClient.create() - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000) - .responseTimeout(Duration.ofMillis(1000)) - .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(1000, TimeUnit.MILLISECONDS)) - .addHandlerLast(new WriteTimeoutHandler(1000, TimeUnit.MILLISECONDS))); + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000) + .responseTimeout(Duration.ofMillis(1000)) + .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(1000, TimeUnit.MILLISECONDS)) + .addHandlerLast(new WriteTimeoutHandler(1000, TimeUnit.MILLISECONDS))); WebClient timeoutClient = WebClient.builder() - .baseUrl("http://localhost:" + port) - .clientConnector(new ReactorClientHttpConnector(httpClient)) - .build(); + .baseUrl("http://localhost:" + port) + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .build(); RequestHeadersSpec neverendingMonoBodyRequest = timeoutClient.post() - .uri("/resource") - .body(Mono.never(), String.class); + .uri("/resource") + .body(Mono.never(), String.class); StepVerifier.create(neverendingMonoBodyRequest.retrieve() .bodyToMono(String.class)) - .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) && ReadTimeoutException.class.isAssignableFrom(ex.getCause() - .getClass())) - .verify(); + .expectErrorMatches(ex -> WebClientRequestException.class.isAssignableFrom(ex.getClass()) + && ReadTimeoutException.class.isAssignableFrom(ex.getCause().getClass())) + .verify(); } // helper methods to create default instances @@ -293,33 +298,33 @@ public class WebClientIntegrationTest { // helper methods to retrieve a response based on different steps of the process (specs) private Mono retrieveResponse(WebClient client) { return client.post() - .uri("/resource") - .bodyValue(BODY_VALUE) - .retrieve() - .bodyToMono(String.class); + .uri("/resource") + .bodyValue(BODY_VALUE) + .retrieve() + .bodyToMono(String.class); } private Mono retrieveResponse(RequestBodyUriSpec spec) { return spec.uri("/resource") - .bodyValue(BODY_VALUE) - .retrieve() - .bodyToMono(String.class); + .bodyValue(BODY_VALUE) + .retrieve() + .bodyToMono(String.class); } private Mono> retrieveGetResponse(RequestHeadersUriSpec spec) { return spec.uri("/resource") - .retrieve() - .bodyToMono(MAP_RESPONSE_REF); + .retrieve() + .bodyToMono(MAP_RESPONSE_REF); } private Mono retrieveResponse(RequestBodySpec spec) { return spec.bodyValue(BODY_VALUE) - .retrieve() - .bodyToMono(String.class); + .retrieve() + .bodyToMono(String.class); } private Mono retrieveResponse(RequestHeadersSpec spec) { return spec.retrieve() - .bodyToMono(String.class); + .bodyToMono(String.class); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java index 3ab687bb41..22bd2829d3 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java @@ -1,22 +1,22 @@ package com.baeldung.reactive.webclient; -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.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WebClientApplication.class) +import static org.springframework.test.annotation.DirtiesContext.ClassMode.BEFORE_CLASS; + +@DirtiesContext(classMode = BEFORE_CLASS) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = WebClientApplication.class) public class WebControllerIntegrationTest { @LocalServerPort - int randomServerPort; + private int randomServerPort; @Autowired private WebTestClient testClient; @@ -24,30 +24,26 @@ public class WebControllerIntegrationTest { @Autowired private WebController webController; - @Before - public void setup() { + @BeforeEach + void setup() { webController.setServerPort(randomServerPort); } @Test - public void whenEndpointWithBlockingClientIsCalled_thenThreeTweetsAreReceived() { + void whenEndpointWithBlockingClientIsCalled_thenThreeTweetsAreReceived() { testClient.get() .uri("/tweets-blocking") .exchange() - .expectStatus() - .isOk() - .expectBodyList(Tweet.class) - .hasSize(3); + .expectStatus().isOk() + .expectBodyList(Tweet.class).hasSize(3); } @Test - public void whenEndpointWithNonBlockingClientIsCalled_thenThreeTweetsAreReceived() { + void whenEndpointWithNonBlockingClientIsCalled_thenThreeTweetsAreReceived() { testClient.get() .uri("/tweets-non-blocking") .exchange() - .expectStatus() - .isOk() - .expectBodyList(Tweet.class) - .hasSize(3); + .expectStatus().isOk() + .expectBodyList(Tweet.class).hasSize(3); } } \ No newline at end of file diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java index 90f4a0eca2..dc2a2a30b9 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung.reactive.webclient; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.ApplicationContext; import org.springframework.security.test.context.support.WithMockUser; @@ -14,7 +15,7 @@ import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.WebHandler; import reactor.core.publisher.Mono; -@SpringBootTest(classes = WebClientApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = WebClientApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class WebTestClientIntegrationTest { @LocalServerPort @@ -26,73 +27,61 @@ public class WebTestClientIntegrationTest { @Autowired private WebClientController controller; - private final RouterFunction ROUTER_FUNCTION = RouterFunctions.route(RequestPredicates.GET("/resource"), request -> ServerResponse.ok() - .build()); - private final WebHandler WEB_HANDLER = exchange -> Mono.empty(); - @Test - public void testWebTestClientWithServerWebHandler() { - WebTestClient.bindToWebHandler(WEB_HANDLER) - .build(); + public void whenBindToWebHandler_thenRequestProcessed() { + WebHandler webHandler = exchange -> Mono.empty(); + + WebTestClient.bindToWebHandler(webHandler) + .build() + .get() + .exchange() + .expectBody().isEmpty(); } @Test - public void testWebTestClientWithRouterFunction() { - WebTestClient.bindToRouterFunction(ROUTER_FUNCTION) - .build() - .get() - .uri("/resource") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .isEmpty(); + public void whenBindToRouter_thenRequestProcessed() { + RouterFunction routerFunction = RouterFunctions.route( + RequestPredicates.GET("/resource"), + request -> ServerResponse.ok().build() + ); + + WebTestClient.bindToRouterFunction(routerFunction) + .build() + .get().uri("/resource") + .exchange() + .expectStatus().isOk() + .expectBody().isEmpty(); } @Test @WithMockUser - public void testWebTestClientWithServerURL() { + public void whenBindToServer_thenRequestProcessed() { WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .build() - .get() - .uri("/resource") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .jsonPath("field") - .isEqualTo("value"); - ; + .baseUrl("http://localhost:" + port).build() + .get().uri("/resource") + .exchange() + .expectStatus().isOk() + .expectBody().jsonPath("field").isEqualTo("value"); } @Test @WithMockUser - public void testWebTestClientWithApplicationContext() { + public void whenBindToApplicationContext_thenRequestProcessed() { WebTestClient.bindToApplicationContext(context) - .build() - .get() - .uri("/resource") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .jsonPath("field") - .isEqualTo("value"); + .build() + .get().uri("/resource") + .exchange() + .expectStatus().isOk() + .expectBody().jsonPath("field").isEqualTo("value"); } @Test - public void testWebTestClientWithController() { + public void whenBindToController_thenRequestProcessed() { WebTestClient.bindToController(controller) - .build() - .get() - .uri("/resource") - .exchange() - .expectStatus() - .isOk() - .expectBody() - .jsonPath("field") - .isEqualTo("value"); + .build() + .get().uri("/resource") + .exchange() + .expectStatus().isOk() + .expectBody().jsonPath("field").isEqualTo("value"); } - } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsUnitTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsUnitTest.java deleted file mode 100644 index ff59f12391..0000000000 --- a/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsUnitTest.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.baeldung.reactive.webclientrequests; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeFunction; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.util.DefaultUriBuilderFactory; -import reactor.core.publisher.Mono; - -import java.time.Duration; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -@RunWith(SpringRunner.class) -@WebFluxTest -public class WebClientRequestsUnitTest { - - private static final String BASE_URL = "https://example.com"; - - private WebClient webClient; - - @Captor - private ArgumentCaptor argumentCaptor; - - private ExchangeFunction exchangeFunction; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - this.exchangeFunction = mock(ExchangeFunction.class); - ClientResponse mockResponse = mock(ClientResponse.class); - when(this.exchangeFunction.exchange(this.argumentCaptor.capture())).thenReturn(Mono.just(mockResponse)); - this.webClient = WebClient - .builder() - .baseUrl(BASE_URL) - .exchangeFunction(exchangeFunction) - .build(); - } - - @Test - public void whenCallSimpleURI_thenURIMatched() { - this.webClient.get() - .uri("/products") - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products"); - } - - @Test - public void whenCallSinglePathSegmentUri_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/{id}") - .build(2)) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/2"); - } - - @Test - public void whenCallMultiplePathSegmentsUri_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/{id}/attributes/{attributeId}") - .build(2, 13)) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/2/attributes/13"); - } - - @Test - public void whenCallSingleQueryParams_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/") - .queryParam("name", "AndroidPhone") - .queryParam("color", "black") - .queryParam("deliveryDate", "13/04/2019") - .build()) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); - } - - @Test - public void whenCallSingleQueryParamsPlaceholders_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/") - .queryParam("name", "{title}") - .queryParam("color", "{authorId}") - .queryParam("deliveryDate", "{date}") - .build("AndroidPhone", "black", "13/04/2019")) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019"); - } - - @Test - public void whenCallArrayQueryParamsBrackets_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/") - .queryParam("tag[]", "Snapdragon", "NFC") - .build()) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC"); - } - - - @Test - public void whenCallArrayQueryParams_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/") - .queryParam("category", "Phones", "Tablets") - .build()) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/?category=Phones&category=Tablets"); - } - - @Test - public void whenCallArrayQueryParamsComma_thenURIMatched() { - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/") - .queryParam("category", String.join(",", "Phones", "Tablets")) - .build()) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/?category=Phones,Tablets"); - } - - @Test - public void whenUriComponentEncoding_thenQueryParamsNotEscaped() { - DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL); - factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT); - this.webClient = WebClient - .builder() - .uriBuilderFactory(factory) - .baseUrl(BASE_URL) - .exchangeFunction(exchangeFunction) - .build(); - this.webClient.get() - .uri(uriBuilder -> uriBuilder - .path("/products/") - .queryParam("name", "AndroidPhone") - .queryParam("color", "black") - .queryParam("deliveryDate", "13/04/2019") - .build()) - .exchange() - .block(Duration.ofSeconds(1)); - verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); - } - - private void verifyCalledUrl(String relativeUrl) { - ClientRequest request = this.argumentCaptor.getValue(); - Assert.assertEquals(String.format("%s%s", BASE_URL, relativeUrl), request.url().toString()); - Mockito.verify(this.exchangeFunction).exchange(request); - verifyNoMoreInteractions(this.exchangeFunction); - } -} diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java new file mode 100644 index 0000000000..eefde078e1 --- /dev/null +++ b/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java @@ -0,0 +1,194 @@ +package com.baeldung.reactive.webclientrequests; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.ExchangeFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.DefaultUriBuilderFactory; +import reactor.core.publisher.Mono; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +@RunWith(SpringRunner.class) +@WebFluxTest +public class WebClientRequestsWithParametersUnitTest { + + private static final String BASE_URL = "https://example.com"; + + private WebClient webClient; + + @Captor + private ArgumentCaptor argumentCaptor; + + @Mock + private ExchangeFunction exchangeFunction; + + @Before + public void init() { + ClientResponse mockResponse = mock(ClientResponse.class); + when(mockResponse.bodyToMono(String.class)).thenReturn(Mono.just("test")); + when(exchangeFunction.exchange(argumentCaptor.capture())).thenReturn(Mono.just(mockResponse)); + + webClient = WebClient + .builder() + .baseUrl(BASE_URL) + .exchangeFunction(exchangeFunction) + .build(); + } + + @Test + public void whenCallSimpleURI_thenURIMatched() { + webClient.get() + .uri("/products") + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products"); + } + + @Test + public void whenCallSinglePathSegmentUri_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/{id}") + .build(2)) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/2"); + } + + @Test + public void whenCallMultiplePathSegmentsUri_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/{id}/attributes/{attributeId}") + .build(2, 13)) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/2/attributes/13"); + } + + @Test + public void whenCallSingleQueryParams_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/") + .queryParam("name", "AndroidPhone") + .queryParam("color", "black") + .queryParam("deliveryDate", "13/04/2019") + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); + } + + @Test + public void whenCallSingleQueryParamsPlaceholders_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/") + .queryParam("name", "{title}") + .queryParam("color", "{authorId}") + .queryParam("deliveryDate", "{date}") + .build("AndroidPhone", "black", "13/04/2019")) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019"); + } + + @Test + public void whenCallArrayQueryParamsBrackets_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/") + .queryParam("tag[]", "Snapdragon", "NFC") + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC"); + } + + @Test + public void whenCallArrayQueryParams_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/") + .queryParam("category", "Phones", "Tablets") + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/?category=Phones&category=Tablets"); + } + + @Test + public void whenCallArrayQueryParamsComma_thenURIMatched() { + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/") + .queryParam("category", String.join(",", "Phones", "Tablets")) + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/?category=Phones,Tablets"); + } + + @Test + public void whenUriComponentEncoding_thenQueryParamsNotEscaped() { + DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(BASE_URL); + factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.URI_COMPONENT); + webClient = WebClient + .builder() + .uriBuilderFactory(factory) + .baseUrl(BASE_URL) + .exchangeFunction(exchangeFunction) + .build(); + + webClient.get() + .uri(uriBuilder -> uriBuilder + .path("/products/") + .queryParam("name", "AndroidPhone") + .queryParam("color", "black") + .queryParam("deliveryDate", "13/04/2019") + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + + verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); + } + + private void verifyCalledUrl(String relativeUrl) { + ClientRequest request = argumentCaptor.getValue(); + assertEquals(String.format("%s%s", BASE_URL, relativeUrl), request.url().toString()); + + verify(exchangeFunction).exchange(request); + verifyNoMoreInteractions(exchangeFunction); + } +} diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webflux/annotation/EmployeeControllerIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webflux/annotation/EmployeeControllerIntegrationTest.java index 24c4303e83..699bc9c154 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/webflux/annotation/EmployeeControllerIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/webflux/annotation/EmployeeControllerIntegrationTest.java @@ -2,27 +2,27 @@ package com.baeldung.reactive.webflux.annotation; import com.baeldung.reactive.webflux.Employee; import com.baeldung.reactive.webflux.EmployeeRepository; -import com.baeldung.reactive.webflux.annotation.EmployeeSpringApplication; -import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes= EmployeeSpringApplication.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@SpringBootTest(webEnvironment = RANDOM_PORT, classes = EmployeeSpringApplication.class) public class EmployeeControllerIntegrationTest { @Autowired @@ -35,40 +35,62 @@ public class EmployeeControllerIntegrationTest { public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee() { Employee employee = new Employee("1", "Employee 1 Name"); - + given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee)); + testClient.get() - .uri("/employees/1") - .exchange() - .expectStatus() - .isOk() - .expectBody(Employee.class) - .isEqualTo(employee); + .uri("/employees/1") + .exchange() + .expectStatus().isOk() + .expectBody(Employee.class).isEqualTo(employee); } @Test public void whenGetAllEmployees_thenCorrectEmployees() { - - List employeeList = new ArrayList<>(); - - Employee employee1 = new Employee("1", "Employee 1 Name"); - Employee employee2 = new Employee("2", "Employee 2 Name"); - Employee employee3 = new Employee("3", "Employee 3 Name"); - - employeeList.add(employee1); - employeeList.add(employee2); - employeeList.add(employee3); - + List employeeList = Arrays.asList( + new Employee("1", "Employee 1 Name"), + new Employee("2", "Employee 2 Name"), + new Employee("3", "Employee 3 Name") + ); Flux employeeFlux = Flux.fromIterable(employeeList); given(employeeRepository.findAllEmployees()).willReturn(employeeFlux); + testClient.get() - .uri("/employees") - .exchange() - .expectStatus() - .isOk() - .expectBodyList(Employee.class) - .hasSize(3) - .isEqualTo(employeeList); + .uri("/employees") + .exchange() + .expectStatus().isOk() + .expectBodyList(Employee.class).isEqualTo(employeeList); + } + + @Test + @WithMockUser(username = "admin", roles = { "ADMIN" }) + public void givenValidUser_whenUpdateEmployee_thenEmployeeUpdated() { + Employee employee = new Employee("10", "Employee 10 Updated"); + + given(employeeRepository.updateEmployee(employee)).willReturn(Mono.just(employee)); + + testClient.post() + .uri("/employees/update") + .body(Mono.just(employee), Employee.class) + .exchange() + .expectStatus().isOk() + .expectBody(Employee.class).isEqualTo(employee); + + verify(employeeRepository).updateEmployee(employee); + } + + @Test + @WithMockUser + public void givenInvalidUser_whenUpdateEmployee_thenForbidden() { + Employee employee = new Employee("10", "Employee 10 Updated"); + + testClient.post() + .uri("/employees/update") + .body(Mono.just(employee), Employee.class) + .exchange() + .expectStatus().isForbidden(); + + verifyNoInteractions(employeeRepository); } } diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java index da866724cc..198ec0d081 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java @@ -2,10 +2,8 @@ package com.baeldung.reactive.webflux.functional; import com.baeldung.reactive.webflux.Employee; import com.baeldung.reactive.webflux.EmployeeRepository; -import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -19,10 +17,10 @@ import java.util.List; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = EmployeeSpringFunctionalApplication.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@SpringBootTest(webEnvironment = RANDOM_PORT, classes = EmployeeSpringFunctionalApplication.class) public class EmployeeSpringFunctionalIntegrationTest { @Autowired @@ -34,58 +32,54 @@ public class EmployeeSpringFunctionalIntegrationTest { @Test public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee() { WebTestClient client = WebTestClient - .bindToRouterFunction(config.getEmployeeByIdRoute()) - .build(); + .bindToRouterFunction(config.getEmployeeByIdRoute()) + .build(); Employee employee = new Employee("1", "Employee 1"); given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee)); client.get() - .uri("/employees/1") - .exchange() - .expectStatus() - .isOk() - .expectBody(Employee.class) - .isEqualTo(employee); + .uri("/employees/1") + .exchange() + .expectStatus().isOk() + .expectBody(Employee.class).isEqualTo(employee); } @Test public void whenGetAllEmployees_thenCorrectEmployees() { WebTestClient client = WebTestClient - .bindToRouterFunction(config.getAllEmployeesRoute()) - .build(); + .bindToRouterFunction(config.getAllEmployeesRoute()) + .build(); List employees = Arrays.asList( - new Employee("1", "Employee 1"), - new Employee("2", "Employee 2")); + new Employee("1", "Employee 1"), + new Employee("2", "Employee 2") + ); Flux employeeFlux = Flux.fromIterable(employees); given(employeeRepository.findAllEmployees()).willReturn(employeeFlux); client.get() - .uri("/employees") - .exchange() - .expectStatus() - .isOk() - .expectBodyList(Employee.class) - .isEqualTo(employees); + .uri("/employees") + .exchange() + .expectStatus().isOk() + .expectBodyList(Employee.class).isEqualTo(employees); } @Test public void whenUpdateEmployee_thenEmployeeUpdated() { WebTestClient client = WebTestClient - .bindToRouterFunction(config.updateEmployeeRoute()) - .build(); + .bindToRouterFunction(config.updateEmployeeRoute()) + .build(); Employee employee = new Employee("1", "Employee 1 Updated"); client.post() - .uri("/employees/update") - .body(Mono.just(employee), Employee.class) - .exchange() - .expectStatus() - .isOk(); + .uri("/employees/update") + .body(Mono.just(employee), Employee.class) + .exchange() + .expectStatus().isOk(); verify(employeeRepository).updateEmployee(employee); } diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml index ea42095d92..fa84ec9558 100644 --- a/spring-roo/pom.xml +++ b/spring-roo/pom.xml @@ -18,6 +18,190 @@ + + + + + org.springframework.roo + org.springframework.roo.annotations + ${roo.version} + pom + provided + + + io.springlets + springlets-data-jpa + ${springlets.version} + + + io.springlets + springlets-data-commons + ${springlets.version} + + + io.springlets + springlets-context + ${springlets.version} + + + org.springframework.roo + org.springframework.roo.querydsl.processor + ${querydsl-processor.version} + + + io.tracee.binding + tracee-springmvc + ${tracee.version} + + + io.springlets + springlets-boot-starter-web + ${springlets.version} + + + com.github.mxab.thymeleaf.extras + thymeleaf-extras-data-attribute + ${thymeleaf-data-dialect.version} + + + ar.com.fdvs + DynamicJasper + ${dynamicjasper.version} + + + ar.com.fdvs + DynamicJasper-core-fonts + ${dynamicjasper-fonts.version} + + + org.webjars.bower + bootstrap + ${bootstrap.version} + + + org.webjars.bower + datatables + ${datatables.version} + + + org.webjars.bower + datatables.net-bs + ${datatables-bs.version} + + + org.webjars.bower + datatables.net-buttons + ${datatables-buttons.version} + + + org.webjars.bower + datatables.net-buttons-bs + ${datatables-buttons-bs.version} + + + org.webjars.bower + datatables.net-responsive + ${datatables-responsive.version} + + + org.webjars.bower + datatables.net-responsive-bs + ${datatables-responsive-bs.version} + + + org.webjars.bower + datatables.net-select + ${datatables-select.version} + + + org.webjars.bower + datatables.net-select-bs + ${datatables-select-bs.version} + + + org.webjars.npm + jquery-datatables-checkboxes + ${datatables-checkboxes.version} + + + org.webjars.npm + jquery + + + org.webjars.npm + datatables.net + + + + + org.webjars.bower + github-com-julmot-datatables-mark-js + ${datatables-mark.version} + + + org.webjars.bower + datetimepicker + ${datetimepicker.version} + + + org.webjars.bower + font-awesome + ${fontawesome.version} + + + org.webjars.bower + jquery + ${jquery.version} + + + org.webjars + jquery.inputmask + ${jquery-inputmask.version} + + + org.webjars + jquery + + + + + org.webjars.bower + jquery-validation + ${jquery-validation.version} + + + org.webjars.bower + momentjs + ${momentjs.version} + + + org.webjars.bower + select2 + ${select2.version} + + + org.webjars.bower + select2-bootstrap-theme + ${select2-bootstrap-theme.version} + + + org.webjars + respond + ${respond.version} + + + org.webjars + html5shiv + ${html5shiv.version} + + + org.webjars.bower + ie10-viewport-bug-workaround + ${bootstrap.ie10-viewport-bug-workaround.version} + + + + @@ -404,190 +588,6 @@ - - - - - org.springframework.roo - org.springframework.roo.annotations - ${roo.version} - pom - provided - - - io.springlets - springlets-data-jpa - ${springlets.version} - - - io.springlets - springlets-data-commons - ${springlets.version} - - - io.springlets - springlets-context - ${springlets.version} - - - org.springframework.roo - org.springframework.roo.querydsl.processor - ${querydsl-processor.version} - - - io.tracee.binding - tracee-springmvc - ${tracee.version} - - - io.springlets - springlets-boot-starter-web - ${springlets.version} - - - com.github.mxab.thymeleaf.extras - thymeleaf-extras-data-attribute - ${thymeleaf-data-dialect.version} - - - ar.com.fdvs - DynamicJasper - ${dynamicjasper.version} - - - ar.com.fdvs - DynamicJasper-core-fonts - ${dynamicjasper-fonts.version} - - - org.webjars.bower - bootstrap - ${bootstrap.version} - - - org.webjars.bower - datatables - ${datatables.version} - - - org.webjars.bower - datatables.net-bs - ${datatables-bs.version} - - - org.webjars.bower - datatables.net-buttons - ${datatables-buttons.version} - - - org.webjars.bower - datatables.net-buttons-bs - ${datatables-buttons-bs.version} - - - org.webjars.bower - datatables.net-responsive - ${datatables-responsive.version} - - - org.webjars.bower - datatables.net-responsive-bs - ${datatables-responsive-bs.version} - - - org.webjars.bower - datatables.net-select - ${datatables-select.version} - - - org.webjars.bower - datatables.net-select-bs - ${datatables-select-bs.version} - - - org.webjars.npm - jquery-datatables-checkboxes - ${datatables-checkboxes.version} - - - org.webjars.npm - jquery - - - org.webjars.npm - datatables.net - - - - - org.webjars.bower - github-com-julmot-datatables-mark-js - ${datatables-mark.version} - - - org.webjars.bower - datetimepicker - ${datetimepicker.version} - - - org.webjars.bower - font-awesome - ${fontawesome.version} - - - org.webjars.bower - jquery - ${jquery.version} - - - org.webjars - jquery.inputmask - ${jquery-inputmask.version} - - - org.webjars - jquery - - - - - org.webjars.bower - jquery-validation - ${jquery-validation.version} - - - org.webjars.bower - momentjs - ${momentjs.version} - - - org.webjars.bower - select2 - ${select2.version} - - - org.webjars.bower - select2-bootstrap-theme - ${select2-bootstrap-theme.version} - - - org.webjars - respond - ${respond.version} - - - org.webjars - html5shiv - ${html5shiv.version} - - - org.webjars.bower - ie10-viewport-bug-workaround - ${bootstrap.ie10-viewport-bug-workaround.version} - - - - 2.0.0.RELEASE 8 diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 9fdfde282d..eb643c78c7 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -22,6 +22,7 @@ spring-security-acl spring-security-auth0 spring-security-core + spring-security-core-2 spring-security-ldap spring-security-legacy-oidc spring-security-oauth2-sso @@ -46,6 +47,7 @@ spring-security-web-x509 spring-session spring-social-login + spring-security-opa \ No newline at end of file diff --git a/spring-security-modules/spring-security-core-2/.gitignore b/spring-security-modules/spring-security-core-2/.gitignore new file mode 100644 index 0000000000..9f970225ad --- /dev/null +++ b/spring-security-modules/spring-security-core-2/.gitignore @@ -0,0 +1 @@ +target/ \ No newline at end of file diff --git a/spring-security-modules/spring-security-core-2/README.md b/spring-security-modules/spring-security-core-2/README.md new file mode 100644 index 0000000000..9ce12af8ef --- /dev/null +++ b/spring-security-modules/spring-security-core-2/README.md @@ -0,0 +1,10 @@ +## Spring Security Core + +This module contains articles about core Spring Security + +### Relevant Articles: +- [Handle Spring Security Exceptions](https://www.baeldung.com/spring-security-exceptions) + +### Build the Project + +`mvn clean install` diff --git a/spring-security-modules/spring-security-core-2/pom.xml b/spring-security-modules/spring-security-core-2/pom.xml new file mode 100644 index 0000000000..cf150bfd42 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + spring-security-core-2 + 0.1-SNAPSHOT + spring-security-core-2 + war + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + + + com.h2database + h2 + runtime + + + org.springframework.security + spring-security-test + + + + + spring-security-core + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-war-plugin + + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java new file mode 100644 index 0000000000..43921f71a2 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/AppInitializer.java @@ -0,0 +1,11 @@ +package com.baeldung.exceptionhandler; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AppInitializer { + public static void main(String[] args) { + SpringApplication.run(AppInitializer.class, args); + } +} diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java similarity index 52% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java rename to spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java index daaeb8159b..0973fe1ad3 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/AccessDeniedController.java @@ -1,16 +1,15 @@ -package com.baeldung.rss; +package com.baeldung.exceptionhandler.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller -@RequestMapping(value = "/rss", produces = "application/*") -public class ArticleRssController { +@RequestMapping("/access-denied") +public class AccessDeniedController { @GetMapping - public String articleFeed() { - return "articleFeedView"; + public String accessDenied() { + return "/denied.html"; } - } diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java new file mode 100644 index 0000000000..8b65a623eb --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/CustomErrorController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping +public class CustomErrorController { + + @GetMapping("/customError") + public String customErrorController() { + return "/error"; + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java new file mode 100644 index 0000000000..d64bf7b5f3 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/HomeController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/home") +public class HomeController { + + @GetMapping + public String home() { + return "/index.html"; + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java new file mode 100644 index 0000000000..a057570e29 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/controller/SecuredResourceController.java @@ -0,0 +1,15 @@ +package com.baeldung.exceptionhandler.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/secured") +public class SecuredResourceController { + + @GetMapping + public String secureResource() { + return "/admin.html"; + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java new file mode 100644 index 0000000000..a3d6aca9be --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAccessDeniedHandler.java @@ -0,0 +1,17 @@ +package com.baeldung.exceptionhandler.security; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +public class CustomAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException { + response.sendRedirect("/access-denied"); + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java new file mode 100644 index 0000000000..281f9d5289 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationFailureHandler.java @@ -0,0 +1,17 @@ +package com.baeldung.exceptionhandler.security; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; + +public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException { + httpServletResponse.sendRedirect("/customError"); + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java new file mode 100644 index 0000000000..62cbdf8873 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/CustomAuthenticationSuccessHandler.java @@ -0,0 +1,31 @@ +package com.baeldung.exceptionhandler.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { + + @Override + public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { + + HttpSession session = httpServletRequest.getSession(); + User authUser = (User) SecurityContextHolder.getContext() + .getAuthentication() + .getPrincipal(); + session.setAttribute("username", authUser.getUsername()); + session.setAttribute("authorities", authentication.getAuthorities()); + + httpServletResponse.setStatus(HttpServletResponse.SC_OK); + + httpServletResponse.sendRedirect("/home"); + } +} diff --git a/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java new file mode 100644 index 0000000000..71ded0f131 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/java/com/baeldung/exceptionhandler/security/SecurityConfig.java @@ -0,0 +1,98 @@ +package com.baeldung.exceptionhandler.security; + +import org.springframework.context.annotation.Bean; +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.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Bean + public UserDetailsService userDetailsService() { + + UserDetails user = User.withUsername("user") + .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode) + .password("password") + .roles("USER") + .build(); + + UserDetails admin = User.withUsername("admin") + .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode) + .password("password") + .roles("ADMIN") + .build(); + + InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager(); + + userDetailsManager.createUser(user); + userDetailsManager.createUser(admin); + + return userDetailsManager; + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("user") + .password("{noop}password") + .roles("USER") + .and() + .withUser("admin") + .password("{noop}password") + .roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf() + .disable() + .httpBasic() + .disable() + .authorizeRequests() + .antMatchers("/login") + .permitAll() + .antMatchers("/customError") + .permitAll() + .antMatchers("/access-denied") + .permitAll() + .antMatchers("/secured") + .hasRole("ADMIN") + .anyRequest() + .authenticated() + .and() + .formLogin() + .failureHandler(authenticationFailureHandler()) + .successHandler(authenticationSuccessHandler()) + .and() + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler()) + .and() + .logout(); + } + + @Bean + public AuthenticationFailureHandler authenticationFailureHandler() { + return new CustomAuthenticationFailureHandler(); + } + + @Bean + public AuthenticationSuccessHandler authenticationSuccessHandler() { + return new CustomAuthenticationSuccessHandler(); + } + + @Bean + public AccessDeniedHandler accessDeniedHandler() { + return new CustomAccessDeniedHandler(); + } + +} diff --git a/spring-security-modules/spring-security-core-2/src/main/resources/application.properties b/spring-security-modules/spring-security-core-2/src/main/resources/application.properties new file mode 100644 index 0000000000..9d154c9cc0 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.thymeleaf.prefix=classpath:/templates/ \ No newline at end of file diff --git a/spring-security-modules/spring-security-core-2/src/main/resources/templates/admin.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/admin.html new file mode 100644 index 0000000000..d7f7ec232a --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/resources/templates/admin.html @@ -0,0 +1,5 @@ + + +
Hello Admin!
+ + diff --git a/spring-security-modules/spring-security-core-2/src/main/resources/templates/denied.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/denied.html new file mode 100644 index 0000000000..b7a8e09309 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/resources/templates/denied.html @@ -0,0 +1,5 @@ + + +
You need permission to perform this action.
+ + diff --git a/spring-security-modules/spring-security-core-2/src/main/resources/templates/error.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/error.html new file mode 100644 index 0000000000..ce74f05d99 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/resources/templates/error.html @@ -0,0 +1,5 @@ + + +
Ups! Wrong credentials
+ + diff --git a/spring-security-modules/spring-security-core-2/src/main/resources/templates/index.html b/spring-security-modules/spring-security-core-2/src/main/resources/templates/index.html new file mode 100644 index 0000000000..34d070b37a --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/main/resources/templates/index.html @@ -0,0 +1,6 @@ + + +
Hello User!
+ + + diff --git a/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java new file mode 100644 index 0000000000..ad35d575a5 --- /dev/null +++ b/spring-security-modules/spring-security-core-2/src/test/java/com/baeldung/exceptionhandler/SecurityConfigUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.exceptionhandler; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.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.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.exceptionhandler.security.SecurityConfig; + +@RunWith(SpringRunner.class) +@WebMvcTest(SecurityConfig.class) +class SecurityConfigUnitTest { + @Autowired + private MockMvc mvc; + + @Test + void whenUserAccessLogin_shouldSucceed() throws Exception { + mvc.perform(get("/login")) + .andExpect(status().isOk()); + } + + @Test + void whenUserAccessWithWrongCredentials_shouldRedirectToCustomErrorPage() throws Exception { + mvc.perform(formLogin("/login").user("username", "wrong") + .password("password", "credentials")) + .andExpect(redirectedUrl("/customError")); + } + + @Test + void whenUserAccessWithCorrectCredentials_shouldRedirectToHome() throws Exception { + mvc.perform(formLogin("/login").user("username", "user") + .password("password", "password")) + .andExpect(redirectedUrl("/home")); + } + + @Test + @WithMockUser(username = "user", roles = { "USER" }) + void whenUserAccessToSecuredPageWithoutUserRole_shouldRedirectToDeniedPage() throws Exception { + mvc.perform(get("/secured")) + .andExpect(redirectedUrl("/access-denied")); + } +} \ No newline at end of file diff --git a/spring-security-modules/spring-security-opa/README.md b/spring-security-modules/spring-security-opa/README.md new file mode 100644 index 0000000000..d2c1652edb --- /dev/null +++ b/spring-security-modules/spring-security-opa/README.md @@ -0,0 +1,4 @@ + +### Relevant Articles: + +- [Spring Security Authorization with OPA](https://www.baeldung.com/spring-security-authorization-opa) diff --git a/spring-security-modules/spring-security-opa/pom.xml b/spring-security-modules/spring-security-opa/pom.xml new file mode 100644 index 0000000000..72b0574253 --- /dev/null +++ b/spring-security-modules/spring-security-opa/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + spring-security-opa + Spring Security with OPA authorization + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-security + + + org.projectlombok + lombok + + + com.google.guava + guava + 31.0.1-jre + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.security + spring-security-test + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactApp.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/Application.java similarity index 61% rename from spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactApp.java rename to spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/Application.java index 79037e1038..789a1f803f 100644 --- a/spring-boot-modules/spring-boot/src/main/java/com/baeldung/jsondateformat/ContactApp.java +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/Application.java @@ -1,13 +1,13 @@ -package com.baeldung.jsondateformat; +package com.baeldung.security.opa; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class ContactApp { - +public class Application { + public static void main(String[] args) { - SpringApplication.run(ContactApp.class, args); + SpringApplication.run(Application.class, args); } } diff --git a/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/OpaConfiguration.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/OpaConfiguration.java new file mode 100644 index 0000000000..e24fdbcf35 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/OpaConfiguration.java @@ -0,0 +1,25 @@ +package com.baeldung.security.opa.config; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.client.WebClient; + +import lombok.RequiredArgsConstructor; + +@Configuration +@RequiredArgsConstructor +@EnableConfigurationProperties(OpaProperties.class) +public class OpaConfiguration { + + private final OpaProperties opaProperties; + + @Bean + public WebClient opaWebClient(WebClient.Builder builder) { + + return builder + .baseUrl(opaProperties.getEndpoint()) + .build(); + } + +} diff --git a/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/OpaProperties.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/OpaProperties.java new file mode 100644 index 0000000000..acc23a2fd2 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/OpaProperties.java @@ -0,0 +1,14 @@ +package com.baeldung.security.opa.config; + +import javax.annotation.Nonnull; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.Data; + +@ConfigurationProperties(prefix = "opa") +@Data +public class OpaProperties { + @Nonnull + private String endpoint = "http://localhost:8181"; +} diff --git a/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/SecurityConfiguration.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/SecurityConfiguration.java new file mode 100644 index 0000000000..7e10cb2e8a --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/config/SecurityConfiguration.java @@ -0,0 +1,110 @@ +package com.baeldung.security.opa.config; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import org.reactivestreams.Publisher; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.client.reactive.ClientHttpRequest; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.ReactiveAuthorizationManager; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.security.web.server.authorization.AuthorizationContext; +import org.springframework.web.reactive.function.BodyInserter; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableMap; + +import reactor.core.publisher.Mono; + +@Configuration +public class SecurityConfiguration { + + + @Bean + public SecurityWebFilterChain accountAuthorization(ServerHttpSecurity http, @Qualifier("opaWebClient")WebClient opaWebClient) { + + // @formatter:on + return http + .httpBasic() + .and() + .authorizeExchange(exchanges -> { + exchanges + .pathMatchers("/account/*") + .access(opaAuthManager(opaWebClient)); + }) + .build(); + // @formatter:on + + } + + @Bean + public ReactiveAuthorizationManager opaAuthManager(WebClient opaWebClient) { + + return (auth, context) -> { + return opaWebClient.post() + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .body(toAuthorizationPayload(auth,context), Map.class) + .exchangeToMono(this::toDecision); + }; + } + + private Mono toDecision(ClientResponse response) { + + if ( !response.statusCode().is2xxSuccessful()) { + return Mono.just(new AuthorizationDecision(false)); + } + + return response + .bodyToMono(ObjectNode.class) + .map(node -> { + boolean authorized = node.path("result").path("authorized").asBoolean(false); + return new AuthorizationDecision(authorized); + }); + + } + + private Publisher> toAuthorizationPayload(Mono auth, AuthorizationContext context) { + // @formatter:off + return auth + .defaultIfEmpty(new AnonymousAuthenticationToken("**ANONYMOUS**", new Object(), Arrays.asList(new SimpleGrantedAuthority("ANONYMOUS")))) + .map( a -> { + + Map headers = context.getExchange().getRequest() + .getHeaders() + .toSingleValueMap(); + + Map attributes = ImmutableMap.builder() + .put("principal",a.getName()) + .put("authorities", + a.getAuthorities() + .stream() + .map(g -> g.getAuthority()) + .collect(Collectors.toList())) + .put("uri", context.getExchange().getRequest().getURI().getPath()) + .put("headers",headers) + .build(); + + Map input = ImmutableMap.builder() + .put("input",attributes) + .build(); + + return input; + }); + // @formatter:on + } +} diff --git a/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/controller/AccountController.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/controller/AccountController.java new file mode 100644 index 0000000000..ba0ff61554 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/controller/AccountController.java @@ -0,0 +1,23 @@ +package com.baeldung.security.opa.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.security.opa.domain.Account; +import com.baeldung.security.opa.service.AccountService; + +import lombok.RequiredArgsConstructor; +import reactor.core.publisher.Mono; + +@RestController +@RequiredArgsConstructor +public class AccountController { + + private final AccountService accountService; + + @GetMapping("/account/{accountId}") + public Mono getAccount(@PathVariable("accountId") String accountId) { + return accountService.findByAccountId(accountId); + } +} diff --git a/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/domain/Account.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/domain/Account.java new file mode 100644 index 0000000000..db494627a8 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/domain/Account.java @@ -0,0 +1,25 @@ +package com.baeldung.security.opa.domain; + +import java.math.BigDecimal; + +import lombok.Data; + +@Data +public class Account { + + private String id; + private BigDecimal balance; + private String currency; + + + public static Account of(String id, BigDecimal balance, String currency) { + Account acc = new Account(); + acc.setId(id); + acc.setBalance(balance); + acc.setCurrency(currency); + + return acc; + } + + +} diff --git a/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/service/AccountService.java b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/service/AccountService.java new file mode 100644 index 0000000000..18968019f9 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/java/com/baeldung/security/opa/service/AccountService.java @@ -0,0 +1,37 @@ +/** + * + */ +package com.baeldung.security.opa.service; + +import java.math.BigDecimal; +import java.util.Map; + +import org.springframework.stereotype.Service; + +import com.baeldung.security.opa.domain.Account; +import com.google.common.collect.ImmutableMap; + +import reactor.core.publisher.Mono; + +/** + * @author Philippe + * + */ +@Service +public class AccountService { + + private Map accounts = ImmutableMap.builder() + .put("0001", Account.of("0001", BigDecimal.valueOf(100.00), "USD")) + .put("0002", Account.of("0002", BigDecimal.valueOf(101.00), "EUR")) + .put("0003", Account.of("0003", BigDecimal.valueOf(102.00), "BRL")) + .put("0004", Account.of("0004", BigDecimal.valueOf(103.00), "AUD")) + .put("0005", Account.of("0005", BigDecimal.valueOf(10400.00), "JPY")) + .build(); + + + public Mono findByAccountId(String accountId) { + return Mono.just(accounts.get(accountId)) + .switchIfEmpty(Mono.error(new IllegalArgumentException("invalid.account"))); + } + +} diff --git a/spring-security-modules/spring-security-opa/src/main/resources/application.yaml b/spring-security-modules/spring-security-opa/src/main/resources/application.yaml new file mode 100644 index 0000000000..6fb9200277 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/main/resources/application.yaml @@ -0,0 +1,3 @@ +# OPA configuration properties +opa: + endpoint: http://localhost:8181/v1/data/baeldung/auth/account \ No newline at end of file diff --git a/spring-security-modules/spring-security-opa/src/test/java/com/baeldung/security/opa/controller/AccountControllerLiveTest.java b/spring-security-modules/spring-security-opa/src/test/java/com/baeldung/security/opa/controller/AccountControllerLiveTest.java new file mode 100644 index 0000000000..7469fd327c --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/test/java/com/baeldung/security/opa/controller/AccountControllerLiveTest.java @@ -0,0 +1,67 @@ +package com.baeldung.security.opa.controller; + +import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; + +// !!! NOTICE: Start OPA server before running this test class !!! +@SpringBootTest +@ActiveProfiles("test") +class AccountControllerLiveTest { + + @Autowired + ApplicationContext context; + WebTestClient rest; + + @BeforeEach + public void setup() { + this.rest = WebTestClient.bindToApplicationContext(this.context) + .apply(springSecurity()) + .configureClient() + .build(); + } + + + @Test + @WithMockUser(username = "user1", roles = { "account:read:0001"} ) + void testGivenValidUser_thenSuccess() { + rest.get() + .uri("/account/0001") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .is2xxSuccessful(); + } + + @Test + @WithMockUser(username = "user1", roles = { "account:read:0002"} ) + void testGivenValidUser_thenUnauthorized() { + rest.get() + .uri("/account/0001") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isForbidden(); + } + + @Test + @WithMockUser(username = "user1", roles = {} ) + void testGivenNoAuthorities_thenForbidden() { + rest.get() + .uri("/account/0001") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isForbidden(); + } + + +} diff --git a/spring-security-modules/spring-security-opa/src/test/rego/account.rego b/spring-security-modules/spring-security-opa/src/test/rego/account.rego new file mode 100644 index 0000000000..567d531bb4 --- /dev/null +++ b/spring-security-modules/spring-security-opa/src/test/rego/account.rego @@ -0,0 +1,43 @@ +# +# Simple authorization rule for accounts +# +# Assumes an input document with the following properties: +# +# resource: requested resource +# method: request method +# authorities: Granted authorities +# headers: Request headers +# +package baeldung.auth.account + +# Not authorized by default +default authorized = false + +# Authorize when there are no rules that deny access to the resource and +# there's at least one rule allowing +authorized = true { + count(deny) == 0 + count(allow) > 0 +} + +# Allow access to /public +allow["public"] { + regex.match("^/public/.*",input.uri) +} + +# Account API requires authenticated user +deny["account_api_authenticated"] { + regex.match("^/account/.*",input.uri) + regex.match("ANONYMOUS",input.principal) +} + +# Authorize access to account if principal has +# matching authority +allow["account_api_authorized"] { + regex.match("^/account/.+",input.uri) + parts := split(input.uri,"/") + account := parts[2] + role := concat(":",[ "ROLE_account", "read", account] ) + role == input.authorities[i] +} + diff --git a/spring-security-modules/spring-security-saml/src/main/resources/application.properties b/spring-security-modules/spring-security-saml/src/main/resources/application.properties index 1d93a12737..fd7798dda9 100644 --- a/spring-security-modules/spring-security-saml/src/main/resources/application.properties +++ b/spring-security-modules/spring-security-saml/src/main/resources/application.properties @@ -1,8 +1,9 @@ -saml.keystore.location=classpath:/saml/samlKeystore.jks +saml.keystore.location=classpath:/saml/saml-keystore # Password for Java keystore and item therein saml.keystore.password= saml.keystore.alias= # SAML Entity ID extracted from top of SAML metadata file saml.idp= -saml.sp=http://localhost:8080/saml/metadata \ No newline at end of file +saml.sp=http://localhost:8080/saml/metadata +spring.main.allow-circular-references=true \ No newline at end of file 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 5da993acd9..0984c25e07 100644 --- a/spring-security-modules/spring-security-web-boot-3/pom.xml +++ b/spring-security-modules/spring-security-web-boot-3/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 spring-security-web-boot-3 0.0.1-SNAPSHOT @@ -73,5 +74,4 @@ 3.6.0
- \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-login/pom.xml b/spring-security-modules/spring-security-web-login/pom.xml index 346338cbcd..c2369abc14 100644 --- a/spring-security-modules/spring-security-web-login/pom.xml +++ b/spring-security-modules/spring-security-web-login/pom.xml @@ -118,7 +118,7 @@ runtime
- + org.springframework.boot spring-boot-starter-test ${spring-boot.version} @@ -136,11 +136,11 @@ ${spring-security.version} test - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} +
diff --git a/spring-security-modules/spring-security-web-rest/README.md b/spring-security-modules/spring-security-web-rest/README.md index fd1f86f6b8..5a94504762 100644 --- a/spring-security-modules/spring-security-web-rest/README.md +++ b/spring-security-modules/spring-security-web-rest/README.md @@ -9,7 +9,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: -- [Setting Up Swagger 2 with a Spring REST API](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) +- [Setting Up Swagger 2 with a Spring REST API Using Springfox](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) - [Custom Error Message Handling for REST API](https://www.baeldung.com/global-error-handler-in-a-spring-rest-api) - [Spring Security Context Propagation with @Async](https://www.baeldung.com/spring-security-async-principal-propagation) - [Servlet 3 Async Support with Spring MVC and Spring Security](https://www.baeldung.com/spring-mvc-async-security) diff --git a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml index 9598843b63..12153c91f2 100644 --- a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml +++ b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-basic-auth/pom.xml @@ -21,7 +21,6 @@ org.springframework.boot spring-boot-maven-plugin
- org.apache.maven.plugins maven-surefire-plugin diff --git a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml index f310ab1e5c..f3ea2728f2 100644 --- a/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml +++ b/spring-security-modules/spring-security-web-x509/spring-security-web-x509-client-auth/pom.xml @@ -21,7 +21,6 @@ org.springframework.boot spring-boot-maven-plugin - org.apache.maven.plugins maven-surefire-plugin diff --git a/spring-state-machine/pom.xml b/spring-state-machine/pom.xml index bc2b67cc38..0e930d6ff1 100644 --- a/spring-state-machine/pom.xml +++ b/spring-state-machine/pom.xml @@ -18,6 +18,11 @@ spring-statemachine-core ${spring-statemachine-core.version} + + org.springframework + spring-context + ${spring-context.version} + org.springframework spring-test @@ -32,8 +37,9 @@ - 1.2.3.RELEASE - 4.3.7.RELEASE + 3.2.0 + 5.3.19 + 5.3.19 1.7.0 diff --git a/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java b/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java index 0c392c2c35..8c95e9d843 100644 --- a/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java +++ b/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java @@ -38,7 +38,7 @@ public class SimpleStateMachineConfiguration extends StateMachineConfigurerAdapt .stateEntry("S3", entryAction()) .stateExit("S3", exitAction()) .state("S4", executeAction(), errorAction()) - .stateDo("S5", executeAction()); + .state("S5", executeAction(), errorAction()); } 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 5909340a82..ac2d6a22c2 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 @@ -1,32 +1,37 @@ 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.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.statemachine.StateMachine; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.spring.statemachine.config.SimpleStateMachineConfiguration; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -@RunWith(SpringJUnit4ClassRunner.class) +@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SimpleStateMachineConfiguration.class) +@TestMethodOrder(OrderAnnotation.class) public class StateMachineIntegrationTest { @Autowired private StateMachine stateMachine; - @Before + @BeforeEach public void setUp() { stateMachine.start(); } @Test + @Order(1) public void whenSimpleStringStateMachineEvents_thenEndState() { assertEquals("SI", stateMachine.getState().getId()); @@ -37,8 +42,8 @@ public class StateMachineIntegrationTest { assertEquals("S2", stateMachine.getState().getId()); } - @Ignore("Fixing in JAVA-9808") @Test + @Order(2) public void whenSimpleStringMachineActionState_thenActionExecuted() { stateMachine.sendEvent("E3"); @@ -58,7 +63,7 @@ public class StateMachineIntegrationTest { assertEquals(2, stateMachine.getExtendedState().getVariables().get("approvalCount")); } - @After + @AfterEach public void tearDown() { stateMachine.stop(); } diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml index 2afde0b07d..f125018fb0 100644 --- a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml +++ b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml @@ -9,13 +9,11 @@ jar https://github.com/openapitools/openapi-generator OpenAPI Java - scm:git:git@github.com:openapitools/openapi-generator.git scm:git:git@github.com:openapitools/openapi-generator.git https://github.com/openapitools/openapi-generator - Unlicense @@ -23,7 +21,6 @@ repo - OpenAPI-Generator Contributors diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml index 66e9d1dda2..c9ba912feb 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml @@ -8,13 +8,11 @@ jar https://github.com/swagger-api/swagger-codegen Swagger Java - scm:git:git@github.com:swagger-api/swagger-codegen.git scm:git:git@github.com:swagger-api/swagger-codegen.git https://github.com/swagger-api/swagger-codegen - Unlicense @@ -22,7 +20,6 @@ repo - Swagger diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestmappingvalue/WelcomeController.java b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestmappingvalue/WelcomeController.java new file mode 100644 index 0000000000..bbc978ccd4 --- /dev/null +++ b/spring-web-modules/spring-mvc-basics-5/src/main/java/com/baeldung/requestmappingvalue/WelcomeController.java @@ -0,0 +1,15 @@ +package com.baeldung.requestmappingvalue; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/${request.value}") +public class WelcomeController { + + @GetMapping + public String getWelcomeMessage() { + return "Welcome to Baeldung!"; + } +} diff --git a/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties b/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties index 935f91554b..61a0755b93 100644 --- a/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties +++ b/spring-web-modules/spring-mvc-basics-5/src/main/resources/application.properties @@ -1 +1,2 @@ server.servlet.context-path=/spring-mvc-basics +request.value=welcome diff --git a/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestmappingvalue/WelcomeControllerUnitTest.java b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestmappingvalue/WelcomeControllerUnitTest.java new file mode 100644 index 0000000000..ac5140733b --- /dev/null +++ b/spring-web-modules/spring-mvc-basics-5/src/test/java/com/baeldung/requestmappingvalue/WelcomeControllerUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.requestmappingvalue; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +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.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +class WelcomeControllerUnitTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void whenUserAccessToWelcome_thenReturnOK() throws Exception { + this.mockMvc.perform(get("/welcome")) + .andExpect(status().isOk()); + } + +} \ No newline at end of file diff --git a/spring-web-modules/spring-rest-http-2/README.md b/spring-web-modules/spring-rest-http-2/README.md index bb9175db8c..2c1b1f76f7 100644 --- a/spring-web-modules/spring-rest-http-2/README.md +++ b/spring-web-modules/spring-rest-http-2/README.md @@ -11,4 +11,7 @@ The "REST With Spring 2" Classes: http://bit.ly/restwithspring - [Setting a Request Timeout for a Spring REST API](https://www.baeldung.com/spring-rest-timeout) - [Long Polling in Spring MVC](https://www.baeldung.com/spring-mvc-long-polling) - [Guide to UriComponentsBuilder in Spring](https://www.baeldung.com/spring-uricomponentsbuilder) +- [Get All Endpoints in Spring Boot](https://www.baeldung.com/spring-boot-get-all-endpoints) +- [HTTP PUT vs. POST in REST API](https://www.baeldung.com/rest-http-put-vs-post) +- [415 Unsupported MediaType in Spring Application](https://www.baeldung.com/spring-415-unsupported-mediatype) - More articles: [[<-- prev]](../spring-rest-http) diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/SpringBootRestApplication.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/controller/HelloController.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/AnnotationDrivenEndpointsListener.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/listener/EndpointsListener.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/Address.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/Address.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/Address.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/Address.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressController.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressController.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressController.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressRepository.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressRepository.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/AddressRepository.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/AddressRepository.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/putvspost/PutVsPostApplication.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UnsupportedMediaTypeApplication.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/User.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/User.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/User.java diff --git a/spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java similarity index 100% rename from spring-boot-rest-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/unsupportedmediatype/UserController.java diff --git a/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties b/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties index ff4af943ec..3119ad188a 100644 --- a/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties +++ b/spring-web-modules/spring-rest-http-2/src/main/resources/application.properties @@ -1 +1,2 @@ -spring.mvc.async.request-timeout=750 \ No newline at end of file +spring.mvc.async.request-timeout=750 +management.endpoints.web.exposure.include=mappings \ No newline at end of file diff --git a/spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java b/spring-web-modules/spring-rest-http-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java similarity index 100% rename from spring-boot-rest-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java rename to spring-web-modules/spring-rest-http-2/src/test/java/com/baeldung/unsupportedmediatype/ApplicationUnitTest.java diff --git a/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties b/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties index ff4af943ec..10ac1ab5fa 100644 --- a/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties +++ b/spring-web-modules/spring-rest-http-2/src/test/resources/application.properties @@ -1 +1,2 @@ -spring.mvc.async.request-timeout=750 \ No newline at end of file +spring.mvc.async.request-timeout=750 +spring.main.allow-bean-definition-overriding=true diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index e5a8ba5ea9..4abaac5628 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -37,12 +37,12 @@ org.springframework.boot spring-boot-starter-test - + au.com.dius pact-jvm-provider-junit5_2.12 ${pact.version} - - + + au.com.dius pact-jvm-consumer-junit5_2.12 ${pact.version} @@ -119,10 +119,10 @@ spring-test - org.mockito - mockito-junit-jupiter - ${mockito.version} - test + org.mockito + mockito-junit-jupiter + ${mockito.version} + test diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml index e6636e3239..a758d79069 100644 --- a/testing-modules/junit-5-basics/pom.xml +++ b/testing-modules/junit-5-basics/pom.xml @@ -17,7 +17,7 @@ org.junit.platform - junit-platform-runner + junit-platform-suite ${junit-platform.version} test diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/GreetingsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/GreetingsUnitTest.java index a07162ceed..1ff21548b8 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/GreetingsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/GreetingsUnitTest.java @@ -3,12 +3,9 @@ package com.baeldung; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import com.baeldung.junit5.Greetings; -@RunWith(JUnitPlatform.class) public class GreetingsUnitTest { @Test diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java index 9b67426dfa..bc64bc0804 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java @@ -4,7 +4,6 @@ import org.junit.jupiter.api.*; import java.util.logging.Logger; -//@RunWith(JUnitPlatform.class) class JUnit5NewFeaturesUnitTest { private static final Logger log = Logger.getLogger(JUnit5NewFeaturesUnitTest.class.getName()); diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java index c2bbfd4d07..b324910ab7 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleUnitTest.java @@ -6,12 +6,9 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; @Tag("annotations") @Tag("junit5") -@RunWith(JUnitPlatform.class) public class AnnotationTestExampleUnitTest { @Test public void shouldRaiseAnException() throws Exception { diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java index c35611aad1..14b1162ecf 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/AssertionsExampleUnitTest.java @@ -6,10 +6,7 @@ import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; -@RunWith(JUnitPlatform.class) public class AssertionsExampleUnitTest { @Test @Disabled diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java index 5181d54a46..68bb66657e 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeAllAndAfterAllAnnotationsUnitTest.java @@ -3,12 +3,9 @@ package com.baeldung.migration.junit5; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@RunWith(JUnitPlatform.class) public class BeforeAllAndAfterAllAnnotationsUnitTest { private static final Logger LOG = LoggerFactory.getLogger(BeforeAllAndAfterAllAnnotationsUnitTest.class); diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java index b2112ef2c3..283665798d 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/BeforeEachAndAfterEachAnnotationsUnitTest.java @@ -9,12 +9,9 @@ import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@RunWith(JUnitPlatform.class) public class BeforeEachAndAfterEachAnnotationsUnitTest { private static final Logger LOG = LoggerFactory.getLogger(BeforeEachAndAfterEachAnnotationsUnitTest.class); diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java index c67a57dcbd..5c878ef7d3 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/migration/junit5/RuleExampleUnitTest.java @@ -1,14 +1,12 @@ package com.baeldung.migration.junit5; -import com.baeldung.migration.junit5.extensions.TraceUnitExtension; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@RunWith(JUnitPlatform.class) +import com.baeldung.migration.junit5.extensions.TraceUnitExtension; + @ExtendWith(TraceUnitExtension.class) public class RuleExampleUnitTest { diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/suites/AllUnitTest.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/suites/AllUnitTest.java index 30b92ad428..b14440f1f2 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/suites/AllUnitTest.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/suites/AllUnitTest.java @@ -1,12 +1,13 @@ package com.baeldung.suites; -import org.junit.platform.runner.JUnitPlatform; +import org.junit.platform.suite.api.ExcludePackages; import org.junit.platform.suite.api.SelectPackages; -import org.junit.runner.RunWith; +import org.junit.platform.suite.api.Suite; -@RunWith(JUnitPlatform.class) +@Suite @SelectPackages("com.baeldung") -// @SelectClasses({AssertionTest.class, AssumptionTest.class, ExceptionTest.class}) +@ExcludePackages("com.baeldung.suites") public class AllUnitTest { } + \ No newline at end of file diff --git a/testing-modules/junit-5-basics/src/test/java/com/baeldung/tags/EmployeeDAOTestSuite.java b/testing-modules/junit-5-basics/src/test/java/com/baeldung/tags/EmployeeDAOTestSuite.java index 783e5a81a2..cddb76381f 100644 --- a/testing-modules/junit-5-basics/src/test/java/com/baeldung/tags/EmployeeDAOTestSuite.java +++ b/testing-modules/junit-5-basics/src/test/java/com/baeldung/tags/EmployeeDAOTestSuite.java @@ -1,11 +1,8 @@ package com.baeldung.tags; -import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.IncludeTags; import org.junit.platform.suite.api.SelectPackages; -import org.junit.runner.RunWith; -@RunWith(JUnitPlatform.class) @SelectPackages("com.baeldung.tags") @IncludeTags("UnitTest") public class EmployeeDAOTestSuite { diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index f794c3990f..047eddcbcb 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -32,12 +32,6 @@ junit-platform-engine ${junit-platform.version} - - org.junit.platform - junit-platform-runner - ${junit-platform.version} - test - org.junit.platform junit-platform-console-standalone diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java index e13b4e24be..6aa3dd4a7f 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java @@ -3,14 +3,15 @@ package com.baeldung.junit5.mockito; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; 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.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -25,7 +26,6 @@ import com.baeldung.junit5.mockito.service.Errors; import com.baeldung.junit5.mockito.service.UserService; @ExtendWith(MockitoExtension.class) -@RunWith(JUnitPlatform.class) public class UserServiceUnitTest { UserService userService; diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java index 3db44c9d63..ce9b188afa 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorUnitTest.java @@ -8,10 +8,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; -@RunWith(JUnitPlatform.class) @DisplayName("Testing PersonValidator") public class PersonValidatorUnitTest { diff --git a/testing-modules/junit5-migration/pom.xml b/testing-modules/junit5-migration/pom.xml index 3ea035c4f9..3720c1dc4a 100644 --- a/testing-modules/junit5-migration/pom.xml +++ b/testing-modules/junit5-migration/pom.xml @@ -22,7 +22,7 @@ org.junit.platform - junit-platform-runner + junit-platform-suite ${junit-platform.version} test diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java index 16de0be9d8..52d8f8f60a 100644 --- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java @@ -1,17 +1,14 @@ package com.baeldung.junit5; +import java.time.Duration; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; - -import java.time.Duration; @Tag("annotations") @Tag("junit5") -@RunWith(JUnitPlatform.class) public class AnnotationTestExampleUnitTest { @Test public void shouldRaiseAnException() throws Exception { diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java index 297d0f1730..df509f561a 100644 --- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java @@ -2,10 +2,7 @@ package com.baeldung.junit5; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; -@RunWith(JUnitPlatform.class) @ExtendWith(TraceUnitExtension.class) public class RuleExampleUnitTest { diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectClassesSuiteUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectClassesSuiteUnitTest.java index 7b4bd746bf..f307a75274 100644 --- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectClassesSuiteUnitTest.java +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectClassesSuiteUnitTest.java @@ -1,10 +1,9 @@ package com.baeldung.junit5vstestng; -import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.SelectClasses; -import org.junit.runner.RunWith; +import org.junit.platform.suite.api.Suite; -@RunWith(JUnitPlatform.class) +@Suite @SelectClasses({Class1UnitTest.class, Class2UnitTest.class}) public class SelectClassesSuiteUnitTest { diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java index 7378eafaa7..ef8756a2bb 100644 --- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java @@ -1,10 +1,9 @@ package com.baeldung.junit5vstestng; -import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.SelectPackages; -import org.junit.runner.RunWith; +import org.junit.platform.suite.api.Suite; -@RunWith(JUnitPlatform.class) +@Suite @SelectPackages({ "com.baeldung.java.suite.childpackage1", "com.baeldung.java.suite.childpackage2" }) public class SelectPackagesSuiteUnitTest { diff --git a/testing-modules/testng-command-line/pom.xml b/testing-modules/testng-command-line/pom.xml index efc49b187d..a71238f4fb 100644 --- a/testing-modules/testng-command-line/pom.xml +++ b/testing-modules/testng-command-line/pom.xml @@ -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