diff --git a/.gitignore b/.gitignore index 21586748b7..b981a473f6 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ .idea/ *.iml *.iws +out/ # Mac .DS_Store @@ -27,6 +28,9 @@ log/ target/ +# Gradle +.gradle/ + spring-openid/src/main/resources/application.properties .recommenders/ /spring-hibernate4/nbproject/ diff --git a/azure/README.md b/azure/README.md index c60186e1ce..ae8c443660 100644 --- a/azure/README.md +++ b/azure/README.md @@ -1,4 +1,4 @@ ### Relevant Articles: -- [Deploy Spring Boot App to Azure](http://www.baeldung.com/spring-boot-azure) +- [Deploy a Spring Boot App to Azure](http://www.baeldung.com/spring-boot-azure) diff --git a/blade/README.md b/blade/README.md index d823de775f..1f2a00ed3f 100644 --- a/blade/README.md +++ b/blade/README.md @@ -1,5 +1,5 @@ ### Relevant Articles: -- [Blade - A Complete GuideBook](http://www.baeldung.com/blade) +- [Blade – A Complete Guidebook](http://www.baeldung.com/blade) -Run Integration Tests with `mvn integration-test` \ No newline at end of file +Run Integration Tests with `mvn integration-test` diff --git a/cloud-foundry-uaa/README.md b/cloud-foundry-uaa/README.md new file mode 100644 index 0000000000..b2f382cad1 --- /dev/null +++ b/cloud-foundry-uaa/README.md @@ -0,0 +1,3 @@ +### Revelant Articles + +- [A Quick Guide To Using Cloud Foundry UAA](https://www.baeldung.com/cloud-foundry-uaa) diff --git a/core-groovy-2/README.md b/core-groovy-2/README.md new file mode 100644 index 0000000000..f60bdb3cbe --- /dev/null +++ b/core-groovy-2/README.md @@ -0,0 +1,7 @@ +# Groovy + +## Relevant articles: + +- [String Matching in Groovy](http://www.baeldung.com/) +- [Groovy def Keyword] + diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml new file mode 100644 index 0000000000..77de9c8fc8 --- /dev/null +++ b/core-groovy-2/pom.xml @@ -0,0 +1,131 @@ + + + 4.0.0 + core-groovy-2 + 1.0-SNAPSHOT + core-groovy-2 + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.codehaus.groovy + groovy + ${groovy.version} + + + org.codehaus.groovy + groovy-all + ${groovy-all.version} + pom + + + org.codehaus.groovy + groovy-dateutil + ${groovy.version} + + + org.codehaus.groovy + groovy-sql + ${groovy-sql.version} + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.hsqldb + hsqldb + ${hsqldb.version} + test + + + org.spockframework + spock-core + ${spock-core.version} + test + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + ${gmavenplus-plugin.version} + + + + addSources + addTestSources + compile + compileTests + + + + + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + + maven-surefire-plugin + 2.20.1 + + false + + **/*Test.java + **/*Spec.java + + + + + + + + + central + http://jcenter.bintray.com + + + + + 1.0.0 + 2.5.6 + 2.5.6 + 2.5.6 + 2.4.0 + 1.1-groovy-2.4 + 1.6 + + + diff --git a/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy new file mode 100644 index 0000000000..310d97d3fd --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy @@ -0,0 +1,79 @@ +package com.baeldung.defkeyword + +import org.codehaus.groovy.runtime.NullObject +import org.codehaus.groovy.runtime.typehandling.GroovyCastException + +import groovy.transform.TypeChecked +import groovy.transform.TypeCheckingMode + +@TypeChecked +class DefUnitTest extends GroovyTestCase { + + def id + def firstName = "Samwell" + def listOfCountries = ['USA', 'UK', 'FRANCE', 'INDIA'] + + @TypeChecked(TypeCheckingMode.SKIP) + def multiply(x, y) { + return x*y + } + + @TypeChecked(TypeCheckingMode.SKIP) + void testDefVariableDeclaration() { + + def list + assert list.getClass() == org.codehaus.groovy.runtime.NullObject + assert list.is(null) + + list = [1,2,4] + assert list instanceof ArrayList + } + + @TypeChecked(TypeCheckingMode.SKIP) + void testTypeVariables() { + int rate = 200 + try { + rate = [12] //GroovyCastException + rate = "nill" //GroovyCastException + } catch(GroovyCastException) { + println "Cannot assign anything other than integer" + } + } + + @TypeChecked(TypeCheckingMode.SKIP) + void testDefVariableMultipleAssignment() { + def rate + assert rate == null + assert rate.getClass() == org.codehaus.groovy.runtime.NullObject + + rate = 12 + assert rate instanceof Integer + + rate = "Not Available" + assert rate instanceof String + + rate = [1, 4] + assert rate instanceof List + + assert divide(12, 3) instanceof BigDecimal + assert divide(1, 0) instanceof String + + } + + def divide(int x, int y) { + if(y==0) { + return "Should not divide by 0" + } else { + return x/y + } + } + + def greetMsg() { + println "Hello! I am Groovy" + } + + void testDefVsType() { + def int count + assert count instanceof Integer + } +} \ No newline at end of file diff --git a/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy b/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy new file mode 100644 index 0000000000..3865bc73fa --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy @@ -0,0 +1,44 @@ +package com.baeldung.strings + +import spock.lang.Specification + +import java.util.regex.Pattern + +class StringMatchingSpec extends Specification { + + def "pattern operator example"() { + given: "a pattern" + def p = ~'foo' + + expect: + p instanceof Pattern + + and: "you can use slash strings to avoid escaping of blackslash" + def digitPattern = ~/\d*/ + digitPattern.matcher('4711').matches() + } + + def "match operator example"() { + expect: + 'foobar' ==~ /.*oba.*/ + + and: "matching is strict" + !('foobar' ==~ /foo/) + } + + def "find operator example"() { + when: "using the find operator" + def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/ + + then: "will find groups" + matcher.size() == 2 + + and: "can access groups using array" + matcher[0][0] == 'foo and bar' + matcher[1][2] == 'buz' + + and: "you can use it as a predicate" + 'foobarbaz' =~ /bar/ + } + +} diff --git a/core-groovy/README.md b/core-groovy/README.md index 606a317747..321c37be8d 100644 --- a/core-groovy/README.md +++ b/core-groovy/README.md @@ -8,6 +8,8 @@ - [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings) - [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating) - [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits) +- [Closures in Groovy](https://www.baeldung.com/groovy-closures) +- [Finding Elements in Collections in Groovy](https://www.baeldung.com/groovy-collections-find-elements) - [Lists in Groovy](https://www.baeldung.com/groovy-lists) - [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date) -- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io) +- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io) \ No newline at end of file diff --git a/core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy b/core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy new file mode 100644 index 0000000000..3865bc73fa --- /dev/null +++ b/core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy @@ -0,0 +1,44 @@ +package com.baeldung.strings + +import spock.lang.Specification + +import java.util.regex.Pattern + +class StringMatchingSpec extends Specification { + + def "pattern operator example"() { + given: "a pattern" + def p = ~'foo' + + expect: + p instanceof Pattern + + and: "you can use slash strings to avoid escaping of blackslash" + def digitPattern = ~/\d*/ + digitPattern.matcher('4711').matches() + } + + def "match operator example"() { + expect: + 'foobar' ==~ /.*oba.*/ + + and: "matching is strict" + !('foobar' ==~ /foo/) + } + + def "find operator example"() { + when: "using the find operator" + def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/ + + then: "will find groups" + matcher.size() == 2 + + and: "can access groups using array" + matcher[0][0] == 'foo and bar' + matcher[1][2] == 'buz' + + and: "you can use it as a predicate" + 'foobarbaz' =~ /bar/ + } + +} diff --git a/core-java-11/README.md b/core-java-11/README.md index b09649f4f1..a4b0e0e59c 100644 --- a/core-java-11/README.md +++ b/core-java-11/README.md @@ -6,3 +6,4 @@ - [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control) - [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client) - [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector) +- [Guide to jlink](https://www.baeldung.com/jlink) diff --git a/core-java-8-2/README.md b/core-java-8-2/README.md new file mode 100644 index 0000000000..e2b12e8819 --- /dev/null +++ b/core-java-8-2/README.md @@ -0,0 +1,6 @@ +========= + +## Core Java 8 Cookbooks and Examples (part 2) + +### Relevant Articles: +- [Anonymous Classes in Java](http://www.baeldung.com/) diff --git a/core-java-8-2/pom.xml b/core-java-8-2/pom.xml new file mode 100644 index 0000000000..7035f12fb7 --- /dev/null +++ b/core-java-8-2/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + com.baeldung + core-java-8-2 + 0.1.0-SNAPSHOT + core-java-8-2 + jar + + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + UTF-8 + 1.8 + 1.8 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + diff --git a/core-java-8/README.md b/core-java-8/README.md index 99182da390..d11d2debce 100644 --- a/core-java-8/README.md +++ b/core-java-8/README.md @@ -3,7 +3,7 @@ ## Core Java 8 Cookbooks and Examples ### Relevant Articles: -- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors) +- [Guide to Java 8’s Collectors](http://www.baeldung.com/java-8-collectors) - [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces) - [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) - [New Features in Java 8](http://www.baeldung.com/java-8-new-features) diff --git a/core-java-8/src/main/java/com/baeldung/Adder.java b/core-java-8/src/main/java/com/baeldung/Adder.java deleted file mode 100644 index e3e100f121..0000000000 --- a/core-java-8/src/main/java/com/baeldung/Adder.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung; - -import java.util.function.Consumer; -import java.util.function.Function; - -public interface Adder { - - String addWithFunction(Function f); - - void addWithConsumer(Consumer f); - -} diff --git a/core-java-8/src/main/java/com/baeldung/AdderImpl.java b/core-java-8/src/main/java/com/baeldung/AdderImpl.java deleted file mode 100644 index 7852934d55..0000000000 --- a/core-java-8/src/main/java/com/baeldung/AdderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung; - - -import java.util.function.Consumer; -import java.util.function.Function; - -public class AdderImpl implements Adder { - - @Override - public String addWithFunction(final Function f) { - return f.apply("Something "); - } - - @Override - public void addWithConsumer(final Consumer f) { - } - -} diff --git a/core-java-8/src/main/java/com/baeldung/Bar.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Bar.java similarity index 80% rename from core-java-8/src/main/java/com/baeldung/Bar.java rename to core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Bar.java index 6219bddf74..4cf0aa2399 100644 --- a/core-java-8/src/main/java/com/baeldung/Bar.java +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Bar.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.java8.lambda.tips; @FunctionalInterface diff --git a/core-java-8/src/main/java/com/baeldung/Baz.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Baz.java similarity index 80% rename from core-java-8/src/main/java/com/baeldung/Baz.java rename to core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Baz.java index 23180551ac..c7efe14c89 100644 --- a/core-java-8/src/main/java/com/baeldung/Baz.java +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Baz.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.java8.lambda.tips; @FunctionalInterface diff --git a/core-java-8/src/main/java/com/baeldung/Foo.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Foo.java similarity index 75% rename from core-java-8/src/main/java/com/baeldung/Foo.java rename to core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Foo.java index c8223727a1..b63ba61e7e 100644 --- a/core-java-8/src/main/java/com/baeldung/Foo.java +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Foo.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.java8.lambda.tips; @FunctionalInterface diff --git a/core-java-8/src/main/java/com/baeldung/FooExtended.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java similarity index 81% rename from core-java-8/src/main/java/com/baeldung/FooExtended.java rename to core-java-8/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java index 8c9b21e397..9141cd8eb8 100644 --- a/core-java-8/src/main/java/com/baeldung/FooExtended.java +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/FooExtended.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.java8.lambda.tips; @FunctionalInterface diff --git a/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Processor.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Processor.java new file mode 100644 index 0000000000..7931129cf5 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/Processor.java @@ -0,0 +1,12 @@ +package com.baeldung.java8.lambda.tips; + +import java.util.concurrent.Callable; +import java.util.function.Supplier; + +public interface Processor { + + String processWithCallable(Callable c) throws Exception; + + String processWithSupplier(Supplier s); + +} diff --git a/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java new file mode 100644 index 0000000000..cb1b3dcdd2 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/ProcessorImpl.java @@ -0,0 +1,20 @@ +package com.baeldung.java8.lambda.tips; + + +import java.util.concurrent.Callable; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +public class ProcessorImpl implements Processor { + + @Override + public String processWithCallable(Callable c) throws Exception { + return c.call(); + } + + @Override + public String processWithSupplier(Supplier s) { + return s.get(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/UseFoo.java b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java similarity index 95% rename from core-java-8/src/main/java/com/baeldung/UseFoo.java rename to core-java-8/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java index 950d02062d..a64d8bb920 100644 --- a/core-java-8/src/main/java/com/baeldung/UseFoo.java +++ b/core-java-8/src/main/java/com/baeldung/java8/lambda/tips/UseFoo.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.java8.lambda.tips; import java.util.function.Function; diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasUnitTest.java b/core-java-8/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java similarity index 93% rename from core-java-8/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasUnitTest.java rename to core-java-8/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java index 13ddcc805f..b409f8e37f 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/java8/lambda/tips/Java8FunctionalInteracesLambdasUnitTest.java @@ -1,8 +1,8 @@ -package com.baeldung.java8; +package com.baeldung.java8.lambda.tips; -import com.baeldung.Foo; -import com.baeldung.FooExtended; -import com.baeldung.UseFoo; +import com.baeldung.java8.lambda.tips.Foo; +import com.baeldung.java8.lambda.tips.FooExtended; +import com.baeldung.java8.lambda.tips.UseFoo; import org.junit.Before; import org.junit.Test; diff --git a/core-java-8/src/test/java/com/baeldung/reduceIfelse/CalculatorUnitTest.java b/core-java-8/src/test/java/com/baeldung/reduceIfelse/CalculatorUnitTest.java index fa351930d8..1ff34bee89 100644 --- a/core-java-8/src/test/java/com/baeldung/reduceIfelse/CalculatorUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/reduceIfelse/CalculatorUnitTest.java @@ -29,4 +29,11 @@ public class CalculatorUnitTest { int result = calculator.calculate(new AddCommand(3, 7)); assertEquals(10, result); } + + @Test + public void whenCalculateUsingFactory_thenReturnCorrectResult() { + Calculator calculator = new Calculator(); + int result = calculator.calculateUsingFactory(3, 4, "add"); + assertEquals(7, result); + } } diff --git a/core-java-9/README.md b/core-java-9/README.md index 2477a38c00..8fdc3f6ee2 100644 --- a/core-java-9/README.md +++ b/core-java-9/README.md @@ -5,26 +5,21 @@ [Java 9 New Features](http://www.baeldung.com/new-java-9) ### Relevant Articles: -- [Java 9 Stream API Improvements](http://www.baeldung.com/java-9-stream-api) -- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods) + +- [Java 9 New Features](https://www.baeldung.com/new-java-9) - [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors) -- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture) -- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api) - [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity) -- [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional) -- [Java 9 Reactive Streams](http://www.baeldung.com/java-9-reactive-streams) -- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new) -- [Java 9 Variable Handles Demistyfied](http://www.baeldung.com/java-variable-handles) +- [Java 9 Variable Handles Demystified](http://www.baeldung.com/java-variable-handles) - [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client) - [Method Handles in Java](http://www.baeldung.com/java-method-handles) - [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) -- [A Guide to Java 9 Modularity](http://www.baeldung.com/java-9-modularity) - [Optional orElse Optional](http://www.baeldung.com/java-optional-or-else-optional) -- [Java 9 java.lang.Module API](http://www.baeldung.com/java-9-module-api) - [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) -- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api) - [Immutable Set in Java](https://www.baeldung.com/java-immutable-set) - [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar) - [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation) +- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api) +- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api) + diff --git a/core-java-collections-map/README.md b/core-java-collections-map/README.md new file mode 100644 index 0000000000..da02928118 --- /dev/null +++ b/core-java-collections-map/README.md @@ -0,0 +1,6 @@ +========= + +## Core Java Collections 2 + +### Relevant Articles: +- Java - Copying a HashMap diff --git a/core-java-collections-map/pom.xml b/core-java-collections-map/pom.xml new file mode 100644 index 0000000000..8c0aef54bf --- /dev/null +++ b/core-java-collections-map/pom.xml @@ -0,0 +1,78 @@ + + 4.0.0 + core-java-collections-map + 0.1.0-SNAPSHOT + core-java-collections-map + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.eclipse.collections + eclipse-collections + ${eclipse.collections.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.openjdk.jmh + jmh-core + ${openjdk.jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${openjdk.jmh.version} + + + org.apache.commons + commons-exec + ${commons-exec.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + 1.19 + 1.2.0 + 3.8.1 + 4.1 + 4.01 + 1.7.0 + 3.11.1 + 7.1.0 + 1.3 + + diff --git a/core-java-collections-map/src/main/java/com/baeldung/copyinghashmap/CopyHashMap.java b/core-java-collections-map/src/main/java/com/baeldung/copyinghashmap/CopyHashMap.java new file mode 100644 index 0000000000..e1649f593c --- /dev/null +++ b/core-java-collections-map/src/main/java/com/baeldung/copyinghashmap/CopyHashMap.java @@ -0,0 +1,55 @@ +package com.baeldung.copyinghashmap; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.SerializationUtils; + +public class CopyHashMap { + + public static HashMap copyUsingConstructor(HashMap originalMap) { + return new HashMap(originalMap); + } + + public static HashMap copyUsingClone(HashMap originalMap) { + return (HashMap) originalMap.clone(); + } + + public static HashMap copyUsingPut(HashMap originalMap) { + HashMap shallowCopy = new HashMap(); + Set> entries = originalMap.entrySet(); + for(Map.Entry mapEntry: entries) { + shallowCopy.put(mapEntry.getKey(), mapEntry.getValue()); + } + + return shallowCopy; + } + + public static HashMap copyUsingPutAll(HashMap originalMap) { + HashMap shallowCopy = new HashMap(); + shallowCopy.putAll(originalMap); + + return shallowCopy; + } + + public static HashMap copyUsingJava8Stream(HashMap originalMap) { + Set> entries = originalMap.entrySet(); + HashMap shallowCopy = (HashMap) entries + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + return shallowCopy; + } + + public static HashMap shallowCopy(HashMap originalMap) { + return (HashMap) originalMap.clone(); + } + + public static HashMap deepCopy(HashMap originalMap) { + return SerializationUtils.clone(originalMap); + } + +} diff --git a/core-java-collections-map/src/test/java/com/baeldung/copyinghashmap/CopyHashMapUnitTest.java b/core-java-collections-map/src/test/java/com/baeldung/copyinghashmap/CopyHashMapUnitTest.java new file mode 100644 index 0000000000..400696d97a --- /dev/null +++ b/core-java-collections-map/src/test/java/com/baeldung/copyinghashmap/CopyHashMapUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.copyinghashmap; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; + +public class CopyHashMapUnitTest { + + @Test + public void givenHashMap_whenShallowCopy_thenCopyisNotSameAsOriginal() { + + HashMap map = new HashMap<>(); + Employee emp1 = new Employee("John"); + Employee emp2 = new Employee("Norman"); + map.put("emp1",emp1); + map.put("emp2",emp2); + + HashMap shallowCopy = CopyHashMap.shallowCopy(map); + + assertThat(shallowCopy).isNotSameAs(map); + + } + + @Test + public void givenHashMap_whenShallowCopyModifyingOriginalObject_thenCopyShouldChange() { + + HashMap map = new HashMap<>(); + Employee emp1 = new Employee("John"); + Employee emp2 = new Employee("Norman"); + map.put("emp1",emp1); + map.put("emp2",emp2); + + HashMap shallowCopy = CopyHashMap.shallowCopy(map); + + emp1.setName("Johny"); + + assertThat(shallowCopy.get("emp1")).isEqualTo(map.get("emp1")); + + } + + @Test + public void givenHashMap_whenDeepCopyModifyingOriginalObject_thenCopyShouldNotChange() { + + HashMap map = new HashMap<>(); + Employee emp1 = new Employee("John"); + Employee emp2 = new Employee("Norman"); + map.put("emp1",emp1); + map.put("emp2",emp2); + HashMap deepCopy = CopyHashMap.deepCopy(map); + + emp1.setName("Johny"); + + assertThat(deepCopy.get("emp1")).isNotEqualTo(map.get("emp1")); + + } + + @Test + public void givenImmutableMap_whenCopyUsingGuava_thenCopyShouldNotChange() { + Employee emp1 = new Employee("John"); + Employee emp2 = new Employee("Norman"); + + Map map = ImmutableMap. builder() + .put("emp1",emp1) + .put("emp2",emp2) + .build(); + Map shallowCopy = ImmutableMap.copyOf(map); + + assertThat(shallowCopy).isSameAs(map); + + } + +} diff --git a/core-java-collections-map/src/test/java/com/baeldung/copyinghashmap/Employee.java b/core-java-collections-map/src/test/java/com/baeldung/copyinghashmap/Employee.java new file mode 100644 index 0000000000..b47fdc768e --- /dev/null +++ b/core-java-collections-map/src/test/java/com/baeldung/copyinghashmap/Employee.java @@ -0,0 +1,28 @@ +package com.baeldung.copyinghashmap; + +import java.io.Serializable; + +public class Employee implements Serializable{ + + private String name; + + public Employee(String name) { + super(); + this.name = name; + } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + +} + + diff --git a/core-java-collections-set/README.md b/core-java-collections-set/README.md new file mode 100644 index 0000000000..710484a2e1 --- /dev/null +++ b/core-java-collections-set/README.md @@ -0,0 +1,6 @@ +========= + +## Core Java Sets Cookbooks and Examples + +### Relevant Articles: +- [Set Operations in Java](http://www.baeldung.com/set-operations-in-java) diff --git a/core-java-collections-set/pom.xml b/core-java-collections-set/pom.xml new file mode 100644 index 0000000000..d5f7937645 --- /dev/null +++ b/core-java-collections-set/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + core-java-collections-set + 0.1.0-SNAPSHOT + core-java-collections-set + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + com.google.guava + guava + ${guava.version} + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + + 4.3 + 27.1-jre + + diff --git a/core-java-collections-set/src/test/java/com/baeldung/set/SetOperationsUnitTest.java b/core-java-collections-set/src/test/java/com/baeldung/set/SetOperationsUnitTest.java new file mode 100644 index 0000000000..7c25585e49 --- /dev/null +++ b/core-java-collections-set/src/test/java/com/baeldung/set/SetOperationsUnitTest.java @@ -0,0 +1,93 @@ +package com.baeldung.set; + +import static org.junit.Assert.*; + +import org.apache.commons.collections4.SetUtils; +import org.junit.Test; + +import com.google.common.collect.Sets; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class SetOperationsUnitTest { + + private Set setA = setOf(1,2,3,4); + private Set setB = setOf(2,4,6,8); + + private static Set setOf(Integer... values) { + return new HashSet(Arrays.asList(values)); + } + + @Test + public void givenTwoSets_WhenWeRetainAll_ThenWeIntersectThem() { + Set intersectSet = new HashSet<>(setA); + intersectSet.retainAll(setB); + assertEquals(setOf(2,4), intersectSet); + } + + @Test + public void givenTwoSets_WhenWeAddAll_ThenWeUnionThem() { + Set unionSet = new HashSet<>(setA); + unionSet.addAll(setB); + assertEquals(setOf(1,2,3,4,6,8), unionSet); + } + + @Test + public void givenTwoSets_WhenRemoveAll_ThenWeGetTheDifference() { + Set differenceSet = new HashSet<>(setA); + differenceSet.removeAll(setB); + assertEquals(setOf(1,3), differenceSet); + } + + @Test + public void givenTwoStreams_WhenWeFilterThem_ThenWeCanGetTheIntersect() { + Set intersectSet = setA.stream() + .filter(setB::contains) + .collect(Collectors.toSet()); + assertEquals(setOf(2,4), intersectSet); + } + + @Test + public void givenTwoStreams_WhenWeConcatThem_ThenWeGetTheUnion() { + Set unionSet = Stream.concat(setA.stream(), setB.stream()) + .collect(Collectors.toSet()); + assertEquals(setOf(1,2,3,4,6,8), unionSet); + } + + @Test + public void givenTwoStreams_WhenWeFilterThem_ThenWeCanGetTheDifference() { + Set differenceSet = setA.stream() + .filter(val -> !setB.contains(val)) + .collect(Collectors.toSet()); + assertEquals(setOf(1,3), differenceSet); + } + + @Test + public void givenTwoSets_WhenWeUseApacheCommonsIntersect_ThenWeGetTheIntersect() { + Set intersectSet = SetUtils.intersection(setA, setB); + assertEquals(setOf(2,4), intersectSet); + } + + @Test + public void givenTwoSets_WhenWeUseApacheCommonsUnion_ThenWeGetTheUnion() { + Set unionSet = SetUtils.union(setA, setB); + assertEquals(setOf(1,2,3,4,6,8), unionSet); + } + + + @Test + public void givenTwoSets_WhenWeUseGuavaIntersect_ThenWeGetTheIntersect() { + Set intersectSet = Sets.intersection(setA, setB); + assertEquals(setOf(2,4), intersectSet); + } + + @Test + public void givenTwoSets_WhenWeUseGuavaUnion_ThenWeGetTheUnion() { + Set unionSet = Sets.union(setA, setB); + assertEquals(setOf(1,2,3,4,6,8), unionSet); + } +} diff --git a/core-java-collections/README.md b/core-java-collections/README.md index 1e504ded65..43f5bfc384 100644 --- a/core-java-collections/README.md +++ b/core-java-collections/README.md @@ -3,7 +3,7 @@ ## Core Java Collections Cookbooks and Examples ### Relevant Articles: -- [Java - Combine Multiple Collections](http://www.baeldung.com/java-combine-multiple-collections) +- [Java – Combine Multiple Collections](http://www.baeldung.com/java-combine-multiple-collections) - [HashSet and TreeSet Comparison](http://www.baeldung.com/java-hashset-vs-treeset) - [Collect a Java Stream to an Immutable Collection](http://www.baeldung.com/java-stream-immutable-collection) - [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque) diff --git a/core-java-concurrency-advanced/README.md b/core-java-concurrency-advanced/README.md index f48fd30c73..8e99858693 100644 --- a/core-java-concurrency-advanced/README.md +++ b/core-java-concurrency-advanced/README.md @@ -12,7 +12,7 @@ - [Guide to the Java Phaser](http://www.baeldung.com/java-phaser) - [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables) - [CyclicBarrier in Java](http://www.baeldung.com/java-cyclic-barrier) -- [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile) +- [Guide to the Volatile Keyword in Java](http://www.baeldung.com/java-volatile) - [Semaphores in Java](http://www.baeldung.com/java-semaphore) - [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread) - [Priority-based Job Scheduling in Java](http://www.baeldung.com/java-priority-job-schedule) @@ -20,6 +20,6 @@ - [Print Even and Odd Numbers Using 2 Threads](https://www.baeldung.com/java-even-odd-numbers-with-2-threads) - [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch) - [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join) -- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random) +- [Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random) - [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join) - [Passing Parameters to Java Threads](https://www.baeldung.com/java-thread-parameters) diff --git a/core-java-concurrency-basic/README.md b/core-java-concurrency-basic/README.md index 7d106095e7..6fa702fbe7 100644 --- a/core-java-concurrency-basic/README.md +++ b/core-java-concurrency-basic/README.md @@ -7,13 +7,13 @@ - [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial) - [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future) - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) -- [Guide to Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized) +- [Guide to the Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized) - [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent) - [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread) - [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop) -- [ExecutorService - Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads) +- [ExecutorService – Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads) - [wait and notify() Methods in Java](http://www.baeldung.com/java-wait-notify) - [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle) - [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable) -- [What is Thread-Safety and How to Achieve it](https://www.baeldung.com/java-thread-safety) +- [What is Thread-Safety and How to Achieve it?](https://www.baeldung.com/java-thread-safety) - [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread) diff --git a/core-java-io/README.md b/core-java-io/README.md index 05b9165147..9ce39459dd 100644 --- a/core-java-io/README.md +++ b/core-java-io/README.md @@ -6,7 +6,7 @@ - [How to Read a Large File Efficiently with Java](http://www.baeldung.com/java-read-lines-large-file) - [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string) - [Java – Write to File](http://www.baeldung.com/java-write-to-file) -- [Java - Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream) +- [Java – Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream) - [Java Scanner](http://www.baeldung.com/java-scanner) - [Java – Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer) - [Java – Directory Size](http://www.baeldung.com/java-folder-size) @@ -14,7 +14,7 @@ - [File Size in Java](http://www.baeldung.com/java-file-size) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) -- [Copy a File with Java](http://www.baeldung.com/java-copy-file) +- [How to Copy a File with Java](http://www.baeldung.com/java-copy-file) - [Java – Append Data to a File](http://www.baeldung.com/java-append-to-file) - [FileNotFoundException in Java](http://www.baeldung.com/java-filenotfound-exception) - [How to Read a File in Java](http://www.baeldung.com/reading-file-in-java) diff --git a/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java b/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java new file mode 100644 index 0000000000..6964ba80e3 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java @@ -0,0 +1,165 @@ +package com.baeldung.filechannel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +public class FileChannelUnitTest { + + @Test + public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream();) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + FileInputStream fin = new FileInputStream("src/test/resources/test_read.in"); + FileChannel channel = fin.getChannel();) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream();) { + + MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5); + + if (buff.hasRemaining()) { + byte[] data = new byte[buff.remaining()]; + buff.get(data); + assertEquals("world", new String(data, StandardCharsets.UTF_8)); + } + } + } + + @Test + public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + String file = "src/test/resources/test_write_using_filechannel.txt"; + try (RandomAccessFile writer = new RandomAccessFile(file, "rw"); + FileChannel channel = writer.getChannel();) { + ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8)); + + channel.write(buff); + + // now we verify whether the file was written correctly + RandomAccessFile reader = new RandomAccessFile(file, "r"); + assertEquals("Hello world", reader.readLine()); + reader.close(); + } + } + + @Test + public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException { + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw"); + FileChannel channel = reader.getChannel(); + FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) { + + assertNotNull(fileLock); + } + } + + @Test + public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel();) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.position()); + + channel.position(4); + assertEquals(4, channel.position()); + } + } + + @Test + public void whenGetFileSize_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel();) { + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.size()); + } + } + + @Test + public void whenTruncateFile_thenCorrect() throws IOException { + String input = "this is a test input"; + + FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt"); + FileChannel channel = fout.getChannel(); + + ByteBuffer buff = ByteBuffer.wrap(input.getBytes()); + channel.write(buff); + buff.flip(); + + channel = channel.truncate(5); + assertEquals(5, channel.size()); + + fout.close(); + channel.close(); + } +} diff --git a/core-java-io/src/test/resources/test_truncate.txt b/core-java-io/src/test/resources/test_truncate.txt new file mode 100644 index 0000000000..26d3b38cdd --- /dev/null +++ b/core-java-io/src/test/resources/test_truncate.txt @@ -0,0 +1 @@ +this \ No newline at end of file diff --git a/core-java-io/src/test/resources/test_write_using_filechannel.txt b/core-java-io/src/test/resources/test_write_using_filechannel.txt new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java-io/src/test/resources/test_write_using_filechannel.txt @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/core-java-jvm/README.md b/core-java-jvm/README.md index 529453f3c4..82067ad952 100644 --- a/core-java-jvm/README.md +++ b/core-java-jvm/README.md @@ -3,4 +3,4 @@ ## Core Java JVM Cookbooks and Examples ### Relevant Articles: -- [Method Inlining in the JVM](http://www.baeldung.com/method-inlining-in-the-jvm/) +- [Method Inlining in the JVM](https://www.baeldung.com/jvm-method-inlining) diff --git a/core-java-lambdas/pom.xml b/core-java-lambdas/pom.xml new file mode 100644 index 0000000000..25538a3524 --- /dev/null +++ b/core-java-lambdas/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + core-java-lambdas + 0.1.0-SNAPSHOT + core-java + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + \ No newline at end of file diff --git a/core-java-lambdas/src/main/java/com/baeldung/lambdas/LambdaVariables.java b/core-java-lambdas/src/main/java/com/baeldung/lambdas/LambdaVariables.java new file mode 100644 index 0000000000..5c1201150f --- /dev/null +++ b/core-java-lambdas/src/main/java/com/baeldung/lambdas/LambdaVariables.java @@ -0,0 +1,88 @@ +package com.baeldung.lambdas; + +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +/** + * Class with examples about working with capturing lambdas. + */ +public class LambdaVariables { + + private volatile boolean run = true; + private int start = 0; + + private ExecutorService executor = Executors.newFixedThreadPool(3); + + public static void main(String[] args) { + new LambdaVariables().localVariableMultithreading(); + } + + Supplier incrementer(int start) { + return () -> start; // can't modify start parameter inside the lambda + } + + Supplier incrementer() { + return () -> start++; + } + + public void localVariableMultithreading() { + boolean run = true; + executor.execute(() -> { + while (run) { + // do operation + } + }); + // commented because it doesn't compile, it's just an example of non-final local variables in lambdas + // run = false; + } + + public void instanceVariableMultithreading() { + executor.execute(() -> { + while (run) { + // do operation + } + }); + + run = false; + } + + /** + * WARNING: always avoid this workaround!! + */ + public void workaroundSingleThread() { + int[] holder = new int[] { 2 }; + IntStream sums = IntStream + .of(1, 2, 3) + .map(val -> val + holder[0]); + + holder[0] = 0; + + System.out.println(sums.sum()); + } + + /** + * WARNING: always avoid this workaround!! + */ + public void workaroundMultithreading() { + int[] holder = new int[] { 2 }; + Runnable runnable = () -> System.out.println(IntStream + .of(1, 2, 3) + .map(val -> val + holder[0]) + .sum()); + + new Thread(runnable).start(); + + // simulating some processing + try { + Thread.sleep(new Random().nextInt(3) * 1000L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + holder[0] = 0; + } + +} diff --git a/core-java-lang-oop-2/README.md b/core-java-lang-oop-2/README.md index e309810ba2..af0aed5af3 100644 --- a/core-java-lang-oop-2/README.md +++ b/core-java-lang-oop-2/README.md @@ -3,3 +3,4 @@ ## Core Java Lang OOP 2 Cookbooks and Examples ### Relevant Articles: +- [Generic Constructors in Java](https://www.baeldung.com/java-generic-constructors) diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Book.java b/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Book.java new file mode 100644 index 0000000000..964156e8e4 --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Book.java @@ -0,0 +1,15 @@ +package com.baeldung.anonymous; + +public class Book { + + final String title; + + public Book(String title) { + this.title = title; + } + + public String description() { + return "Title: " + title; + } + +} diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Main.java b/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Main.java new file mode 100644 index 0000000000..d4eed69567 --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Main.java @@ -0,0 +1,64 @@ +package com.baeldung.anonymous; + +import java.util.ArrayList; +import java.util.List; + +/** + * Code snippet that illustrates the usage of anonymous classes. + * + * Note that use of Runnable instances in this example does not demonstrate their + * common use. + * + * @author A. Shcherbakov + * + */ +public class Main { + + public static void main(String[] args) { + final List actions = new ArrayList(2); + + Runnable action = new Runnable() { + @Override + public void run() { + System.out.println("Hello from runnable."); + } + + }; + actions.add(action); + + Book book = new Book("Design Patterns") { + @Override + public String description() { + return "Famous GoF book."; + } + }; + + System.out.println(String.format("Title: %s, description: %s", book.title, book.description())); + + actions.add(new Runnable() { + @Override + public void run() { + System.out.println("Hello from runnable #2."); + + } + }); + + int count = 1; + + Runnable action2 = new Runnable() { + static final int x = 0; + // static int y = 0; + + @Override + public void run() { + System.out.println(String.format("Runnable with captured variables: count = %s, x = %s", count, x)); + } + }; + actions.add(action2); + + for (Runnable a : actions) { + a.run(); + } + } + +} diff --git a/core-java-lang-oop/README.md b/core-java-lang-oop/README.md index 970a8d44b1..c9ee9a9e94 100644 --- a/core-java-lang-oop/README.md +++ b/core-java-lang-oop/README.md @@ -10,7 +10,7 @@ - [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy) - [Guide to Inheritance in Java](http://www.baeldung.com/java-inheritance) - [Object Type Casting in Java](http://www.baeldung.com/java-type-casting) -- [The "final" Keyword in Java](http://www.baeldung.com/java-final) +- [The “final” Keyword in Java](http://www.baeldung.com/java-final) - [Type Erasure in Java Explained](http://www.baeldung.com/java-type-erasure) - [Pass-By-Value as a Parameter Passing Mechanism in Java](http://www.baeldung.com/java-pass-by-value-or-pass-by-reference) - [Variable and Method Hiding in Java](http://www.baeldung.com/java-variable-method-hiding) diff --git a/core-java-lang/README.md b/core-java-lang/README.md index eaedc93eed..e9169a5820 100644 --- a/core-java-lang/README.md +++ b/core-java-lang/README.md @@ -12,7 +12,7 @@ - [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies) - [Java Double Brace Initialization](http://www.baeldung.com/java-double-brace-initialization) - [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator) -- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) +- [Comparator and Comparable in Java](http://www.baeldung.com/java-comparator-comparable) - [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break) - [Nested Classes in Java](http://www.baeldung.com/java-nested-classes) - [A Guide to Inner Interfaces in Java](http://www.baeldung.com/java-inner-interfaces) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml new file mode 100644 index 0000000000..ad49cceb9d --- /dev/null +++ b/core-java-modules/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + core-java-modules + core-java-modules + pom + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + + pre-jpms + + + \ No newline at end of file diff --git a/core-java-modules/pre-jpms/pom.xml b/core-java-modules/pre-jpms/pom.xml new file mode 100644 index 0000000000..169cd21f3e --- /dev/null +++ b/core-java-modules/pre-jpms/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + pre-jpms + 0.0.1-SNAPSHOT + jar + pre-jpms + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + ../../ + + + + + org.slf4j + slf4j-api + 1.7.25 + + + + pre-jpms + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + package + + copy-dependencies + + + + ${project.build.directory}/dependency-jars/ + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.baeldung.prejpms.App + true + dependency-jars/ + + + + + + + + + UTF-8 + + diff --git a/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java b/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java new file mode 100644 index 0000000000..1afaae30e4 --- /dev/null +++ b/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/App.java @@ -0,0 +1,77 @@ +package com.baeldung.prejpms; + +import java.io.StringWriter; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.crypto.provider.SunJCE; + +import sun.misc.BASE64Encoder; +import sun.reflect.Reflection; + +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) throws Exception { + + getCrytpographyProviderName(); + getCallStackClassNames(); + getXmlFromObject(new Book(100, "Java Modules Architecture")); + getBase64EncodedString("Java"); + } + + private static void getCrytpographyProviderName() { + try { + LOGGER.info("1. JCE Provider Name: {}\n", new SunJCE().getName()); + } catch (Throwable e) { + LOGGER.error(e.toString()); + } + } + + private static void getCallStackClassNames() { + try { + StringBuffer sbStack = new StringBuffer(); + int i = 0; + Class caller = Reflection.getCallerClass(i++); + do { + sbStack.append(i + ".") + .append(caller.getName()) + .append("\n"); + caller = Reflection.getCallerClass(i++); + } while (caller != null); + LOGGER.info("2. Call Stack:\n{}", sbStack); + } catch (Throwable e) { + LOGGER.error(e.toString()); + } + } + + private static void getXmlFromObject(Book book) { + try { + Marshaller marshallerObj = JAXBContext.newInstance(Book.class) + .createMarshaller(); + marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + + StringWriter sw = new StringWriter(); + marshallerObj.marshal(book, sw); + LOGGER.info("3. Xml for Book object:\n{}", sw); + } catch (Throwable e) { + LOGGER.error(e.toString()); + } + + } + + private static void getBase64EncodedString(String inputString) { + try { + String encodedString = new BASE64Encoder().encode(inputString.getBytes()); + LOGGER.info("4. Base Encoded String: {}", encodedString); + } catch (Throwable e) { + LOGGER.error(e.toString()); + } + } +} diff --git a/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/Book.java b/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/Book.java new file mode 100644 index 0000000000..6780c73738 --- /dev/null +++ b/core-java-modules/pre-jpms/src/main/java/com/baeldung/prejpms/Book.java @@ -0,0 +1,37 @@ +package com.baeldung.prejpms; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "book") +public class Book { + private long id; + private String name; + + public Book() { + } + + public Book(long id, String name) { + this.id = id; + this.name = name; + } + + @XmlAttribute + public void setId(Long id) { + this.id = id; + } + + @XmlElement(name = "title") + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public Long getId() { + return id; + } +} diff --git a/core-java-modules/pre-jpms/src/main/resources/logback.xml b/core-java-modules/pre-jpms/src/main/resources/logback.xml new file mode 100644 index 0000000000..7c5914e58e --- /dev/null +++ b/core-java-modules/pre-jpms/src/main/resources/logback.xml @@ -0,0 +1,10 @@ + + + + [%level] %msg%n + + + + + + \ No newline at end of file diff --git a/core-java-networking/README.md b/core-java-networking/README.md index e76f28030d..2341520df7 100644 --- a/core-java-networking/README.md +++ b/core-java-networking/README.md @@ -14,4 +14,5 @@ - [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets) - [Guide to Java URL Encoding/Decoding](http://www.baeldung.com/java-url-encoding-decoding) - [Do a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) -- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri) \ No newline at end of file +- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri) +- [Read an InputStream using the Java Server Socket](https://www.baeldung.com/java-inputstream-server-socket) diff --git a/core-java-networking/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java b/core-java-networking/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java index 0b5f6d7714..9fbbee8501 100644 --- a/core-java-networking/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java +++ b/core-java-networking/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java @@ -17,8 +17,8 @@ public class ProxyAcceptCookiePolicy implements CookiePolicy { host = uri.getHost(); } - if (!HttpCookie.domainMatches(acceptedProxy, host)) { - return false; + if (HttpCookie.domainMatches(acceptedProxy, host)) { + return true; } return CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, cookie); diff --git a/core-java/README.md b/core-java/README.md index cbc9251b0b..c2d1b4a06b 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -29,7 +29,7 @@ - [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid) - [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle) - [Class Loaders in Java](http://www.baeldung.com/java-classloaders) -- [Guide to Java Clock Class](http://www.baeldung.com/java-clock) +- [Guide to the Java Clock Class](http://www.baeldung.com/java-clock) - [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class) - [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler) - [How to Get the Size of an Object in Java](http://www.baeldung.com/java-size-of-object) diff --git a/core-kotlin-2/README.md b/core-kotlin-2/README.md index 4ac1c2c7bb..6d0b20135d 100644 --- a/core-kotlin-2/README.md +++ b/core-kotlin-2/README.md @@ -2,5 +2,8 @@ - [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type) - [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges) +- [Creating a Kotlin Range Iterator on a Custom Object](https://www.baeldung.com/kotlin-custom-range-iterator) +- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions) +- [Kotlin Annotations](https://www.baeldung.com/kotlin-annotations) - [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts) -- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison) +- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison) \ No newline at end of file diff --git a/core-kotlin-2/build.gradle b/core-kotlin-2/build.gradle index b058e0ecad..1c52172404 100644 --- a/core-kotlin-2/build.gradle +++ b/core-kotlin-2/build.gradle @@ -5,7 +5,7 @@ version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.2.41' + ext.kotlin_version = '1.3.30' repositories { mavenCentral() @@ -26,8 +26,6 @@ sourceCompatibility = 1.8 compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } -kotlin { experimental { coroutines "enable" } } - repositories { mavenCentral() jcenter() @@ -39,10 +37,22 @@ sourceSets { srcDirs 'com/baeldung/ktor' } } +} +test { + useJUnitPlatform() + testLogging { + events "passed", "skipped", "failed" + } } dependencies { - compile "ch.qos.logback:logback-classic:1.2.1" - testCompile group: 'junit', name: 'junit', version: '4.12' -} \ No newline at end of file + implementation "ch.qos.logback:logback-classic:1.2.1" + implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}" + testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' + testImplementation 'junit:junit:4.12' + testImplementation 'org.assertj:assertj-core:3.12.2' + testImplementation 'org.mockito:mockito-core:2.27.0' + testImplementation "org.jetbrains.kotlin:kotlin-test:${kotlin_version}" + testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:${kotlin_version}" +} diff --git a/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar b/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar index 01b8bf6b1f..5c2d1cf016 100644 Binary files a/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar and b/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar differ diff --git a/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties b/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties index 933b6473ce..5f1b1201a7 100644 --- a/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties +++ b/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip diff --git a/core-kotlin-2/gradlew b/core-kotlin-2/gradlew index cccdd3d517..b0d6d0ab5d 100644 --- a/core-kotlin-2/gradlew +++ b/core-kotlin-2/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 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. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/core-kotlin-2/gradlew.bat b/core-kotlin-2/gradlew.bat index f9553162f1..9991c50326 100644 --- a/core-kotlin-2/gradlew.bat +++ b/core-kotlin-2/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem 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, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/core-kotlin-2/pom.xml b/core-kotlin-2/pom.xml index e329611593..be2f5fa68f 100644 --- a/core-kotlin-2/pom.xml +++ b/core-kotlin-2/pom.xml @@ -20,9 +20,21 @@ ${kotlin.version} - org.junit.platform - junit-platform-runner - ${junit.platform.version} + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + net.bytebuddy + byte-buddy + ${byte-buddy.version} test @@ -37,6 +49,12 @@ ${kotlin.version} test + + org.jetbrains.kotlin + kotlin-test-junit5 + ${kotlin.version} + test + @@ -69,10 +87,11 @@ - 1.2.71 - 1.1.1 - 5.2.0 + 1.3.30 + 5.4.2 + 2.27.0 + 1.9.12 3.10.0 - \ No newline at end of file + diff --git a/core-kotlin-io/.gitignore b/core-kotlin-io/.gitignore new file mode 100644 index 0000000000..f521947850 --- /dev/null +++ b/core-kotlin-io/.gitignore @@ -0,0 +1,11 @@ +/bin/ + +#ignore gradle +.gradle/ + + +#ignore build and generated files +build/ +node/ +target/ +out/ diff --git a/core-kotlin-io/README.md b/core-kotlin-io/README.md new file mode 100644 index 0000000000..c085c0653f --- /dev/null +++ b/core-kotlin-io/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [InputStream to String in Kotlin](https://www.baeldung.com/kotlin-inputstream-to-string) diff --git a/core-kotlin-io/pom.xml b/core-kotlin-io/pom.xml new file mode 100644 index 0000000000..a0b688a223 --- /dev/null +++ b/core-kotlin-io/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + core-kotlin-io + core-kotlin-io + jar + + + com.baeldung + parent-kotlin + 1.0.0-SNAPSHOT + ../parent-kotlin + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + net.bytebuddy + byte-buddy + ${byte-buddy.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + org.jetbrains.kotlin + kotlin-test-junit5 + ${kotlin.version} + test + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + + + + 1.3.30 + 5.4.2 + 2.27.0 + 1.9.12 + 3.10.0 + + + diff --git a/core-kotlin-io/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt b/core-kotlin-io/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt new file mode 100644 index 0000000000..e94a2e84ee --- /dev/null +++ b/core-kotlin-io/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt @@ -0,0 +1,18 @@ +package com.baeldung.inputstream + +import java.io.InputStream + +fun InputStream.readUpToChar(stopChar: Char): String { + val stringBuilder = StringBuilder() + var currentChar = this.read().toChar() + while (currentChar != stopChar) { + stringBuilder.append(currentChar) + currentChar = this.read().toChar() + if (this.available() <= 0) { + stringBuilder.append(currentChar) + break + } + } + return stringBuilder.toString() +} + diff --git a/core-kotlin-io/src/test/kotlin/com/baeldung/console/ConsoleIOUnitTest.kt b/core-kotlin-io/src/test/kotlin/com/baeldung/console/ConsoleIOUnitTest.kt new file mode 100644 index 0000000000..c73096fce6 --- /dev/null +++ b/core-kotlin-io/src/test/kotlin/com/baeldung/console/ConsoleIOUnitTest.kt @@ -0,0 +1,79 @@ +package com.baeldung.console + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test +import org.mockito.Mockito.`when` +import org.mockito.Mockito.mock +import java.io.BufferedReader +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.Console +import java.io.InputStreamReader +import java.io.PrintStream +import java.util.* + + +class ConsoleIOUnitTest { + + @Test + fun givenText_whenPrint_thenPrintText() { + val expectedTest = "Hello from Kotlin" + val out = ByteArrayOutputStream() + System.setOut(PrintStream(out)) + + print(expectedTest) + out.flush() + val printedText = String(out.toByteArray()) + + assertThat(printedText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenRead_thenReadText() { + val expectedTest = "Hello from Kotlin" + val input = ByteArrayInputStream(expectedTest.toByteArray()) + System.setIn(input) + + val readText = readLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenReadWithScanner_thenReadText() { + val expectedTest = "Hello from Kotlin" + val scanner = Scanner(ByteArrayInputStream(expectedTest.toByteArray())) + + val readText = scanner.nextLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenReadWithBufferedReader_thenReadText() { + val expectedTest = "Hello from Kotlin" + val reader = BufferedReader(InputStreamReader(ByteArrayInputStream(expectedTest.toByteArray()))) + + val readText = reader.readLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenReadWithConsole_thenReadText() { + val expectedTest = "Hello from Kotlin" + val console = mock(Console::class.java) + `when`(console.readLine()).thenReturn(expectedTest) + + val readText = console.readLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @AfterEach + fun resetIO() { + System.setOut(System.out) + System.setIn(System.`in`) + } +} \ No newline at end of file diff --git a/core-kotlin-io/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt b/core-kotlin-io/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt new file mode 100644 index 0000000000..d10d23bef0 --- /dev/null +++ b/core-kotlin-io/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt @@ -0,0 +1,72 @@ +package com.baeldung.inputstream + +import kotlinx.io.core.use +import org.junit.Test +import java.io.BufferedReader +import java.io.File +import kotlin.test.assertEquals + +class InputStreamToStringTest { + private val fileName = "src/test/resources/inputstream2string.txt" + private val endOfLine = System.lineSeparator() + private val fileFullContent = "Computer programming can be a hassle$endOfLine" + + "It's like trying to take a defended castle" + + @Test + fun whenReadFileWithBufferedReader_thenFullFileContentIsReadAsString() { + val file = File(fileName) + val inputStream = file.inputStream() + val content = inputStream.bufferedReader().use(BufferedReader::readText) + assertEquals(fileFullContent, content) + } + @Test + fun whenReadFileWithBufferedReaderReadText_thenFullFileContentIsReadAsString() { + val file = File(fileName) + val inputStream = file.inputStream() + val reader = BufferedReader(inputStream.reader()) + var content: String + try { + content = reader.readText() + } finally { + reader.close() + } + assertEquals(fileFullContent, content) + } + @Test + fun whenReadFileWithBufferedReaderManually_thenFullFileContentIsReadAsString() { + val file = File(fileName) + val inputStream = file.inputStream() + val reader = BufferedReader(inputStream.reader()) + val content = StringBuilder() + try { + var line = reader.readLine() + while (line != null) { + content.append(line) + line = reader.readLine() + } + } finally { + reader.close() + } + assertEquals(fileFullContent.replace(endOfLine, ""), content.toString()) + + } + + @Test + fun whenReadFileUpToStopChar_thenPartBeforeStopCharIsReadAsString() { + val file = File(fileName) + val inputStream = file.inputStream() + val content = inputStream.use { it.readUpToChar(' ') } + assertEquals("Computer", content) + } + + @Test + fun whenReadFileWithoutContainingStopChar_thenFullFileContentIsReadAsString() { + val file = File(fileName) + val inputStream = file.inputStream() + val content = inputStream.use { it.readUpToChar('-') } + assertEquals(fileFullContent, content) + } + + +} + diff --git a/core-kotlin-io/src/test/resources/inputstream2string.txt b/core-kotlin-io/src/test/resources/inputstream2string.txt new file mode 100644 index 0000000000..40ef9fc5f3 --- /dev/null +++ b/core-kotlin-io/src/test/resources/inputstream2string.txt @@ -0,0 +1,2 @@ +Computer programming can be a hassle +It's like trying to take a defended castle \ No newline at end of file diff --git a/core-kotlin-io/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/core-kotlin-io/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..ca6ee9cea8 --- /dev/null +++ b/core-kotlin-io/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/core-kotlin/README.md b/core-kotlin/README.md index 73a78eccff..3392db9171 100644 --- a/core-kotlin/README.md +++ b/core-kotlin/README.md @@ -1,7 +1,7 @@ ## Relevant articles: - [Introduction to the Kotlin Language](http://www.baeldung.com/kotlin) -- [A guide to the “when{}” block in Kotlin](http://www.baeldung.com/kotlin-when) +- [Guide to the “when{}” Block in Kotlin](http://www.baeldung.com/kotlin-when) - [Comprehensive Guide to Null Safety in Kotlin](http://www.baeldung.com/kotlin-null-safety) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) - [Difference Between “==” and “===” operators in Kotlin](http://www.baeldung.com/kotlin-equality-operators) diff --git a/core-kotlin/src/test/java/com/baeldung/kotlin/StringUtilTest.java b/core-kotlin/src/test/java/com/baeldung/kotlin/StringUtilUnitTest.java similarity index 94% rename from core-kotlin/src/test/java/com/baeldung/kotlin/StringUtilTest.java rename to core-kotlin/src/test/java/com/baeldung/kotlin/StringUtilUnitTest.java index 3f109b78a2..c7ef18b879 100644 --- a/core-kotlin/src/test/java/com/baeldung/kotlin/StringUtilTest.java +++ b/core-kotlin/src/test/java/com/baeldung/kotlin/StringUtilUnitTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import static com.baeldung.kotlin.Strings.*; -public class StringUtilTest { +public class StringUtilUnitTest { @Test public void shouldEscapeXmlTagsInString() { diff --git a/couchbase/README.md b/couchbase/README.md index 9b76609593..7a99ce4299 100644 --- a/couchbase/README.md +++ b/couchbase/README.md @@ -3,7 +3,7 @@ ### Relevant Articles: - [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk) - [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring) -- [Asynchronous Batch Opereations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase) +- [Asynchronous Batch Operations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase) - [Querying Couchbase with MapReduce Views](http://www.baeldung.com/couchbase-query-mapreduce-view) - [Querying Couchbase with N1QL](http://www.baeldung.com/n1ql-couchbase) diff --git a/fastUtil/pom.xml b/fastUtil/pom.xml new file mode 100644 index 0000000000..fcd9020747 --- /dev/null +++ b/fastUtil/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + + com.baeldung + fastUtil + 1.0-SNAPSHOT + + + + + it.unimi.dsi + fastutil + 8.2.2 + + + + junit + junit + 4.12 + test + + + + org.openjdk.jmh + jmh-core + 1.19 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + test + + + + + + + + \ No newline at end of file diff --git a/fastUtil/src/test/java/com/baeldung/BigArraysUnitTest.java b/fastUtil/src/test/java/com/baeldung/BigArraysUnitTest.java new file mode 100644 index 0000000000..a794d1a2f6 --- /dev/null +++ b/fastUtil/src/test/java/com/baeldung/BigArraysUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung; + +import it.unimi.dsi.fastutil.ints.IntBigArrays; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +public class BigArraysUnitTest { + + @Test + public void givenValidAray_whenWrapped_checkAccessFromIntBigArraysMethodsCorrect() { + int[] oneDArray = new int[] { 2, 1, 5, 2, 1, 7 }; + int[][] twoDArray = IntBigArrays.wrap(oneDArray.clone()); + + int firstIndex = IntBigArrays.get(twoDArray, 0); + int lastIndex = IntBigArrays.get(twoDArray, IntBigArrays.length(twoDArray)-1); + + assertEquals(2, firstIndex); + assertEquals(7, lastIndex); + + } + +} diff --git a/fastUtil/src/test/java/com/baeldung/FastUtilTypeSpecificBenchmarkUnitTest.java b/fastUtil/src/test/java/com/baeldung/FastUtilTypeSpecificBenchmarkUnitTest.java new file mode 100644 index 0000000000..2c77989fe5 --- /dev/null +++ b/fastUtil/src/test/java/com/baeldung/FastUtilTypeSpecificBenchmarkUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung; + +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +public class FastUtilTypeSpecificBenchmarkUnitTest { + + @Param({"100", "1000", "10000", "100000"}) + public int setSize; + + @Benchmark + public IntSet givenFastUtilsIntSetWithInitialSizeSet_whenPopulated_checkTimeTaken() { + IntSet intSet = new IntOpenHashSet(setSize); + for(int i = 0; i < setSize; i++){ + intSet.add(i); + } + return intSet; + } + + + @Benchmark + public Set givenCollectionsHashSetWithInitialSizeSet_whenPopulated_checkTimeTaken() { + Set intSet = new HashSet(setSize); + for(int i = 0; i < setSize; i++){ + intSet.add(i); + } + return intSet; + } + + public static void main(String... args) throws RunnerException { + Options opts = new OptionsBuilder() + .include(".*") + .warmupIterations(1) + .measurementIterations(2) + .jvmArgs("-Xms2g", "-Xmx2g") + .shouldDoGC(true) + .forks(1) + .build(); + + new Runner(opts).run(); + } + + + + +} diff --git a/fastUtil/src/test/java/com/baeldung/FastUtilTypeSpecificUnitTest.java b/fastUtil/src/test/java/com/baeldung/FastUtilTypeSpecificUnitTest.java new file mode 100644 index 0000000000..61295cc6f1 --- /dev/null +++ b/fastUtil/src/test/java/com/baeldung/FastUtilTypeSpecificUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung; + +import it.unimi.dsi.fastutil.doubles.Double2DoubleMap; +import it.unimi.dsi.fastutil.doubles.Double2DoubleOpenHashMap; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + + +public class FastUtilTypeSpecificUnitTest { + + @Test + public void givenValidDouble2DoubleMap_whenContentsQueried_checkCorrect(){ + Double2DoubleMap d2dMap = new Double2DoubleOpenHashMap(); + d2dMap.put(2.0, 5.5); + d2dMap.put(3.0, 6.6); + assertEquals(5.5, d2dMap.get(2.0)); + } + +} diff --git a/gson/README.md b/gson/README.md index fec0506488..268116a2ac 100644 --- a/gson/README.md +++ b/gson/README.md @@ -11,6 +11,6 @@ - [Convert JSON to a Map Using Gson](https://www.baeldung.com/gson-json-to-map) - [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives) - [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject) -- [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field) +- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field) - [Serializing and Deserializing a List with Gson](https://www.baeldung.com/gson-list) diff --git a/guava-collections-set/.gitignore b/guava-collections-set/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/guava-collections-set/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/guava-collections-set/pom.xml b/guava-collections-set/pom.xml new file mode 100644 index 0000000000..46dcae492d --- /dev/null +++ b/guava-collections-set/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + com.baeldung + guava-collections-set + 0.1.0-SNAPSHOT + guava-collections-set + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + guava-collections-set + + + + + 27.1-jre + + 3.6.1 + + + diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java new file mode 100644 index 0000000000..e74db29881 --- /dev/null +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java @@ -0,0 +1,92 @@ +package org.baeldung.guava; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class GuavaMultiSetUnitTest { + + @Test + public void givenMultiSet_whenAddingValues_shouldReturnCorrectCount() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + bookStore.add("Potter"); + + assertThat(bookStore.contains("Potter")).isTrue(); + assertThat(bookStore.count("Potter")).isEqualTo(3); + } + + @Test + public void givenMultiSet_whenRemovingValues_shouldReturnCorrectCount() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + + bookStore.remove("Potter"); + assertThat(bookStore.contains("Potter")).isTrue(); + assertThat(bookStore.count("Potter")).isEqualTo(1); + } + + @Test + public void givenMultiSet_whenSetCount_shouldReturnCorrectCount() { + Multiset bookStore = HashMultiset.create(); + bookStore.setCount("Potter", 50); + assertThat(bookStore.count("Potter")).isEqualTo(50); + } + + @Test + public void givenMultiSet_whenSettingNegativeCount_shouldThrowException() { + Multiset bookStore = HashMultiset.create(); + assertThatThrownBy(() -> bookStore.setCount("Potter", -1)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + public void givenMultiSet_whenSettingCountWithEmptySet_shouldBeSuccessful() { + Multiset bookStore = HashMultiset.create(); + assertThat(bookStore.setCount("Potter", 0, 2)).isTrue(); + } + + @Test + public void givenMultiSet_whenSettingCountWithCorrectValue_shouldBeSuccessful() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + + assertThat(bookStore.setCount("Potter", 2, 52)).isTrue(); + } + + @Test + public void givenMultiSet_whenSettingCountWithIncorrectValue_shouldFail() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + + assertThat(bookStore.setCount("Potter", 5, 52)).isFalse(); + } + + @Test + public void givenMap_compareMultiSetOperations() { + Map bookStore = new HashMap<>(); + bookStore.put("Potter", 3); + + assertThat(bookStore.containsKey("Potter")).isTrue(); + assertThat(bookStore.get("Potter")).isEqualTo(3); + + bookStore.put("Potter", 2); + assertThat(bookStore.get("Potter")).isEqualTo(2); + + bookStore.put("Potter", null); + assertThat(bookStore.containsKey("Potter")).isTrue(); + + bookStore.put("Potter", -1); + assertThat(bookStore.containsKey("Potter")).isTrue(); + } +} \ No newline at end of file diff --git a/guava-modules/guava-21/README.md b/guava-modules/guava-21/README.md index 68c1ac4a8e..4e897325b6 100644 --- a/guava-modules/guava-21/README.md +++ b/guava-modules/guava-21/README.md @@ -1,4 +1,4 @@ ### Relevant articles: -- [New Stream, Comparator and Collector Functionality in Guava 21](http://www.baeldung.com/guava-21-new) +- [New Stream, Comparator and Collector in Guava 21](http://www.baeldung.com/guava-21-new) - [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent) - [Zipping Collections in Java](http://www.baeldung.com/java-collections-zip) diff --git a/httpclient-simple/.gitignore b/httpclient-simple/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/httpclient-simple/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md new file mode 100644 index 0000000000..96d9e9ec0e --- /dev/null +++ b/httpclient-simple/README.md @@ -0,0 +1,12 @@ +========= +## HttpClient 4.x Cookbooks and Examples + +###The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + + +### Relevant Articles: + +- [HttpClient 4 – Get the Status Code](http://www.baeldung.com/httpclient-status-code) +- [HttpClient with SSL](http://www.baeldung.com/httpclient-ssl) +- [HttpClient Basic Authentication](http://www.baeldung.com/httpclient-4-basic-authentication) diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml new file mode 100644 index 0000000000..f3d00251d7 --- /dev/null +++ b/httpclient-simple/pom.xml @@ -0,0 +1,315 @@ + + 4.0.0 + com.baeldung + httpclient-simple + 0.1-SNAPSHOT + httpclient-simple + war + + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + + + + + + + + org.springframework.security + spring-security-web + ${spring.version} + + + org.springframework.security + spring-security-config + ${spring.version} + + + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-expression + ${spring.version} + + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + + org.springframework + spring-oxm + ${spring.version} + + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + org.apache.httpcomponents + httpcore + ${httpcore.version} + + + commons-logging + commons-logging + + + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + fluent-hc + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpmime + ${httpclient.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + org.apache.httpcomponents + httpasyncclient + ${httpasyncclient.version} + + + commons-logging + commons-logging + + + + + com.github.tomakehurst + wiremock + ${wiremock.version} + test + + + + + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + provided + + + + javax.servlet + jstl + ${jstl.version} + runtime + + + + + + com.google.guava + guava + ${guava.version} + + + + + + org.springframework + spring-test + ${spring.version} + test + + + + + httpclient-simple + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + + + + 8082 + + + + + + + + + + live + + + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + + + + 1.2 + 3.1.0 + + 19.0 + 3.5 + 1.10 + 4.1.4 + + 2.5.1 + 4.4.11 + 4.5.8 + + 2.6 + 1.6.1 + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/basic/MyBasicAuthenticationEntryPoint.java b/httpclient-simple/src/main/java/org/baeldung/basic/MyBasicAuthenticationEntryPoint.java new file mode 100644 index 0000000000..6e580e7a22 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/basic/MyBasicAuthenticationEntryPoint.java @@ -0,0 +1,30 @@ +package org.baeldung.basic; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +@Component +public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint { + + @Override + public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException { + response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\""); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + final PrintWriter writer = response.getWriter(); + writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED + " - " + authException.getMessage()); + } + + @Override + public void afterPropertiesSet() throws Exception { + setRealmName("Baeldung"); + super.afterPropertiesSet(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java b/httpclient-simple/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java new file mode 100644 index 0000000000..a2f51d343b --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java @@ -0,0 +1,39 @@ +package org.baeldung.client; + +import java.net.URI; + +import org.apache.http.HttpHost; +import org.apache.http.client.AuthCache; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory { + + HttpHost host; + + public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) { + super(); + this.host = host; + } + + protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { + return createHttpContext(); + } + + private HttpContext createHttpContext() { + + AuthCache authCache = new BasicAuthCache(); + + BasicScheme basicAuth = new BasicScheme(); + authCache.put(host, basicAuth); + + BasicHttpContext localcontext = new BasicHttpContext(); + localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache); + return localcontext; + } +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/client/RestTemplateFactory.java b/httpclient-simple/src/main/java/org/baeldung/client/RestTemplateFactory.java new file mode 100644 index 0000000000..3ed0bc82b7 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/client/RestTemplateFactory.java @@ -0,0 +1,44 @@ +package org.baeldung.client; + +import org.apache.http.HttpHost; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.support.BasicAuthenticationInterceptor; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class RestTemplateFactory implements FactoryBean, InitializingBean { + private RestTemplate restTemplate; + + public RestTemplateFactory() { + super(); + } + + // API + + @Override + public RestTemplate getObject() { + return restTemplate; + } + + @Override + public Class getObjectType() { + return RestTemplate.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + @Override + public void afterPropertiesSet() { + HttpHost host = new HttpHost("localhost", 8082, "http"); + final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryBasicAuth(host); + restTemplate = new RestTemplate(requestFactory); + restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor("user1", "user1Pass")); + } + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/client/spring/ClientConfig.java b/httpclient-simple/src/main/java/org/baeldung/client/spring/ClientConfig.java new file mode 100644 index 0000000000..73e602855c --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/client/spring/ClientConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.client.spring; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan("org.baeldung.client") +public class ClientConfig { + + public ClientConfig() { + super(); + } + + // beans + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/filter/CustomFilter.java b/httpclient-simple/src/main/java/org/baeldung/filter/CustomFilter.java new file mode 100644 index 0000000000..01e5b0b59d --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/filter/CustomFilter.java @@ -0,0 +1,18 @@ +package org.baeldung.filter; + +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +public class CustomFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + chain.doFilter(request, response); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java b/httpclient-simple/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java new file mode 100644 index 0000000000..7ca2a80c52 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java @@ -0,0 +1,49 @@ +package org.baeldung.filter; + +import org.baeldung.security.RestAuthenticationEntryPoint; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +@Configuration +@EnableWebSecurity +public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + + @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user1") + .password(passwordEncoder().encode("user1Pass")) + .authorities("ROLE_USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/securityNone") + .permitAll() + .anyRequest() + .authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint); + + http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/httpclient-simple/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java b/httpclient-simple/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java new file mode 100644 index 0000000000..698052fa2b --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java @@ -0,0 +1,48 @@ +package org.baeldung.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.util.StringUtils; + +public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + private RequestCache requestCache = new HttpSessionRequestCache(); + + @Override + public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication) throws ServletException, IOException { + final SavedRequest savedRequest = requestCache.getRequest(request, response); + + if (savedRequest == null) { + super.onAuthenticationSuccess(request, response, authentication); + + return; + } + final String targetUrlParameter = getTargetUrlParameter(); + if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) { + requestCache.removeRequest(request, response); + super.onAuthenticationSuccess(request, response, authentication); + + return; + } + + clearAuthenticationAttributes(request); + + // Use the DefaultSavedRequest URL + // final String targetUrl = savedRequest.getRedirectUrl(); + // logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl); + // getRedirectStrategy().sendRedirect(request, response, targetUrl); + } + + public void setRequestCache(final RequestCache requestCache) { + this.requestCache = requestCache; + } +} diff --git a/httpclient-simple/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java b/httpclient-simple/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java new file mode 100644 index 0000000000..77aa32ff97 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java @@ -0,0 +1,23 @@ +package org.baeldung.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.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +/** + * The Entry Point will not redirect to any sort of Login - it will return the 401 + */ +@Component +public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + } + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/httpclient-simple/src/main/java/org/baeldung/spring/SecSecurityConfig.java new file mode 100644 index 0000000000..4ce80dab9f --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/spring/SecSecurityConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.spring; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +@Configuration +@ImportResource({ "classpath:webSecurityConfig.xml" }) +@ComponentScan("org.baeldung.security") +public class SecSecurityConfig { + + public SecSecurityConfig() { + super(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/spring/WebConfig.java b/httpclient-simple/src/main/java/org/baeldung/spring/WebConfig.java new file mode 100644 index 0000000000..5876e1307b --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/spring/WebConfig.java @@ -0,0 +1,30 @@ +package org.baeldung.spring; + +import java.util.List; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +@ComponentScan("org.baeldung.web") +public class WebConfig implements WebMvcConfigurer { + + public WebConfig() { + super(); + } + + // beans + + @Override + public void configureMessageConverters(final List> converters) { + converters.add(new MappingJackson2HttpMessageConverter()); + } + + // + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/web/controller/BarController.java b/httpclient-simple/src/main/java/org/baeldung/web/controller/BarController.java new file mode 100644 index 0000000000..2bc314baa2 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/controller/BarController.java @@ -0,0 +1,31 @@ +package org.baeldung.web.controller; + +import org.baeldung.web.dto.Bar; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/bars") +public class BarController { + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public BarController() { + super(); + } + + // API + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + public Bar findOne(@PathVariable("id") final Long id) { + return new Bar(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/web/controller/FooController.java b/httpclient-simple/src/main/java/org/baeldung/web/controller/FooController.java new file mode 100644 index 0000000000..b50edb2dcf --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/controller/FooController.java @@ -0,0 +1,33 @@ +package org.baeldung.web.controller; + +import org.baeldung.web.dto.Foo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/foos") +public class FooController { + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public FooController() { + super(); + } + + // API + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + @PreAuthorize("hasRole('ROLE_USER')") + public Foo findOne(@PathVariable("id") final Long id) { + return new Foo(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/web/dto/Bar.java b/httpclient-simple/src/main/java/org/baeldung/web/dto/Bar.java new file mode 100644 index 0000000000..d33e39a823 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/dto/Bar.java @@ -0,0 +1,14 @@ +package org.baeldung.web.dto; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Bar implements Serializable { + + public Bar() { + super(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/web/dto/Foo.java b/httpclient-simple/src/main/java/org/baeldung/web/dto/Foo.java new file mode 100644 index 0000000000..09c1dac933 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/dto/Foo.java @@ -0,0 +1,14 @@ +package org.baeldung.web.dto; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Foo implements Serializable { + + public Foo() { + super(); + } + +} diff --git a/httpclient-simple/src/main/resources/logback.xml b/httpclient-simple/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/httpclient-simple/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/resources/webSecurityConfig.xml b/httpclient-simple/src/main/resources/webSecurityConfig.xml new file mode 100644 index 0000000000..a93dc841b6 --- /dev/null +++ b/httpclient-simple/src/main/resources/webSecurityConfig.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/webapp/WEB-INF/api-servlet.xml b/httpclient-simple/src/main/webapp/WEB-INF/api-servlet.xml new file mode 100644 index 0000000000..1dbff70b83 --- /dev/null +++ b/httpclient-simple/src/main/webapp/WEB-INF/api-servlet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/webapp/WEB-INF/web.xml b/httpclient-simple/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..83b4aeb0a7 --- /dev/null +++ b/httpclient-simple/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,43 @@ + + + + Spring Security Custom Application + + + + contextClass + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + contextConfigLocation + org.baeldung.spring + + + + org.springframework.web.context.ContextLoaderListener + + + + + api + org.springframework.web.servlet.DispatcherServlet + 1 + + + api + /api/* + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + springSecurityFilterChain + /* + + + \ No newline at end of file diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/ClientLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/client/ClientLiveTest.java similarity index 88% rename from spring-security-rest-basic-auth/src/test/java/org/baeldung/client/ClientLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/client/ClientLiveTest.java index 2a668f827a..286ee3c900 100644 --- a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/ClientLiveTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/client/ClientLiveTest.java @@ -33,13 +33,13 @@ public class ClientLiveTest { @Test public final void whenSecuredRestApiIsConsumed_then200OK() { - final ResponseEntity responseEntity = secureRestTemplate.exchange("http://localhost:8082/spring-security-rest-basic-auth/api/foos/1", HttpMethod.GET, null, Foo.class); + final ResponseEntity responseEntity = secureRestTemplate.exchange("http://localhost:8082/httpclient-simple/api/foos/1", HttpMethod.GET, null, Foo.class); assertThat(responseEntity.getStatusCode().value(), is(200)); } @Test(expected = ResourceAccessException.class) public final void whenHttpsUrlIsConsumed_thenException() { - final String urlOverHttps = "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1"; + final String urlOverHttps = "https://localhost:8443/httpclient-simple/api/bars/1"; final ResponseEntity response = new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); } diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java b/httpclient-simple/src/test/java/org/baeldung/client/RestClientLiveManualTest.java similarity index 63% rename from spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java rename to httpclient-simple/src/test/java/org/baeldung/client/RestClientLiveManualTest.java index 104129b663..53f259c21d 100644 --- a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/client/RestClientLiveManualTest.java @@ -8,19 +8,24 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLContext; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; import org.junit.Ignore; import org.junit.Test; import org.springframework.http.HttpMethod; @@ -34,14 +39,14 @@ import org.springframework.web.client.RestTemplate; * */ public class RestClientLiveManualTest { - final String urlOverHttps = "http://localhost:8082/spring-security-rest-basic-auth/api/bars/1"; + final String urlOverHttps = "http://localhost:8082/httpclient-simple/api/bars/1"; // tests // old httpClient will throw UnsupportedOperationException @Ignore @Test - public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() throws GeneralSecurityException { + public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException_1() throws GeneralSecurityException { final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); final CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient(); @@ -57,6 +62,29 @@ public class RestClientLiveManualTest { final ResponseEntity response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); } + + // new httpClient : 4.4 and above + @Test + public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException_2() throws GeneralSecurityException { + + final TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; + final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + final Registry socketFactoryRegistry = RegistryBuilder. create() + .register("https", sslsf) + .register("http", new PlainConnectionSocketFactory()) + .build(); + + final BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(socketFactoryRegistry); + final CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(sslsf) + .setConnectionManager(connectionManager) + .build(); + + final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + final ResponseEntity response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class); + assertThat(response.getStatusCode().value(), equalTo(200)); + } @Test public final void givenAcceptingAllCertificatesUsing4_4_whenHttpsUrlIsConsumed_thenCorrect() throws ClientProtocolException, IOException { diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java similarity index 82% rename from httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java index 4eadfe24d5..9e95905c70 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java @@ -1,32 +1,31 @@ package org.baeldung.httpclient; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.ssl.SSLContexts; -import org.junit.Test; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; -import java.io.IOException; -import java.security.GeneralSecurityException; - import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; +import org.junit.Test; + /** * This test requires a localhost server over HTTPS
* It should only be manually run, not part of the automated build @@ -50,16 +49,22 @@ public class HttpsClientSslLiveTest { .getStatusCode(), equalTo(200)); } - @SuppressWarnings("deprecation") @Test public final void givenHttpClientPre4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException { final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; - final SSLSocketFactory sf = new SSLSocketFactory(acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - final SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("https", 443, sf)); - final ClientConnectionManager ccm = new PoolingClientConnectionManager(registry); + + final SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(null, acceptingTrustStrategy) + .build(); - final CloseableHttpClient httpClient = new DefaultHttpClient(ccm); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + Registry socketFactoryRegistry = RegistryBuilder. create().register("https", sslsf).build(); + PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + + final CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(sslsf) + .setConnectionManager(clientConnectionManager) + .build(); final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); final HttpResponse response = httpClient.execute(getMethod); @@ -76,10 +81,9 @@ public class HttpsClientSslLiveTest { .loadTrustMaterial(null, acceptingTrustStrategy) .build(); - final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); final CloseableHttpClient httpClient = HttpClients.custom() - .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) .setSSLSocketFactory(sslsf) .build(); diff --git a/httpclient-simple/src/test/java/org/baeldung/httpclient/ResponseUtil.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/ResponseUtil.java new file mode 100644 index 0000000000..fd38b95cbe --- /dev/null +++ b/httpclient-simple/src/test/java/org/baeldung/httpclient/ResponseUtil.java @@ -0,0 +1,26 @@ +package org.baeldung.httpclient; + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; + +import java.io.IOException; + +public final class ResponseUtil { + private ResponseUtil() { + } + + public static void closeResponse(CloseableHttpResponse response) throws IOException { + if (response == null) { + return; + } + + try { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + entity.getContent().close(); + } + } finally { + response.close(); + } + } +} diff --git a/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java similarity index 100% rename from httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java diff --git a/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java similarity index 96% rename from httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java index c9956e5852..96278b481a 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java @@ -23,19 +23,18 @@ import org.junit.Before; import org.junit.Test; import java.io.IOException; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; /* - * NOTE : Need module spring-security-rest-basic-auth to be running + * NOTE : Need module httpclient-simple to be running */ public class HttpClientAuthLiveTest { - private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8081/spring-security-rest-basic-auth/api/foos/1"; + private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8082/httpclient-simple/api/foos/1"; private static final String DEFAULT_USER = "user1"; private static final String DEFAULT_PASS = "user1Pass"; @@ -111,7 +110,7 @@ public class HttpClientAuthLiveTest { } private HttpContext context() { - final HttpHost targetHost = new HttpHost("localhost", 8080, "http"); + final HttpHost targetHost = new HttpHost("localhost", 8082, "http"); final CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS)); diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/test/LiveTestSuite.java b/httpclient-simple/src/test/java/org/baeldung/test/LiveTestSuite.java similarity index 100% rename from spring-security-rest-basic-auth/src/test/java/org/baeldung/test/LiveTestSuite.java rename to httpclient-simple/src/test/java/org/baeldung/test/LiveTestSuite.java diff --git a/httpclient-simple/src/test/resources/.gitignore b/httpclient-simple/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/httpclient-simple/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/httpclient/README.md b/httpclient/README.md index 87fb38706d..cab538be85 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -8,13 +8,11 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [HttpClient 4 – Send Custom Cookie](http://www.baeldung.com/httpclient-4-cookies) -- [HttpClient 4 – Get the Status Code](http://www.baeldung.com/httpclient-status-code) -- [HttpClient 4 – Cancel / Abort Request](http://www.baeldung.com/httpclient-cancel-request) +- [HttpClient 4 – Cancel Request](http://www.baeldung.com/httpclient-cancel-request) - [HttpClient 4 Cookbook](http://www.baeldung.com/httpclient4) - [Unshorten URLs with HttpClient](http://www.baeldung.com/unshorten-url-httpclient) - [HttpClient 4 – Follow Redirects for POST](http://www.baeldung.com/httpclient-redirect-on-http-post) - [Custom HTTP Header with the HttpClient](http://www.baeldung.com/httpclient-custom-http-header) -- [HttpClient Basic Authentication](http://www.baeldung.com/httpclient-4-basic-authentication) - [Multipart Upload with HttpClient 4](http://www.baeldung.com/httpclient-multipart-upload) - [HttpAsyncClient Tutorial](http://www.baeldung.com/httpasyncclient-tutorial) - [HttpClient 4 Tutorial](http://www.baeldung.com/httpclient-guide) diff --git a/httpclient/pom.xml b/httpclient/pom.xml index c9f9808ede..def3a05816 100644 --- a/httpclient/pom.xml +++ b/httpclient/pom.xml @@ -122,11 +122,10 @@ 19.0 3.5 1.10 - 4.1.2 + 4.1.4 2.5.1 - 4.4.5 - 4.5.3 + 4.5.8 1.6.1 diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java index d39697c0a9..47a587885e 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -4,7 +4,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import java.io.IOException; -import java.security.cert.X509Certificate; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -18,8 +17,7 @@ import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; +import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.BasicCredentialsProvider; @@ -31,6 +29,7 @@ import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; +import org.apache.http.ssl.SSLContexts; import org.junit.Test; public class HttpAsyncClientLiveTest { @@ -104,7 +103,7 @@ public class HttpAsyncClientLiveTest { final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); - final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).setSSLContext(sslContext).build(); + final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build(); client.start(); final HttpGet request = new HttpGet(HOST_WITH_SSL); diff --git a/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java index 0f8ebefe6c..cf945098db 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java @@ -327,7 +327,8 @@ public class HttpClientConnectionManagementLiveTest { // 8.1 public final void whenHttpClientChecksStaleConns_thenNoExceptions() { poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build()).setConnectionManager(poolingConnManager).build(); + poolingConnManager.setValidateAfterInactivity(1000); + client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().build()).setConnectionManager(poolingConnManager).build(); } @Test diff --git a/jackson-2/pom.xml b/jackson-2/pom.xml index ddbcb81dcc..6b973dd6f5 100644 --- a/jackson-2/pom.xml +++ b/jackson-2/pom.xml @@ -22,6 +22,20 @@ ${jackson.version} + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.9.8 + + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.9.8 + + diff --git a/jackson-2/src/main/java/com/baeldung/jackson/entities/Order.java b/jackson-2/src/main/java/com/baeldung/jackson/entities/Order.java new file mode 100644 index 0000000000..2075b7879b --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/entities/Order.java @@ -0,0 +1,68 @@ +package com.baeldung.jackson.entities; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +public class Order { + private String orderNo; + private LocalDate date; + private String customerName; + private List orderLines; + + public Order() { + + } + + public Order(String orderNo, LocalDate date, String customerName, List orderLines) { + super(); + this.orderNo = orderNo; + this.date = date; + this.customerName = customerName; + this.orderLines = orderLines; + } + + public String getOrderNo() { + return orderNo; + } + + public void setOrderNo(String orderNo) { + this.orderNo = orderNo; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public List getOrderLines() { + if (orderLines == null) { + orderLines = new ArrayList<>(); + } + return orderLines; + } + + public void setOrderLines(List orderLines) { + if (orderLines == null) { + orderLines = new ArrayList<>(); + } + this.orderLines = orderLines; + } + + @Override + public String toString() { + return "Order [orderNo=" + orderNo + ", date=" + date + ", customerName=" + customerName + ", orderLines=" + orderLines + "]"; + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/entities/OrderLine.java b/jackson-2/src/main/java/com/baeldung/jackson/entities/OrderLine.java new file mode 100644 index 0000000000..858d094dd1 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/entities/OrderLine.java @@ -0,0 +1,49 @@ +package com.baeldung.jackson.entities; + +import java.math.BigDecimal; + +public class OrderLine { + private String item; + private int quantity; + private BigDecimal unitPrice; + + public OrderLine() { + + } + + public OrderLine(String item, int quantity, BigDecimal unitPrice) { + super(); + this.item = item; + this.quantity = quantity; + this.unitPrice = unitPrice; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public BigDecimal getUnitPrice() { + return unitPrice; + } + + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } + + @Override + public String toString() { + return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]"; + } +} diff --git a/jackson-2/src/main/resources/orderInput.yaml b/jackson-2/src/main/resources/orderInput.yaml new file mode 100644 index 0000000000..0aaa6186a2 --- /dev/null +++ b/jackson-2/src/main/resources/orderInput.yaml @@ -0,0 +1,11 @@ +orderNo: A001 +date: 2019-04-17 +customerName: Customer, Joe +orderLines: + - item: No. 9 Sprockets + quantity: 12 + unitPrice: 1.23 + - item: Widget (10mm) + quantity: 4 + unitPrice: 3.45 + \ No newline at end of file diff --git a/jackson-2/src/test/java/com/baeldung/jackson/yaml/YamlUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/yaml/YamlUnitTest.java new file mode 100644 index 0000000000..3ed84db60e --- /dev/null +++ b/jackson-2/src/test/java/com/baeldung/jackson/yaml/YamlUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.jackson.yaml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.jackson.entities.Order; +import com.baeldung.jackson.entities.OrderLine; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; + +public class YamlUnitTest { + private ObjectMapper mapper; + + @Before + public void setup() { + mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER)); + mapper.findAndRegisterModules(); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + } + + @Test + public void givenYamlInput_ObjectCreated() throws JsonParseException, JsonMappingException, IOException { + Order order = mapper.readValue(new File("src/main/resources/orderInput.yaml"), Order.class); + assertEquals("A001", order.getOrderNo()); + assertEquals(LocalDate.parse("2019-04-17", DateTimeFormatter.ISO_DATE), order.getDate()); + assertEquals("Customer, Joe", order.getCustomerName()); + assertEquals(2, order.getOrderLines() + .size()); + } + + @Test + public void givenYamlObject_FileWritten() throws JsonGenerationException, JsonMappingException, IOException { + List lines = new ArrayList<>(); + lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP))); + lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP))); + Order order = new Order( + "B-9910", + LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE), + "Customer, Jane", + lines); + mapper.writeValue(new File("src/main/resources/orderOutput.yaml"), order); + + File outputYaml = new File("src/main/resources/orderOutput.yaml"); + assertTrue(outputYaml.exists()); + } +} diff --git a/jackson-simple/.gitignore b/jackson-simple/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/jackson-simple/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/jackson-simple/README.md b/jackson-simple/README.md new file mode 100644 index 0000000000..be647e22d5 --- /dev/null +++ b/jackson-simple/README.md @@ -0,0 +1,13 @@ +========= +### Jackson Articles that are also part of the e-book + +###The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: +- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization) +- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties) +- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations) +- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial) +- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields) +- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property) diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml new file mode 100644 index 0000000000..5023ad87b6 --- /dev/null +++ b/jackson-simple/pom.xml @@ -0,0 +1,131 @@ + + 4.0.0 + jackson-simple + 0.1-SNAPSHOT + jackson-simple + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + commons-io + commons-io + ${commons-io.version} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson.version} + + + + com.fasterxml.jackson.module + jackson-module-jsonSchema + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + ${jackson.version} + + + + joda-time + joda-time + ${joda-time.version} + + + + com.google.code.gson + gson + ${gson.version} + + + + + + io.rest-assured + json-schema-validator + ${rest-assured.version} + test + + + + io.rest-assured + json-path + ${rest-assured.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + jackson-simple + + + src/main/resources + true + + + + + + + 3.8 + 2.10 + 2.8.5 + 4.2 + + + 3.1.1 + 3.11.0 + + + diff --git a/jackson-simple/src/main/resources/logback.xml b/jackson-simple/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/jackson-simple/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/AliasBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/AliasBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/AliasBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/AliasBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/MyBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/MyBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/RawBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/RawBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/RawBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/RawBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/Zoo.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/Zoo.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/Zoo.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/Zoo.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java new file mode 100644 index 0000000000..25de4a8f7a --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java @@ -0,0 +1,21 @@ +package com.baeldung.jackson.bidirection; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class ItemWithIdentity { + public int id; + public String itemName; + public UserWithIdentity owner; + + public ItemWithIdentity() { + super(); + } + + public ItemWithIdentity(final int id, final String itemName, final UserWithIdentity owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java new file mode 100644 index 0000000000..910ccec174 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java @@ -0,0 +1,17 @@ +package com.baeldung.jackson.bidirection; + +public class ItemWithIgnore { + public int id; + public String itemName; + public UserWithIgnore owner; + + public ItemWithIgnore() { + super(); + } + + public ItemWithIgnore(final int id, final String itemName, final UserWithIgnore owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java new file mode 100644 index 0000000000..0ca8d721e8 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java @@ -0,0 +1,21 @@ +package com.baeldung.jackson.bidirection; + +import com.fasterxml.jackson.annotation.JsonManagedReference; + +public class ItemWithRef { + public int id; + public String itemName; + + @JsonManagedReference + public UserWithRef owner; + + public ItemWithRef() { + super(); + } + + public ItemWithRef(final int id, final String itemName, final UserWithRef owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java new file mode 100644 index 0000000000..db83a09389 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java @@ -0,0 +1,28 @@ +package com.baeldung.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class UserWithIdentity { + public int id; + public String name; + public List userItems; + + public UserWithIdentity() { + super(); + } + + public UserWithIdentity(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithIdentity item) { + userItems.add(item); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java new file mode 100644 index 0000000000..857a373cc5 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java @@ -0,0 +1,28 @@ +package com.baeldung.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class UserWithIgnore { + public int id; + public String name; + + @JsonIgnore + public List userItems; + + public UserWithIgnore() { + super(); + } + + public UserWithIgnore(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithIgnore item) { + userItems.add(item); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java new file mode 100644 index 0000000000..3de03fc651 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java @@ -0,0 +1,28 @@ +package com.baeldung.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonBackReference; + +public class UserWithRef { + public int id; + public String name; + + @JsonBackReference + public List userItems; + + public UserWithRef() { + super(); + } + + public UserWithRef(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithRef item) { + userItems.add(item); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java new file mode 100644 index 0000000000..90c7d9fbac --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.date; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class CustomDateDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -5451717385630622729L; + private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + public CustomDateDeserializer() { + this(null); + } + + public CustomDateDeserializer(final Class vc) { + super(vc); + } + + @Override + public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException { + final String date = jsonparser.getText(); + try { + return formatter.parse(date); + } catch (final ParseException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java new file mode 100644 index 0000000000..d840e1940f --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.date; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class CustomDateSerializer extends StdSerializer { + + private static final long serialVersionUID = -2894356342227378312L; + private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + public CustomDateSerializer() { + this(null); + } + + public CustomDateSerializer(final Class t) { + super(t); + } + + @Override + public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException { + gen.writeString(formatter.format(value)); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java new file mode 100644 index 0000000000..607e694cef --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.date; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; + +public class EventWithFormat { + public String name; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss") + public Date eventDate; + + public EventWithFormat() { + super(); + } + + public EventWithFormat(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java new file mode 100644 index 0000000000..c359b5c846 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java @@ -0,0 +1,31 @@ +package com.baeldung.jackson.date; + +import java.util.Date; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class EventWithSerializer { + public String name; + + @JsonDeserialize(using = CustomDateDeserializer.class) + @JsonSerialize(using = CustomDateSerializer.class) + public Date eventDate; + + public EventWithSerializer() { + super(); + } + + public EventWithSerializer(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java b/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java new file mode 100644 index 0000000000..eaba9a7173 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java @@ -0,0 +1,41 @@ +package com.baeldung.jackson.deserialization; + +import java.io.IOException; + +import com.baeldung.jackson.dtos.ItemWithSerializer; +import com.baeldung.jackson.dtos.User; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.IntNode; + +public class ItemDeserializerOnClass extends StdDeserializer { + + private static final long serialVersionUID = 5579141241817332594L; + + public ItemDeserializerOnClass() { + this(null); + } + + public ItemDeserializerOnClass(final Class vc) { + super(vc); + } + + /** + * {"id":1,"itemNr":"theItem","owner":2} + */ + @Override + public ItemWithSerializer deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { + final JsonNode node = jp.getCodec() + .readTree(jp); + final int id = (Integer) ((IntNode) node.get("id")).numberValue(); + final String itemName = node.get("itemName") + .asText(); + final int userId = (Integer) ((IntNode) node.get("owner")).numberValue(); + + return new ItemWithSerializer(id, itemName, new User(userId, null)); + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java new file mode 100644 index 0000000000..6fce2bc88e --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java @@ -0,0 +1,32 @@ +package com.baeldung.jackson.dtos; + +public class Item { + public int id; + public String itemName; + public User owner; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java new file mode 100644 index 0000000000..aea9aa770d --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.dtos; + +import com.baeldung.jackson.deserialization.ItemDeserializerOnClass; +import com.baeldung.jackson.serialization.ItemSerializerOnClass; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize(using = ItemSerializerOnClass.class) +@JsonDeserialize(using = ItemDeserializerOnClass.class) +public class ItemWithSerializer { + public final int id; + public final String itemName; + public final User owner; + + public ItemWithSerializer(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java new file mode 100644 index 0000000000..49cf07baea --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java @@ -0,0 +1,54 @@ +package com.baeldung.jackson.dtos; + +public class MyDto { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDto() { + super(); + } + + public MyDto(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + // + + @Override + public String toString() { + return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]"; + } + +} diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java new file mode 100644 index 0000000000..2418e8070d --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.dtos; + +public class User { + public int id; + public String name; + + public User() { + super(); + } + + public User(final int id, final String name) { + this.id = id; + this.name = name; + } + + // API + + public int getId() { + return id; + } + + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java new file mode 100644 index 0000000000..69c476d8a5 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.dtos.withEnum; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum DistanceEnumWithValue { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumWithValue(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + @JsonValue + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java new file mode 100644 index 0000000000..d879c16e6a --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java @@ -0,0 +1,18 @@ +package com.baeldung.jackson.exception; + +import com.fasterxml.jackson.annotation.JsonRootName; + +@JsonRootName(value = "user") +public class UserWithRoot { + public int id; + public String name; + + public UserWithRoot() { + super(); + } + + public UserWithRoot(final int id, final String name) { + this.id = id; + this.name = name; + } +} diff --git a/jackson/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java rename to jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java new file mode 100644 index 0000000000..26d20d4847 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.jsonview; + +import com.fasterxml.jackson.annotation.JsonView; + +public class Item { + @JsonView(Views.Public.class) + public int id; + + @JsonView(Views.Public.class) + public String itemName; + + @JsonView(Views.Internal.class) + public String ownerName; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final String ownerName) { + this.id = id; + this.itemName = itemName; + this.ownerName = ownerName; + } + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public String getOwnerName() { + return ownerName; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java new file mode 100644 index 0000000000..65950b7f9f --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java @@ -0,0 +1,9 @@ +package com.baeldung.jackson.jsonview; + +public class Views { + public static class Public { + } + + public static class Internal extends Public { + } +} diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java new file mode 100644 index 0000000000..1fdf44e17c --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java @@ -0,0 +1,32 @@ +package com.baeldung.jackson.serialization; + +import java.io.IOException; + +import com.baeldung.jackson.dtos.ItemWithSerializer; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class ItemSerializerOnClass extends StdSerializer { + + private static final long serialVersionUID = -1760959597313610409L; + + public ItemSerializerOnClass() { + this(null); + } + + public ItemSerializerOnClass(final Class t) { + super(t); + } + + @Override + public final void serialize(final ItemWithSerializer value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeNumberField("id", value.id); + jgen.writeStringField("itemName", value.itemName); + jgen.writeNumberField("owner", value.owner.id); + jgen.writeEndObject(); + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java diff --git a/jackson-simple/src/test/resources/.gitignore b/jackson-simple/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/jackson-simple/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/jackson/README.md b/jackson/README.md index e9cf6f212c..794ddc04d9 100644 --- a/jackson/README.md +++ b/jackson/README.md @@ -6,9 +6,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization) - [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array) -- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties) - [Jackson – Custom Serializer](http://www.baeldung.com/jackson-custom-serialization) - [Getting Started with Custom Deserialization in Jackson](http://www.baeldung.com/jackson-deserialization) - [Jackson Exceptions – Problems and Solutions](http://www.baeldung.com/jackson-exception) @@ -16,11 +14,9 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Jackson – Bidirectional Relationships](http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion) - [Jackson JSON Tutorial](http://www.baeldung.com/jackson) - [Jackson – Working with Maps and nulls](http://www.baeldung.com/jackson-map-null-values-or-null-key) -- [Jackson – Decide What Fields Get Serialized/Deserializaed](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not) -- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations) +- [Jackson – Decide What Fields Get Serialized/Deserialized](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not) - [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model) - [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson) -- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial) - [XML Serialization and Deserialization with Jackson](http://www.baeldung.com/jackson-xml-serialization-and-deserialization) - [More Jackson Annotations](http://www.baeldung.com/jackson-advanced-annotations) - [Inheritance with Jackson](http://www.baeldung.com/jackson-inheritance) @@ -31,9 +27,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Jackson – JsonMappingException (No serializer found for class)](http://www.baeldung.com/jackson-jsonmappingexception) - [How To Serialize Enums as JSON Objects with Jackson](http://www.baeldung.com/jackson-serialize-enums) - [Jackson – Marshall String to JsonNode](http://www.baeldung.com/jackson-json-to-jsonnode) -- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields) - [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array) -- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property) - [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria) - [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values) - [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json) diff --git a/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java b/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java index 6be2f29baa..e783c67f5b 100644 --- a/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java +++ b/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java @@ -12,8 +12,6 @@ import org.junit.runners.Suite; ,JacksonDeserializationUnitTest.class ,JacksonDeserializationUnitTest.class ,JacksonPrettyPrintUnitTest.class - ,JacksonSerializationIgnoreUnitTest.class - ,JacksonSerializationUnitTest.class ,SandboxUnitTest.class ,JacksonFieldUnitTest.class }) // @formatter:on diff --git a/java-collections-maps-2/README.md b/java-collections-maps-2/README.md new file mode 100644 index 0000000000..8bcafccfe8 --- /dev/null +++ b/java-collections-maps-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles: +- [Map of Primitives in Java](https://www.baeldung.com/java-map-primitives) diff --git a/java-dates-2/README.md b/java-dates-2/README.md new file mode 100644 index 0000000000..a6b5c8e574 --- /dev/null +++ b/java-dates-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles: +- [Converting Between LocalDate and XMLGregorianCalendar](https://www.baeldung.com/java-localdate-to-xmlgregoriancalendar) diff --git a/java-math/.gitignore b/java-math/.gitignore new file mode 100644 index 0000000000..30b2b7442c --- /dev/null +++ b/java-math/.gitignore @@ -0,0 +1,4 @@ +/target/ +.settings/ +.classpath +.project \ No newline at end of file diff --git a/java-math/README.md b/java-math/README.md new file mode 100644 index 0000000000..d821348204 --- /dev/null +++ b/java-math/README.md @@ -0,0 +1,10 @@ +## Relevant articles: + +- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial) +- [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm) +- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap) +- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points) +- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines) +- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred) +- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage) +- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude) \ No newline at end of file diff --git a/java-math/pom.xml b/java-math/pom.xml new file mode 100644 index 0000000000..159d053df3 --- /dev/null +++ b/java-math/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + java-math + 0.0.1-SNAPSHOT + java-math + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + com.google.guava + guava + ${guava.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + org.assertj + assertj-core + ${org.assertj.core.version} + test + + + com.github.dpaukov + combinatoricslib3 + 3.3.0 + + + + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + + + + + 3.6.1 + 3.9.0 + 1.11 + 27.0.1-jre + + + \ No newline at end of file diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java b/java-math/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java rename to java-math/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java b/java-math/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java rename to java-math/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java b/java-math/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java rename to java-math/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java b/java-math/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java rename to java-math/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java b/java-math/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java rename to java-math/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java b/java-math/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java rename to java-math/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java b/java-math/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java rename to java-math/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/factorial/Factorial.java b/java-math/src/main/java/com/baeldung/algorithms/factorial/Factorial.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/factorial/Factorial.java rename to java-math/src/main/java/com/baeldung/algorithms/factorial/Factorial.java diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java b/java-math/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java similarity index 100% rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java rename to java-math/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java b/java-math/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java rename to java-math/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/mercator/Mercator.java b/java-math/src/main/java/com/baeldung/algorithms/mercator/Mercator.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/mercator/Mercator.java rename to java-math/src/main/java/com/baeldung/algorithms/mercator/Mercator.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java b/java-math/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java rename to java-math/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java diff --git a/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java b/java-math/src/main/java/com/baeldung/algorithms/percentage/PercentageCalculator.java similarity index 93% rename from java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java rename to java-math/src/main/java/com/baeldung/algorithms/percentage/PercentageCalculator.java index e74de2cc67..f69b23146e 100644 --- a/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java +++ b/java-math/src/main/java/com/baeldung/algorithms/percentage/PercentageCalculator.java @@ -1,4 +1,4 @@ -package com.baeldung.percentage; +package com.baeldung.algorithms.percentage; import java.util.Scanner; diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java b/java-math/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java rename to java-math/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java b/java-math/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java rename to java-math/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java diff --git a/algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java b/java-math/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java similarity index 100% rename from algorithms-miscellaneous-2/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java rename to java-math/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/resources/logback.xml b/java-math/src/main/resources/logback.xml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/resources/logback.xml rename to java-math/src/main/resources/logback.xml diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java similarity index 93% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java index 785afdbb2b..784681a807 100644 --- a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java +++ b/java-math/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java @@ -2,8 +2,6 @@ package com.baeldung.algorithms.distancebetweenpoints; import org.junit.Test; -import com.baeldung.algorithms.distancebetweenpoints.DistanceBetweenPointsService; - import static org.junit.Assert.assertEquals; public class DistanceBetweenPointsServiceUnitTest { diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java similarity index 100% rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java diff --git a/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/percentage/PercentageCalculatorUnitTest.java similarity index 95% rename from java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/percentage/PercentageCalculatorUnitTest.java index 202d4f8112..e49acc0c4b 100644 --- a/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java +++ b/java-math/src/test/java/com/baeldung/algorithms/percentage/PercentageCalculatorUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.percentage; +package com.baeldung.algorithms.percentage; import org.junit.Assert; import org.junit.Test; diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java similarity index 93% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java index 6707b34477..e4bb614b48 100644 --- a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java +++ b/java-math/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java @@ -4,9 +4,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; import org.junit.Test; -import com.baeldung.algorithms.rectanglesoverlap.Point; -import com.baeldung.algorithms.rectanglesoverlap.Rectangle; - public class RectangleUnitTest { @Test diff --git a/algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java b/java-math/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java similarity index 100% rename from algorithms-miscellaneous-2/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java rename to java-math/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java diff --git a/java-streams/README.md b/java-streams/README.md index e294e5aee1..0c9588c47e 100644 --- a/java-streams/README.md +++ b/java-streams/README.md @@ -8,7 +8,7 @@ - [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams) - [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany) - [How to Get the Last Element of a Stream in Java?](http://www.baeldung.com/java-stream-last-element) -- [”Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception) +- [“Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception) - [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream) - [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices) - [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams) diff --git a/kotlin-libraries/README.md b/kotlin-libraries/README.md index 5e2526e64e..94359193b6 100644 --- a/kotlin-libraries/README.md +++ b/kotlin-libraries/README.md @@ -10,3 +10,5 @@ - [Introduction to Arrow in Kotlin](https://www.baeldung.com/kotlin-arrow) - [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor) - [REST API With Kotlin and Kovert](https://www.baeldung.com/kotlin-kovert) +- [MockK: A Mocking Library for Kotlin](https://www.baeldung.com/kotlin-mockk) +- [Kotlin Immutable Collections](https://www.baeldung.com/kotlin-immutable-collections) \ No newline at end of file diff --git a/libraries2/pom.xml b/libraries-2/pom.xml similarity index 100% rename from libraries2/pom.xml rename to libraries-2/pom.xml diff --git a/libraries2/src/main/java/com/baeldung/jbpm/WorkflowProcessMain.java b/libraries-2/src/main/java/com/baeldung/jbpm/WorkflowProcessMain.java similarity index 100% rename from libraries2/src/main/java/com/baeldung/jbpm/WorkflowProcessMain.java rename to libraries-2/src/main/java/com/baeldung/jbpm/WorkflowProcessMain.java diff --git a/libraries2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngine.java b/libraries-2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngine.java similarity index 100% rename from libraries2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngine.java rename to libraries-2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngine.java diff --git a/libraries2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngineImpl.java b/libraries-2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngineImpl.java similarity index 100% rename from libraries2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngineImpl.java rename to libraries-2/src/main/java/com/baeldung/jbpm/engine/WorkflowEngineImpl.java diff --git a/libraries2/src/main/resources/META-INF/kmodule.xml b/libraries-2/src/main/resources/META-INF/kmodule.xml similarity index 100% rename from libraries2/src/main/resources/META-INF/kmodule.xml rename to libraries-2/src/main/resources/META-INF/kmodule.xml diff --git a/libraries2/src/main/resources/com/baeldung/process/helloworld.bpmn b/libraries-2/src/main/resources/com/baeldung/process/helloworld.bpmn similarity index 100% rename from libraries2/src/main/resources/com/baeldung/process/helloworld.bpmn rename to libraries-2/src/main/resources/com/baeldung/process/helloworld.bpmn diff --git a/libraries2/src/test/java/com/baeldung/jbpm/WorkflowEngineIntegrationTest.java b/libraries-2/src/test/java/com/baeldung/jbpm/WorkflowEngineIntegrationTest.java similarity index 100% rename from libraries2/src/test/java/com/baeldung/jbpm/WorkflowEngineIntegrationTest.java rename to libraries-2/src/test/java/com/baeldung/jbpm/WorkflowEngineIntegrationTest.java diff --git a/libraries-apache-commons/src/main/java/com/baeldung/commons/beanutils/CourseService.java b/libraries-apache-commons/src/main/java/com/baeldung/commons/beanutils/CourseService.java index 538fa3accb..2c7644fd64 100644 --- a/libraries-apache-commons/src/main/java/com/baeldung/commons/beanutils/CourseService.java +++ b/libraries-apache-commons/src/main/java/com/baeldung/commons/beanutils/CourseService.java @@ -29,6 +29,6 @@ public class CourseService { } public static void copyProperties(Course course, CourseEntity courseEntity) throws IllegalAccessException, InvocationTargetException { - BeanUtils.copyProperties(course, courseEntity); + BeanUtils.copyProperties(courseEntity, course); } } diff --git a/libraries-apache-commons/src/test/java/com/baeldung/commons/beanutils/CourseServiceUnitTest.java b/libraries-apache-commons/src/test/java/com/baeldung/commons/beanutils/CourseServiceUnitTest.java index 833d91b2c4..224ee8404c 100644 --- a/libraries-apache-commons/src/test/java/com/baeldung/commons/beanutils/CourseServiceUnitTest.java +++ b/libraries-apache-commons/src/test/java/com/baeldung/commons/beanutils/CourseServiceUnitTest.java @@ -44,6 +44,8 @@ public class CourseServiceUnitTest { CourseEntity courseEntity = new CourseEntity(); CourseService.copyProperties(course, courseEntity); + Assert.assertNotNull(course.getName()); + Assert.assertNotNull(courseEntity.getName()); Assert.assertEquals(course.getName(), courseEntity.getName()); Assert.assertEquals(course.getCodes(), courseEntity.getCodes()); Assert.assertNull(courseEntity.getStudent("ST-1")); diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 9f125361ba..17d57fe203 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -32,6 +32,12 @@ ${scribejava.version} + + com.google.crypto.tink + tink + ${tink.version} + + junit junit @@ -55,6 +61,7 @@ 5.6.0 2.3.3.RELEASE 1.3.1 + 1.2.2 1.2.2 diff --git a/libraries-security/src/test/java/com/baeldung/tink/TinkUnitTest.java b/libraries-security/src/test/java/com/baeldung/tink/TinkUnitTest.java new file mode 100644 index 0000000000..b98c698016 --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/tink/TinkUnitTest.java @@ -0,0 +1,101 @@ +package com.baeldung.tink; + +import com.google.crypto.tink.*; +import com.google.crypto.tink.aead.AeadConfig; +import com.google.crypto.tink.aead.AeadFactory; +import com.google.crypto.tink.aead.AeadKeyTemplates; +import com.google.crypto.tink.config.TinkConfig; +import com.google.crypto.tink.hybrid.HybridDecryptFactory; +import com.google.crypto.tink.hybrid.HybridEncryptFactory; +import com.google.crypto.tink.hybrid.HybridKeyTemplates; +import com.google.crypto.tink.mac.MacFactory; +import com.google.crypto.tink.mac.MacKeyTemplates; +import com.google.crypto.tink.signature.PublicKeySignFactory; +import com.google.crypto.tink.signature.PublicKeyVerifyFactory; +import com.google.crypto.tink.signature.SignatureKeyTemplates; +import org.junit.Assert; +import org.junit.Test; + +import java.security.GeneralSecurityException; + +public class TinkUnitTest { + + private static final String PLAINTEXT = "BAELDUNG"; + private static final String DATA = "TINK"; + + @Test + public void givenPlaintext_whenEncryptWithAead_thenPlaintextIsEncrypted() throws GeneralSecurityException { + + AeadConfig.register(); + + KeysetHandle keysetHandle = KeysetHandle.generateNew( + AeadKeyTemplates.AES256_GCM); + + Aead aead = AeadFactory.getPrimitive(keysetHandle); + + byte[] ciphertext = aead.encrypt(PLAINTEXT.getBytes(), + DATA.getBytes()); + + Assert.assertNotEquals(PLAINTEXT, new String(ciphertext)); + } + + @Test + public void givenData_whenComputeMAC_thenVerifyMAC() throws GeneralSecurityException { + + TinkConfig.register(); + + KeysetHandle keysetHandle = KeysetHandle.generateNew( + MacKeyTemplates.HMAC_SHA256_128BITTAG); + + Mac mac = MacFactory.getPrimitive(keysetHandle); + + byte[] tag = mac.computeMac(DATA.getBytes()); + + mac.verifyMac(tag, DATA.getBytes()); + } + + @Test + public void givenData_whenSignData_thenVerifySignature() throws GeneralSecurityException { + + TinkConfig.register(); + + KeysetHandle privateKeysetHandle = KeysetHandle.generateNew( + SignatureKeyTemplates.ECDSA_P256); + + PublicKeySign signer = PublicKeySignFactory.getPrimitive(privateKeysetHandle); + + byte[] signature = signer.sign(DATA.getBytes()); + + KeysetHandle publicKeysetHandle = + privateKeysetHandle.getPublicKeysetHandle(); + + PublicKeyVerify verifier = PublicKeyVerifyFactory.getPrimitive(publicKeysetHandle); + + verifier.verify(signature, DATA.getBytes()); + } + + @Test + public void givenPlaintext_whenEncryptWithHybridEncryption_thenVerifyDecryptedIsEqual() throws GeneralSecurityException { + + TinkConfig.register(); + + KeysetHandle privateKeysetHandle = KeysetHandle.generateNew( + HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256); + + KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle(); + + HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle); + + HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(privateKeysetHandle); + + String contextInfo = "Tink"; + + byte[] ciphertext = hybridEncrypt.encrypt(PLAINTEXT.getBytes(), contextInfo.getBytes()); + + byte[] plaintextDecrypted = hybridDecrypt.decrypt(ciphertext, contextInfo.getBytes()); + + Assert.assertEquals(PLAINTEXT,new String(plaintextDecrypted)); + } +} + + diff --git a/libraries-server/README.md b/libraries-server/README.md index 75c12fd61a..dc6bcd0716 100644 --- a/libraries-server/README.md +++ b/libraries-server/README.md @@ -3,7 +3,7 @@ - [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) - [Introduction to Netty](http://www.baeldung.com/netty) - [Exceptions in Netty](http://www.baeldung.com/netty-exception-handling) -- [Programatically Create, Configure, and Run a Tomcat Server](http://www.baeldung.com/tomcat-programmatic-setup) +- [Programmatically Create, Configure and Run a Tomcat Server](http://www.baeldung.com/tomcat-programmatic-setup) - [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic) - [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) - [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client) diff --git a/libraries/README.md b/libraries/README.md index 57f22631f1..f6a39daef1 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -6,7 +6,7 @@ - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert) - [Intro to JaVers](http://www.baeldung.com/javers) -- [Intro to Serenity BDD](http://www.baeldung.com/serenity-bdd) +- [Introduction to Serenity BDD](http://www.baeldung.com/serenity-bdd) - [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) - [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay) - [Introduction to Quartz](http://www.baeldung.com/quartz) @@ -14,14 +14,14 @@ - [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm) - [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave) - [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing) -- [Introduction to Awaitility](http://www.baeldung.com/awaitlity-testing) +- [Introduction to Awaitlity](http://www.baeldung.com/awaitlity-testing) - [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog) - [Introduction to Neuroph](http://www.baeldung.com/neuroph) - [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss) - [Introduction to PCollections](http://www.baeldung.com/java-pcollections) - [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly) - [Introduction to Eclipse Collections](http://www.baeldung.com/eclipse-collections) -- [DistinctBy in Java Stream API](http://www.baeldung.com/java-streams-distinct-by) +- [DistinctBy in the Java Stream API](http://www.baeldung.com/java-streams-distinct-by) - [Introduction to NoException](http://www.baeldung.com/no-exception) - [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) - [Introduction to javax.measure](http://www.baeldung.com/javax-measure) @@ -36,7 +36,7 @@ - [Introduction To Docx4J](http://www.baeldung.com/docx4j) - [Introduction to StreamEx](http://www.baeldung.com/streamex) - [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) -- [Guide to google-http-client](http://www.baeldung.com/google-http-client) +- [A Guide to Google-Http-Client](http://www.baeldung.com/google-http-client) - [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) - [A Docker Guide for Java](http://www.baeldung.com/docker-java-api) - [Introduction To OpenCSV](http://www.baeldung.com/opencsv) diff --git a/logging-modules/README.md b/logging-modules/README.md index 0f12d7eb22..17405847b1 100644 --- a/logging-modules/README.md +++ b/logging-modules/README.md @@ -4,5 +4,4 @@ ### Relevant Articles: - [Creating a Custom Logback Appender](http://www.baeldung.com/custom-logback-appender) -- [Get Log Output in JSON Format](http://www.baeldung.com/java-log-json-output) - [A Guide To Logback](http://www.baeldung.com/logback) diff --git a/logging-modules/log4j2/README.md b/logging-modules/log4j2/README.md index 2cf6f9768f..dd326bc7a1 100644 --- a/logging-modules/log4j2/README.md +++ b/logging-modules/log4j2/README.md @@ -4,3 +4,4 @@ - [Log4j 2 and Lambda Expressions](http://www.baeldung.com/log4j-2-lazy-logging) - [Programmatic Configuration with Log4j 2](http://www.baeldung.com/log4j2-programmatic-config) - [Creating a Custom Log4j2 Appender](https://www.baeldung.com/log4j2-custom-appender) +- [Get Log Output in JSON](http://www.baeldung.com/java-log-json-output) diff --git a/logging-modules/logback/README.md b/logging-modules/logback/README.md index e69de29bb2..df55492b69 100644 --- a/logging-modules/logback/README.md +++ b/logging-modules/logback/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Get Log Output in JSON](https://www.baeldung.com/java-log-json-output) diff --git a/maven-java-11/multimodule-maven-project/daomodule/pom.xml b/maven-java-11/multimodule-maven-project/daomodule/pom.xml new file mode 100644 index 0000000000..de9be656d4 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/daomodule/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + com.baeldung.multimodule-maven-project + multimodule-maven-project + 1.0 + + com.baeldung.daomodule + daomodule + jar + 1.0 + daomodule + diff --git a/maven-java-11/multimodule-maven-project/daomodule/src/main/java/com/baeldung/dao/Dao.java b/maven-java-11/multimodule-maven-project/daomodule/src/main/java/com/baeldung/dao/Dao.java new file mode 100644 index 0000000000..f86ae8abb3 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/daomodule/src/main/java/com/baeldung/dao/Dao.java @@ -0,0 +1,12 @@ +package com.baeldung.dao; + +import java.util.List; +import java.util.Optional; + +public interface Dao { + + Optional findById(int id); + + List findAll(); + +} diff --git a/maven-java-11/multimodule-maven-project/daomodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/daomodule/src/main/java/module-info.java new file mode 100644 index 0000000000..072d7ad007 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/daomodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.dao { + exports com.baeldung.dao; +} diff --git a/maven-java-11/multimodule-maven-project/entitiymodule/pom.xml b/maven-java-11/multimodule-maven-project/entitiymodule/pom.xml new file mode 100644 index 0000000000..8e700e62b5 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/entitiymodule/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + com.baeldung.multimodule-maven-project + multimodule-maven-project + 1.0 + + com.baeldung.entitymodule + entitymodule + jar + 1.0 + entitymodule + + 11 + 11 + + diff --git a/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/com/baeldung/entity/User.java b/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/com/baeldung/entity/User.java new file mode 100644 index 0000000000..22022a2e6d --- /dev/null +++ b/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/com/baeldung/entity/User.java @@ -0,0 +1,19 @@ +package com.baeldung.entity; + +public class User { + + private final String name; + + public User(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "User{" + "name=" + name + '}'; + } +} diff --git a/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/module-info.java new file mode 100644 index 0000000000..67a3097352 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/entitiymodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.entity { + exports com.baeldung.entity; +} diff --git a/maven-java-11/multimodule-maven-project/mainppmodule/pom.xml b/maven-java-11/multimodule-maven-project/mainppmodule/pom.xml new file mode 100644 index 0000000000..d2c94527f1 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/mainppmodule/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + com.baeldung.multimodule-maven-project + multimodule-maven-project + 1.0 + + com.baeldung.mainappmodule + mainappmodule + 1.0 + jar + mainappmodule + + + + com.baeldung.entitymodule + entitymodule + 1.0 + + + com.baeldung.daomodule + daomodule + 1.0 + + + com.baeldung.userdaomodule + userdaomodule + 1.0 + + + diff --git a/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/com/baeldung/mainapp/Application.java b/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/com/baeldung/mainapp/Application.java new file mode 100644 index 0000000000..0c0df7461b --- /dev/null +++ b/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/com/baeldung/mainapp/Application.java @@ -0,0 +1,19 @@ +package com.baeldung.mainapp; + +import com.baeldung.dao.Dao; +import com.baeldung.entity.User; +import com.baeldung.userdao.UserDao; +import java.util.HashMap; +import java.util.Map; + +public class Application { + + public static void main(String[] args) { + Map users = new HashMap<>(); + users.put(1, new User("Julie")); + users.put(2, new User("David")); + Dao userDao = new UserDao(users); + userDao.findAll().forEach(System.out::println); + } + +} diff --git a/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/module-info.java new file mode 100644 index 0000000000..c688fcf7de --- /dev/null +++ b/maven-java-11/multimodule-maven-project/mainppmodule/src/main/java/module-info.java @@ -0,0 +1,6 @@ +module com.baeldung.mainapp { + requires com.baeldung.entity; + requires com.baeldung.userdao; + requires com.baeldung.dao; + uses com.baeldung.dao.Dao; +} diff --git a/maven-java-11/multimodule-maven-project/pom.xml b/maven-java-11/multimodule-maven-project/pom.xml new file mode 100644 index 0000000000..f22541738c --- /dev/null +++ b/maven-java-11/multimodule-maven-project/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + com.baeldung.multimodule-maven-project + multimodule-maven-project + 1.0 + pom + multimodule-maven-project + + com.baeldung.maven-java-11 + maven-java-11 + 1.0 + + + + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 3.12.2 + test + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + + + + + entitymodule + daomodule + userdaomodule + mainappmodule + + + + UTF-8 + + diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/pom.xml b/maven-java-11/multimodule-maven-project/userdaomodule/pom.xml new file mode 100644 index 0000000000..b4fe7f0398 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/userdaomodule/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + com.baeldung.multimodule-maven-project + multimodule-maven-project + 1.0 + + com.baeldung.userdaomodule + userdaomodule + 1.0 + jar + userdaomodule + + + com.baeldung.entitymodule + entitymodule + 1.0 + + + com.baeldung.daomodule + daomodule + 1.0 + + + junit + junit + test + + + diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/com/baeldung/userdao/UserDao.java b/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/com/baeldung/userdao/UserDao.java new file mode 100644 index 0000000000..1f1ea38a60 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/com/baeldung/userdao/UserDao.java @@ -0,0 +1,32 @@ +package com.baeldung.userdao; + +import com.baeldung.dao.Dao; +import com.baeldung.entity.User; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class UserDao implements Dao { + + private final Map users; + + public UserDao() { + users = new HashMap<>(); + } + + public UserDao(Map users) { + this.users = users; + } + + @Override + public List findAll() { + return new ArrayList<>(users.values()); + } + + @Override + public Optional findById(int id) { + return Optional.ofNullable(users.get(id)); + } +} \ No newline at end of file diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/module-info.java b/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/module-info.java new file mode 100644 index 0000000000..f1cb217e23 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/userdaomodule/src/main/java/module-info.java @@ -0,0 +1,6 @@ +module com.baeldung.userdao { + requires com.baeldung.entity; + requires com.baeldung.dao; + provides com.baeldung.dao.Dao with com.baeldung.userdao.UserDao; + exports com.baeldung.userdao; +} diff --git a/maven-java-11/multimodule-maven-project/userdaomodule/src/test/java/com/baeldung/userdao/test/UserDaoUnitTest.java b/maven-java-11/multimodule-maven-project/userdaomodule/src/test/java/com/baeldung/userdao/test/UserDaoUnitTest.java new file mode 100644 index 0000000000..191d17ff32 --- /dev/null +++ b/maven-java-11/multimodule-maven-project/userdaomodule/src/test/java/com/baeldung/userdao/test/UserDaoUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.userdao.test; + +import com.baeldung.dao.Dao; +import com.baeldung.entity.User; +import com.baeldung.userdao.UserDao; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; +import org.junit.Before; +import org.junit.Test; + +public class UserDaoUnitTest { + + private Dao userDao; + + @Before + public void setUpUserDaoInstance() { + Map users = new HashMap<>(); + users.put(1, new User("Julie")); + users.put(2, new User("David")); + userDao = new UserDao(users); + } + + @Test + public void givenUserDaoIntance_whenCalledFindById_thenCorrect() { + assertThat(userDao.findById(1), isA(Optional.class)); + } + + @Test + public void givenUserDaoIntance_whenCalledFindAll_thenCorrect() { + assertThat(userDao.findAll(), isA(List.class)); + } +} diff --git a/maven-java-11/pom.xml b/maven-java-11/pom.xml new file mode 100644 index 0000000000..4342fa740f --- /dev/null +++ b/maven-java-11/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + com.baeldung.maven-java-11 + maven-java-11 + 1.0 + pom + maven-java-11 + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + multimodule-maven-project + + + UTF-8 + 11 + 11 + + diff --git a/parent-kotlin/pom.xml b/parent-kotlin/pom.xml index 7a3a8b10ca..86ab45ecb1 100644 --- a/parent-kotlin/pom.xml +++ b/parent-kotlin/pom.xml @@ -202,10 +202,10 @@ - 1.3.10 + 1.3.30 1.0.0 0.9.5 - 3.11.0 - 1.2.0 + 3.12.0 + 1.3.2 diff --git a/patterns/README.md b/patterns/README.md index b3ece5e52b..f627251aa4 100644 --- a/patterns/README.md +++ b/patterns/README.md @@ -3,3 +3,4 @@ - [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) - [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern) - [The Dependency Inversion Principle in Java](https://www.baeldung.com/java-dependency-inversion-principle) +- [Avoid Check for Null Statement in Java](https://www.baeldung.com/java-avoid-null-check) diff --git a/patterns/design-patterns-2/README.md b/patterns/design-patterns-2/README.md new file mode 100644 index 0000000000..c2a75d4680 --- /dev/null +++ b/patterns/design-patterns-2/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [The Mediator Pattern in Java](https://www.baeldung.com/java-mediator-pattern) diff --git a/patterns/design-patterns/README.md b/patterns/design-patterns/README.md index c43ea48505..605fdc0d6e 100644 --- a/patterns/design-patterns/README.md +++ b/patterns/design-patterns/README.md @@ -19,4 +19,4 @@ - [The Command Pattern in Java](http://www.baeldung.com/java-command-pattern) - [Java Constructors vs Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods) - [The Adapter Pattern in Java](https://www.baeldung.com/java-adapter-pattern) -- [Currying in Java](https://baeldung.com/currying-in-java) +- [Currying in Java](https://www.baeldung.com/java-currying) diff --git a/patterns/principles/solid/README.md b/patterns/principles/solid/README.md index e2d72ecd28..ddd2f78b7e 100644 --- a/patterns/principles/solid/README.md +++ b/patterns/principles/solid/README.md @@ -1,5 +1,5 @@ ### Relevant Articles: -- [A Guide to Solid Principles](https://www.baeldung.com/solid-principles) +- [A Solid Guide to Solid Principles](https://www.baeldung.com/solid-principles) diff --git a/persistence-modules/README.md b/persistence-modules/README.md index 87dc9522fd..2fbaf25f2f 100644 --- a/persistence-modules/README.md +++ b/persistence-modules/README.md @@ -11,3 +11,5 @@ - [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) - [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all) - [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive) +- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby) +- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush) diff --git a/persistence-modules/core-java-persistence/pom.xml b/persistence-modules/core-java-persistence/pom.xml index a777eeb73f..2ad2083fec 100644 --- a/persistence-modules/core-java-persistence/pom.xml +++ b/persistence-modules/core-java-persistence/pom.xml @@ -6,15 +6,21 @@ 0.1.0-SNAPSHOT core-java-persistence jar - + com.baeldung parent-java 0.0.1-SNAPSHOT ../../parent-java - + + + org.postgresql + postgresql + ${postgresql.version} + test + org.assertj assertj-core @@ -52,7 +58,7 @@ ${springframework.boot.spring-boot-starter.version} - + core-java-persistence @@ -62,8 +68,10 @@ - + + 42.2.5.jre7 + 8.0.15 3.10.0 1.4.197 2.4.0 @@ -72,5 +80,5 @@ 1.5.8.RELEASE 4.3.4.RELEASE - + \ No newline at end of file diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbc/joins/ArticleWithAuthor.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbc/joins/ArticleWithAuthor.java new file mode 100644 index 0000000000..5ce196ee47 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbc/joins/ArticleWithAuthor.java @@ -0,0 +1,41 @@ +package com.baeldung.jdbc.joins; + +class ArticleWithAuthor { + + private String title; + + private String authorFirstName; + + private String authorLastName; + + public ArticleWithAuthor(String title, String authorFirstName, String authorLastName) { + this.title = title; + this.authorFirstName = authorFirstName; + this.authorLastName = authorLastName; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthorFirstName() { + return authorFirstName; + } + + public void setAuthorFirstName(String authorFirstName) { + this.authorFirstName = authorFirstName; + } + + public String getAuthorLastName() { + return authorLastName; + } + + public void setAuthorLastName(String authorLastName) { + this.authorLastName = authorLastName; + } + +} diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAO.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAO.java new file mode 100644 index 0000000000..55f03d99ec --- /dev/null +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAO.java @@ -0,0 +1,61 @@ +package com.baeldung.jdbc.joins; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +class ArticleWithAuthorDAO { + + private static final String QUERY_TEMPLATE = "SELECT ARTICLE.TITLE, AUTHOR.LAST_NAME, AUTHOR.FIRST_NAME FROM ARTICLE %s AUTHOR ON AUTHOR.id=ARTICLE.AUTHOR_ID"; + private final Connection connection; + + ArticleWithAuthorDAO(Connection connection) { + this.connection = connection; + } + + List articleInnerJoinAuthor() { + String query = String.format(QUERY_TEMPLATE, "INNER JOIN"); + return executeQuery(query); + } + + List articleLeftJoinAuthor() { + String query = String.format(QUERY_TEMPLATE, "LEFT JOIN"); + return executeQuery(query); + } + + List articleRightJoinAuthor() { + String query = String.format(QUERY_TEMPLATE, "RIGHT JOIN"); + return executeQuery(query); + } + + List articleFullJoinAuthor() { + String query = String.format(QUERY_TEMPLATE, "FULL JOIN"); + return executeQuery(query); + } + + private List executeQuery(String query) { + try (Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery(query); + return mapToList(resultSet); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + private List mapToList(ResultSet resultSet) throws SQLException { + List list = new ArrayList<>(); + while (resultSet.next()) { + ArticleWithAuthor articleWithAuthor = new ArticleWithAuthor( + resultSet.getString("TITLE"), + resultSet.getString("FIRST_NAME"), + resultSet.getString("LAST_NAME") + ); + list.add(articleWithAuthor); + } + return list; + } +} diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java new file mode 100644 index 0000000000..5c20b6bf1e --- /dev/null +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java @@ -0,0 +1,89 @@ +package com.baeldung.jdbc.joins; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ArticleWithAuthorDAOIntegrationTest { + private Connection connection; + + private ArticleWithAuthorDAO articleWithAuthorDAO; + + @Before + public void setup() throws ClassNotFoundException, SQLException { + Class.forName("org.postgresql.Driver"); + connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/myDb", "user", "pass"); + articleWithAuthorDAO = new ArticleWithAuthorDAO(connection); + Statement statement = connection.createStatement(); + String createAuthorSql = "CREATE TABLE IF NOT EXISTS AUTHOR (ID int NOT NULL PRIMARY KEY, FIRST_NAME varchar(255), LAST_NAME varchar(255));"; + String createArticleSql = "CREATE TABLE IF NOT EXISTS ARTICLE (ID int NOT NULL PRIMARY KEY, TITLE varchar(255) NOT NULL, AUTHOR_ID int, FOREIGN KEY(AUTHOR_ID) REFERENCES AUTHOR(ID));"; + statement.execute(createAuthorSql); + statement.execute(createArticleSql); + + insertTestData(statement); + } + + @Test + public void whenQueryWithInnerJoin_thenShouldReturnProperRows() { + List articleWithAuthorList = articleWithAuthorDAO.articleInnerJoinAuthor(); + + assertThat(articleWithAuthorList).hasSize(4); + assertThat(articleWithAuthorList).noneMatch(row -> row.getAuthorFirstName() == null || row.getTitle() == null); + } + + @Test + public void whenQueryWithLeftJoin_thenShouldReturnProperRows() { + List articleWithAuthorList = articleWithAuthorDAO.articleLeftJoinAuthor(); + + assertThat(articleWithAuthorList).hasSize(5); + assertThat(articleWithAuthorList).anyMatch(row -> row.getAuthorFirstName() == null); + } + + @Test + public void whenQueryWithRightJoin_thenShouldReturnProperRows() { + List articleWithAuthorList = articleWithAuthorDAO.articleRightJoinAuthor(); + + assertThat(articleWithAuthorList).hasSize(5); + assertThat(articleWithAuthorList).anyMatch(row -> row.getTitle() == null); + } + + @Test + public void whenQueryWithFullJoin_thenShouldReturnProperRows() { + List articleWithAuthorList = articleWithAuthorDAO.articleFullJoinAuthor(); + + assertThat(articleWithAuthorList).hasSize(6); + assertThat(articleWithAuthorList).anyMatch(row -> row.getTitle() == null); + assertThat(articleWithAuthorList).anyMatch(row -> row.getAuthorFirstName() == null); + } + + @After + public void cleanup() throws SQLException { + connection.createStatement().execute("DROP TABLE ARTICLE"); + connection.createStatement().execute("DROP TABLE AUTHOR"); + connection.close(); + } + + public void insertTestData(Statement statement) throws SQLException { + String insertAuthors = "INSERT INTO AUTHOR VALUES " + + "(1, 'Siena', 'Kerr')," + + "(2, 'Daniele', 'Ferguson')," + + "(3, 'Luciano', 'Wise')," + + "(4, 'Jonas', 'Lugo');"; + String insertArticles = "INSERT INTO ARTICLE VALUES " + + "(1, 'First steps in Java', 1)," + + "(2, 'SpringBoot tutorial', 1)," + + "(3, 'Java 12 insights', null)," + + "(4, 'SQL JOINS', 2)," + + "(5, 'Introduction to Spring Security', 3);"; + statement.execute(insertAuthors); + statement.execute(insertArticles); + } +} diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml new file mode 100644 index 0000000000..11caf67bf1 --- /dev/null +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -0,0 +1,52 @@ + + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + hibernate-mapping + 1.0.0-SNAPSHOT + 4.0.0 + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + com.h2database + h2 + ${h2database.version} + + + + + hibernate-mapping + + + src/test/resources + true + + + + + + 5.3.7.Final + 1.4.196 + 3.8.0 + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java new file mode 100644 index 0000000000..7411edd225 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -0,0 +1,64 @@ +package com.baeldung.hibernate; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + private static SessionFactory sessionFactory; + + private HibernateUtil() { + } + + public static SessionFactory getSessionFactory(Strategy strategy) { + if (sessionFactory == null) { + sessionFactory = buildSessionFactory(strategy); + } + return sessionFactory; + } + + private static SessionFactory buildSessionFactory(Strategy strategy) { + try { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + + for (Class entityClass : strategy.getEntityClasses()) { + metadataSources.addAnnotatedClass(entityClass); + } + + Metadata metadata = metadataSources.getMetadataBuilder() + .build(); + + return metadata.getSessionFactoryBuilder() + .build(); + } catch (IOException ex) { + throw new ExceptionInInitializerError(ex); + } + } + + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource("hibernate.properties"); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java new file mode 100644 index 0000000000..75f10ed583 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java @@ -0,0 +1,31 @@ +package com.baeldung.hibernate; + + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public enum Strategy { + //See that the classes belongs to different packages + MAP_KEY_COLUMN_BASED(Collections.singletonList(com.baeldung.hibernate.persistmaps.mapkeycolumn.Order.class)), + MAP_KEY_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkey.Item.class, + com.baeldung.hibernate.persistmaps.mapkey.Order.class)), + MAP_KEY_JOIN_COLUMN_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller.class, + com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Item.class, + com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Order.class)), + MAP_KEY_ENUMERATED_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyenumerated.Order.class, + com.baeldung.hibernate.persistmaps.mapkey.Item.class)), + MAP_KEY_TEMPORAL_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeytemporal.Order.class, + com.baeldung.hibernate.persistmaps.mapkey.Item.class)); + + + private List> entityClasses; + + Strategy(List> entityClasses) { + this.entityClasses = entityClasses; + } + + public List> getEntityClasses() { + return entityClasses; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java new file mode 100644 index 0000000000..b7f3cef9a2 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java @@ -0,0 +1,6 @@ +package com.baeldung.hibernate.persistmaps; + +public enum ItemType { + JEANS, + TSHIRTS +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java new file mode 100644 index 0000000000..385ffe93ea --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java @@ -0,0 +1,95 @@ +package com.baeldung.hibernate.persistmaps.mapkey; + +import com.baeldung.hibernate.persistmaps.ItemType; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.Date; +import java.util.Objects; + +@Entity +@Table(name = "item") +public class Item { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @Column(name = "name") + private String itemName; + + @Column(name = "price") + private double itemPrice; + + @Enumerated(EnumType.STRING) + @Column(name = "item_type") + private ItemType itemType; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_on") + private Date createdOn; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public double getItemPrice() { + return itemPrice; + } + + public void setItemPrice(double itemPrice) { + this.itemPrice = itemPrice; + } + + public ItemType getItemType() { + return itemType; + } + + public void setItemType(ItemType itemType) { + this.itemType = itemType; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Item item = (Item) o; + return id == item.id && + Double.compare(item.itemPrice, itemPrice) == 0 && + Objects.equals(itemName, item.itemName) && + itemType == item.itemType && + Objects.equals(createdOn, item.createdOn); + } + + @Override + public int hashCode() { + return Objects.hash(id, itemName, itemPrice, itemType, createdOn); + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java new file mode 100644 index 0000000000..8409cacd6b --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java @@ -0,0 +1,44 @@ +package com.baeldung.hibernate.persistmaps.mapkey; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKey; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKey(name = "itemName") + private Map itemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemMap() { + return itemMap; + } + + public void setItemMap(Map itemMap) { + this.itemMap = itemMap; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java new file mode 100644 index 0000000000..fa092060da --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java @@ -0,0 +1,43 @@ +package com.baeldung.hibernate.persistmaps.mapkeycolumn; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.MapKeyColumn; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @ElementCollection + @CollectionTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}) + @MapKeyColumn(name = "item_name") + @Column(name = "price") + private Map itemPriceMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemPriceMap() { + return itemPriceMap; + } + + public void setItemPriceMap(Map itemPriceMap) { + this.itemPriceMap = itemPriceMap; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java new file mode 100644 index 0000000000..e1f62599b8 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.persistmaps.mapkeyenumerated; + +import com.baeldung.hibernate.persistmaps.ItemType; +import com.baeldung.hibernate.persistmaps.mapkey.Item; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKeyEnumerated; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKeyEnumerated(EnumType.STRING) + private Map itemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemMap() { + return itemMap; + } + + public void setItemMap(Map itemMap) { + this.itemMap = itemMap; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java new file mode 100644 index 0000000000..97bbd5b539 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java @@ -0,0 +1,112 @@ +package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; + +import com.baeldung.hibernate.persistmaps.ItemType; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.Date; +import java.util.Objects; + +@Entity +@Table(name = "item") +public class Item { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @Column(name = "name") + private String itemName; + + @Column(name = "price") + private double itemPrice; + + @Column(name = "item_type") + @Enumerated(EnumType.STRING) + private ItemType itemType; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_on") + private Date createdOn; + + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "seller_id") + private Seller seller; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public double getItemPrice() { + return itemPrice; + } + + public void setItemPrice(double itemPrice) { + this.itemPrice = itemPrice; + } + + public ItemType getItemType() { + return itemType; + } + + public void setItemType(ItemType itemType) { + this.itemType = itemType; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public Seller getSeller() { + return seller; + } + + public void setSeller(Seller seller) { + this.seller = seller; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Item item = (Item) o; + return id == item.id && + Double.compare(item.itemPrice, itemPrice) == 0 && + Objects.equals(itemName, item.itemName) && + itemType == item.itemType && + Objects.equals(createdOn, item.createdOn) && + Objects.equals(seller, item.seller); + } + + @Override + public int hashCode() { + + return Objects.hash(id, itemName, itemPrice, itemType, createdOn, seller); + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java new file mode 100644 index 0000000000..d680d84501 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java @@ -0,0 +1,44 @@ +package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKeyJoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKeyJoinColumn(name = "seller_id") + private Map sellerItemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getSellerItemMap() { + return sellerItemMap; + } + + public void setSellerItemMap(Map sellerItemMap) { + this.sellerItemMap = sellerItemMap; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java new file mode 100644 index 0000000000..15b08e9fe6 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java @@ -0,0 +1,51 @@ +package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Objects; + +@Entity +@Table(name = "seller") +public class Seller { + + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @Column(name = "name") + private String sellerName; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSellerName() { + return sellerName; + } + + public void setSellerName(String sellerName) { + this.sellerName = sellerName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Seller seller = (Seller) o; + return Objects.equals(sellerName, seller.sellerName); + } + + @Override + public int hashCode() { + + return Objects.hash(sellerName); + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java new file mode 100644 index 0000000000..be602c1e9f --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.persistmaps.mapkeytemporal; + +import com.baeldung.hibernate.persistmaps.mapkey.Item; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKeyTemporal; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TemporalType; +import java.util.Date; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKeyTemporal(TemporalType.TIMESTAMP) + private Map itemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemMap() { + return itemMap; + } + + public void setItemMap(Map itemMap) { + this.itemMap = itemMap; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/resources/logback.xml b/persistence-modules/hibernate-mapping/src/main/resources/logback.xml new file mode 100644 index 0000000000..26beb6d5b4 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java new file mode 100644 index 0000000000..acd77ee382 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java @@ -0,0 +1,79 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkeycolumn.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyColumnIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_COLUMN_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyColumn_thenPersistMap() { + Map itemPriceMap = new HashMap<>(); + itemPriceMap.put("Wrangler Jeans", 150.0); + itemPriceMap.put("Lee Jeans", 180.0); + + + Order order = new Order(); + order.setItemPriceMap(itemPriceMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(); + } + + private void assertInsertedData() { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemPriceMap = order.getItemPriceMap(); + assertNotNull(itemPriceMap); + assertEquals(itemPriceMap.size(), 2); + assertEquals((Double) 150.0, itemPriceMap.get("Wrangler Jeans")); + assertEquals((Double) 180.0, itemPriceMap.get("Lee Jeans")); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java new file mode 100644 index 0000000000..221aa7b1d7 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java @@ -0,0 +1,95 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.Item; +import com.baeldung.hibernate.persistmaps.mapkeyenumerated.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyEnumeratedIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_ENUMERATED_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyEnumerated_thenPersistMap() { + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573))); + + + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573))); + + Map itemMap = new HashMap<>(); + itemMap.put(item1.getItemType(), item1); + itemMap.put(item2.getItemType(), item2); + + Order order = new Order(); + order.setItemMap(itemMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(item1, item2); + } + + private void assertInsertedData(Item expectedItem1, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemMap = order.getItemMap(); + assertNotNull(itemMap); + assertEquals(2, itemMap.size()); + assertEquals(expectedItem1, itemMap.get(ItemType.JEANS)); + assertEquals(expectedItem2, itemMap.get(ItemType.TSHIRTS)); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} + diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java new file mode 100644 index 0000000000..b500deb78e --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java @@ -0,0 +1,95 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.Item; +import com.baeldung.hibernate.persistmaps.mapkey.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKey_thenPersistMap() { + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573))); + + + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573))); + + Map itemMap = new HashMap<>(); + itemMap.put(item1.getItemName(), item1); + itemMap.put(item2.getItemName(), item2); + + Order order = new Order(); + order.setItemMap(itemMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(item1, item2); + } + + private void assertInsertedData(Item expectedItem1, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemMap = order.getItemMap(); + assertNotNull(itemMap); + assertEquals(2, itemMap.size()); + assertEquals(expectedItem1, itemMap.get("Wrangler Jeans")); + assertEquals(expectedItem2, itemMap.get("Armani Tshirts")); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} + diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java new file mode 100644 index 0000000000..88b22f5c99 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java @@ -0,0 +1,105 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Item; +import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Order; +import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyJoinColumnIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_JOIN_COLUMN_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyJoinColumn_thenPersistMap() { + Seller seller1 = new Seller(); + seller1.setSellerName("Walmart"); + + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573))); + item1.setSeller(seller1); + + + Seller seller2 = new Seller(); + seller2.setSellerName("Amazon"); + + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573))); + item2.setSeller(seller2); + + Map itemSellerMap = new HashMap<>(); + itemSellerMap.put(seller1, item1); + itemSellerMap.put(seller2, item2); + + Order order = new Order(); + order.setSellerItemMap(itemSellerMap); + + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(seller1, item1, seller2, item2); + } + + private void assertInsertedData(Seller seller1, Item expectedItem1, Seller seller2, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map sellerItemMap = order.getSellerItemMap(); + assertNotNull(sellerItemMap); + assertEquals(2, sellerItemMap.size()); + assertEquals(expectedItem1, sellerItemMap.get(seller1)); + assertEquals(expectedItem2, sellerItemMap.get(seller2)); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} + diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java new file mode 100644 index 0000000000..7117cad22f --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java @@ -0,0 +1,96 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.Item; +import com.baeldung.hibernate.persistmaps.mapkeytemporal.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyTemporalIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_TEMPORAL_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyEnumerated_thenPersistMap() { + Date item1CreatedOn = Date.from(Instant.ofEpochSecond(1554926573)); + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(item1CreatedOn); + + + Date item2CreatedOn = Date.from(Instant.ofEpochSecond(1554890573)); + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(item2CreatedOn); + + Map itemMap = new HashMap<>(); + itemMap.put(item1CreatedOn, item1); + itemMap.put(item2CreatedOn, item2); + + Order order = new Order(); + order.setItemMap(itemMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(item1CreatedOn, item1, item2CreatedOn, item2); + } + + private void assertInsertedData(Date item1CreatedOn, Item expectedItem1, Date item2CreatedOn, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemMap = order.getItemMap(); + assertNotNull(itemMap); + assertEquals(2, itemMap.size()); + assertEquals(expectedItem1, itemMap.get(item1CreatedOn)); + assertEquals(expectedItem2, itemMap.get(item2CreatedOn)); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties b/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties new file mode 100644 index 0000000000..c22da2496b --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties @@ -0,0 +1,10 @@ +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.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop + diff --git a/persistence-modules/hibernate5/README.md b/persistence-modules/hibernate5/README.md index a37720a428..68008bc8fe 100644 --- a/persistence-modules/hibernate5/README.md +++ b/persistence-modules/hibernate5/README.md @@ -32,3 +32,4 @@ - [Common Hibernate Exceptions](https://www.baeldung.com/hibernate-exceptions) - [Hibernate Aggregate Functions](https://www.baeldung.com/hibernate-aggregate-functions) - [Hibernate Query Plan Cache](https://www.baeldung.com/hibernate-query-plan-cache) +- [TransactionRequiredException Error](https://www.baeldung.com/jpa-transaction-required-exception) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 2424999fb3..5be1015942 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -2,7 +2,7 @@ - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) -- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) +- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) diff --git a/persistence-modules/java-mongodb/pom.xml b/persistence-modules/java-mongodb/pom.xml index 9658ef567f..0f5efedb96 100644 --- a/persistence-modules/java-mongodb/pom.xml +++ b/persistence-modules/java-mongodb/pom.xml @@ -35,8 +35,8 @@ 1.8 1.8 - 3.4.1 + 3.10.1 1.11 - \ No newline at end of file + diff --git a/persistence-modules/java-mongodb/src/main/java/com/baeldung/MongoBsonExample.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/MongoBsonExample.java new file mode 100644 index 0000000000..0ad3dfae30 --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/java/com/baeldung/MongoBsonExample.java @@ -0,0 +1,79 @@ +package com.baeldung; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import org.bson.Document; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MongoBsonExample +{ + public static void main(String[] args) + { + // + // 4.1 Connect to cluster (default is localhost:27017) + // + + MongoClient mongoClient = MongoClients.create(); + MongoDatabase database = mongoClient.getDatabase("myDB"); + MongoCollection collection = database.getCollection("employees"); + + // + // 4.2 Insert new document + // + + Document employee = new Document() + .append("first_name", "Joe") + .append("last_name", "Smith") + .append("title", "Java Developer") + .append("years_of_service", 3) + .append("skills", Arrays.asList("java", "spring", "mongodb")) + .append("manager", new Document() + .append("first_name", "Sally") + .append("last_name", "Johanson")); + collection.insertOne(employee); + + // + // 4.3 Find documents + // + + + Document query = new Document("last_name", "Smith"); + List results = new ArrayList<>(); + collection.find(query).into(results); + + query = + new Document("$or", Arrays.asList( + new Document("last_name", "Smith"), + new Document("first_name", "Joe"))); + results = new ArrayList<>(); + collection.find(query).into(results); + + // + // 4.4 Update document + // + + query = new Document( + "skills", + new Document( + "$elemMatch", + new Document("$eq", "spring"))); + Document update = new Document( + "$push", + new Document("skills", "security")); + collection.updateMany(query, update); + + // + // 4.5 Delete documents + // + + query = new Document( + "years_of_service", + new Document("$lt", 0)); + collection.deleteMany(query); + } +} diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 47c733d8a7..67a5c36fed 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -22,6 +22,7 @@ hbase hibernate5 hibernate-ogm + hibernate-mapping influxdb java-cassandra java-cockroachdb @@ -34,7 +35,7 @@ querydsl redis solr - spring-boot-h2/spring-boot-h2-database + spring-boot-persistence-h2 spring-boot-persistence spring-boot-persistence-mongodb spring-data-cassandra diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/.gitignore b/persistence-modules/spring-boot-persistence-h2/.gitignore similarity index 100% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/.gitignore rename to persistence-modules/spring-boot-persistence-h2/.gitignore diff --git a/persistence-modules/spring-boot-h2/README.md b/persistence-modules/spring-boot-persistence-h2/README.md similarity index 67% rename from persistence-modules/spring-boot-h2/README.md rename to persistence-modules/spring-boot-persistence-h2/README.md index af5f395440..377b7c8939 100644 --- a/persistence-modules/spring-boot-h2/README.md +++ b/persistence-modules/spring-boot-persistence-h2/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [Access the Same In-Memory H2 Database in Multiple Spring Boot Applications](https://www.baeldung.com/spring-boot-access-h2-database-multiple-apps) +- [Spring Boot With H2 Database](https://www.baeldung.com/spring-boot-h2-database) \ No newline at end of file diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/pom.xml b/persistence-modules/spring-boot-persistence-h2/pom.xml similarity index 97% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/pom.xml rename to persistence-modules/spring-boot-persistence-h2/pom.xml index 882b88b535..4c8073ddb4 100644 --- a/persistence-modules/spring-boot-h2/spring-boot-h2-database/pom.xml +++ b/persistence-modules/spring-boot-persistence-h2/pom.xml @@ -14,7 +14,7 @@ parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../../../parent-boot-2 + ../../parent-boot-2 diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java similarity index 100% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java rename to persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java similarity index 100% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java rename to persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java similarity index 100% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java rename to persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java new file mode 100644 index 0000000000..378093cfa9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/SpringBootH2Application.java @@ -0,0 +1,12 @@ +package com.baeldung.h2db.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootH2Application { + + public static void main(String... args) { + SpringApplication.run(SpringBootH2Application.class, args); + } +} diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/UserRepository.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/UserRepository.java new file mode 100644 index 0000000000..35e496e910 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/daos/UserRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.h2db.springboot.daos; + + + + +import com.baeldung.h2db.springboot.models.User; +import org.springframework.data.repository.CrudRepository; + +public interface UserRepository extends CrudRepository { +} diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/User.java b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/User.java new file mode 100644 index 0000000000..fa3c01c035 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/java/com/baeldung/h2db/springboot/models/User.java @@ -0,0 +1,54 @@ +package com.baeldung.h2db.springboot.models; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Table(name = "users") +@Entity +public class User { + + @Id + @GeneratedValue + private int id; + + private String firstName; + + private String lastName; + + public User() { } + + public int getId() { + return id; + } + + public void setId(int 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; + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + '}'; + } +} diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/application.properties b/persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties similarity index 84% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/application.properties rename to persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties index 5e425a3550..109b389b58 100644 --- a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/application.properties +++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/application.properties @@ -2,7 +2,7 @@ spring.datasource.url=jdbc:h2:mem:mydb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= -spring.jpa.hibernate.ddl-auto=create +spring.jpa.hibernate.ddl-auto=create-drop spring.h2.console.enabled=true spring.h2.console.path=/h2-console debug=true \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-h2/src/main/resources/data.sql b/persistence-modules/spring-boot-persistence-h2/src/main/resources/data.sql new file mode 100644 index 0000000000..2d7b446005 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/main/resources/data.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS billionaires; + +CREATE TABLE billionaires ( + id INT AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(250) NOT NULL, + last_name VARCHAR(250) NOT NULL, + career VARCHAR(250) DEFAULT NULL +); + +INSERT INTO billionaires (first_name, last_name, career) VALUES +('Aliko', 'Dangote', 'Billionaire Industrialist'), +('Bill', 'Gates', 'Billionaire Tech Entrepreneur'), +('Folrunsho', 'Alakija', 'Billionaire Oil Magnate'); \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java new file mode 100644 index 0000000000..aecc63c599 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java @@ -0,0 +1,50 @@ +package com.baeldung; + +import com.baeldung.h2db.springboot.SpringBootH2Application; +import com.baeldung.h2db.springboot.daos.UserRepository; +import com.baeldung.h2db.springboot.models.User; +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.*; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootH2Application.class) +public class SpringBootH2IntegrationTest { + + @Autowired + private UserRepository userRepository; + + @Test + public void contextLoads() { } + + @Test + public void givenUserProfile_whenAddUser_thenCreateNewUser() { + User user = new User(); + user.setFirstName("John"); + user.setLastName("Doe"); + userRepository.save(user); + List users = (List) userRepository.findAll(); + assertFalse(users.isEmpty()); + + String firstName = "Aliko"; + String lastName = "Dangote"; + User user1 = userRepository.findById(users.get(0).getId()).get(); + user1.setLastName(lastName); + user1.setFirstName(firstName); + userRepository.save(user1); + + user = userRepository.findById(user.getId()).get(); + assertEquals(user.getFirstName(), firstName); + assertEquals(user.getLastName(), lastName); + + userRepository.deleteById(user.getId()); + assertTrue( ((List) userRepository.findAll()).isEmpty()); + } + +} diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from persistence-modules/spring-boot-h2/spring-boot-h2-database/src/test/java/com/baeldung/SpringContextIntegrationTest.java rename to persistence-modules/spring-boot-persistence-h2/src/test/java/com/baeldung/SpringContextIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence/README.MD b/persistence-modules/spring-boot-persistence/README.MD index ee7c2e298e..709f505ea9 100644 --- a/persistence-modules/spring-boot-persistence/README.MD +++ b/persistence-modules/spring-boot-persistence/README.MD @@ -8,3 +8,4 @@ - [Integrating Spring Boot with HSQLDB](https://www.baeldung.com/spring-boot-hsqldb) - [Configuring a DataSource Programmatically in Spring Boot](https://www.baeldung.com/spring-boot-configure-data-source-programmatic) - [Resolving “Failed to Configure a DataSource” Error](https://www.baeldung.com/spring-boot-failed-to-configure-data-source) +- [Spring Boot with Hibernate](https://www.baeldung.com/spring-boot-hibernate) diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java index 547a905d91..c5c77be56f 100644 --- a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java +++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java @@ -1,13 +1,9 @@ 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.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @@ -17,10 +13,17 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + @Configuration @EnableJpaRepositories(basePackages = { "com.baeldung.boot.repository", "com.baeldung.repository" }) @PropertySource("classpath:persistence-generic-entity.properties") @EnableTransactionManagement +@Profile("default") //only required to allow H2JpaConfig and H2TestProfileJPAConfig to coexist in same project + //this demo project is showcasing several ways to achieve the same end, and class-level + //Profile annotations are only necessary because the different techniques are sharing a project public class H2JpaConfig { @Autowired diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java index 0227458987..d7bb44e133 100644 --- a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - +import com.baeldung.boot.Application; +import com.baeldung.boot.domain.GenericEntity; +import com.baeldung.boot.repository.GenericEntityRepository; +import com.baeldung.config.H2TestProfileJPAConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,13 +11,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.boot.Application; -import com.baeldung.boot.config.H2JpaConfig; -import com.baeldung.boot.domain.GenericEntity; -import com.baeldung.boot.repository.GenericEntityRepository; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; @RunWith(SpringRunner.class) -@SpringBootTest(classes = { Application.class, H2JpaConfig.class }) +@SpringBootTest(classes = { Application.class, H2TestProfileJPAConfig.class }) @ActiveProfiles("test") public class SpringBootProfileIntegrationTest { @Autowired diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java index e0678bcf47..f73000a10e 100644 --- a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java +++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java @@ -1,10 +1,5 @@ package com.baeldung.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; @@ -17,9 +12,16 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + @Configuration @EnableJpaRepositories(basePackages = { "com.baeldung.repository", "com.baeldung.boot.repository" }) @EnableTransactionManagement +@Profile("test") //only required to allow H2JpaConfig and H2TestProfileJPAConfig to coexist in same project + //this demo project is showcasing several ways to achieve the same end, and class-level + //Profile annotations are only necessary because the different techniques are sharing a project public class H2TestProfileJPAConfig { @Autowired diff --git a/persistence-modules/spring-data-couchbase-2/README.md b/persistence-modules/spring-data-couchbase-2/README.md index 2b6a1faddf..3145fc653a 100644 --- a/persistence-modules/spring-data-couchbase-2/README.md +++ b/persistence-modules/spring-data-couchbase-2/README.md @@ -2,7 +2,7 @@ ### Relevant Articles: - [Intro to Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase) -- [Entity Validation, Query Consistency, and Optimistic Locking in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase) +- [Entity Validation, Optimistic Locking, and Query Consistency in Spring Data Couchbase](http://www.baeldung.com/entity-validation-locking-and-query-consistency-in-spring-data-couchbase) - [Multiple Buckets and Spatial View Queries in Spring Data Couchbase](http://www.baeldung.com/spring-data-couchbase-buckets-and-spatial-view-queries) ### Overview diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 295a434d17..41381ab82a 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -3,3 +3,4 @@ ## Spring Data JPA Example Project ### Relevant Articles: +- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby) diff --git a/persistence-modules/spring-data-jpa-2/pom.xml b/persistence-modules/spring-data-jpa-2/pom.xml index 8e46112659..251007ba6d 100644 --- a/persistence-modules/spring-data-jpa-2/pom.xml +++ b/persistence-modules/spring-data-jpa-2/pom.xml @@ -1,12 +1,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 - com.baeldung + + com.baeldung spring-data-jpa-2 - spring-data-jpa - + spring-data-jpa + parent-boot-2 com.baeldung @@ -19,12 +20,22 @@ org.springframework.boot spring-boot-starter-data-jpa - + com.h2database h2 - + + + com.fasterxml.jackson.core + jackson-databind + + + + org.springframework + spring-oxm + + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/config/JpaPopulators.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/config/JpaPopulators.java new file mode 100644 index 0000000000..24348d31c5 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/config/JpaPopulators.java @@ -0,0 +1,35 @@ +package com.baeldung.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.data.repository.init.Jackson2RepositoryPopulatorFactoryBean; +import org.springframework.data.repository.init.UnmarshallerRepositoryPopulatorFactoryBean; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +import com.baeldung.entity.Fruit; + +@Configuration +public class JpaPopulators { + + @Bean + public Jackson2RepositoryPopulatorFactoryBean getRespositoryPopulator() throws Exception { + Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean(); + factory.setResources(new Resource[] { new ClassPathResource("fruit-data.json") }); + return factory; + } + + @Bean + public UnmarshallerRepositoryPopulatorFactoryBean repositoryPopulator() { + + Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller(); + unmarshaller.setClassesToBeBound(Fruit.class); + + UnmarshallerRepositoryPopulatorFactoryBean factory = new UnmarshallerRepositoryPopulatorFactoryBean(); + factory.setUnmarshaller(unmarshaller); + factory.setResources(new Resource[] { new ClassPathResource("apple-fruit-data.xml"), new ClassPathResource("guava-fruit-data.xml") }); + return factory; + } + +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/entity/Book.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/entity/Book.java new file mode 100644 index 0000000000..deac24548a --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/entity/Book.java @@ -0,0 +1,51 @@ +package com.baeldung.datajpadelete.entity; + +import javax.persistence.*; + +@Entity +public class Book { + + @Id + @GeneratedValue + private Long id; + private String title; + + @ManyToOne + private Category category; + + public Book() { + } + + public Book(String title) { + this.title = title; + } + + public Book(String title, Category category) { + this.title = title; + this.category = category; + } + + 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 Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/entity/Category.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/entity/Category.java new file mode 100644 index 0000000000..16f1a4157f --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/entity/Category.java @@ -0,0 +1,60 @@ +package com.baeldung.datajpadelete.entity; + +import javax.persistence.*; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Entity +public class Category { + + @Id + @GeneratedValue + private Long id; + private String name; + + @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true) + private List books; + + public Category() { + } + + public Category(String name) { + this.name = name; + } + + public Category(String name, Book... books) { + this.name = name; + this.books = Stream.of(books).collect(Collectors.toList()); + this.books.forEach(x -> x.setCategory(this)); + } + + public Category(String name, List books) { + this.name = name; + this.books = books; + } + + 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 List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/repository/BookRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/repository/BookRepository.java new file mode 100644 index 0000000000..5d0f45f127 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/repository/BookRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.datajpadelete.repository; + +import com.baeldung.datajpadelete.entity.Book; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface BookRepository extends CrudRepository { + + long deleteByTitle(String title); + + @Modifying + @Query("delete from Book b where b.title=:title") + void deleteBooks(@Param("title") String title); + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/repository/CategoryRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/repository/CategoryRepository.java new file mode 100644 index 0000000000..6fe7058a78 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/datajpadelete/repository/CategoryRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.datajpadelete.repository; + +import com.baeldung.datajpadelete.entity.Category; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CategoryRepository extends CrudRepository { +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/Company.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/Company.java new file mode 100644 index 0000000000..203cff1e35 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/Company.java @@ -0,0 +1,71 @@ +package com.baeldung.embeddable.model; + +import javax.persistence.AttributeOverride; +import javax.persistence.AttributeOverrides; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Company { + + @Id + @GeneratedValue + private Integer id; + + private String name; + + private String address; + + private String phone; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride( name = "firstName", column = @Column(name = "contact_first_name")), + @AttributeOverride( name = "lastName", column = @Column(name = "contact_last_name")), + @AttributeOverride( name = "phone", column = @Column(name = "contact_phone")) + }) + private ContactPerson contactPerson; + + 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 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 ContactPerson getContactPerson() { + return contactPerson; + } + + public void setContactPerson(ContactPerson contactPerson) { + this.contactPerson = contactPerson; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/ContactPerson.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/ContactPerson.java new file mode 100644 index 0000000000..561da80878 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/ContactPerson.java @@ -0,0 +1,38 @@ +package com.baeldung.embeddable.model; + +import javax.persistence.Embeddable; + +@Embeddable +public class ContactPerson { + + private String firstName; + + private String lastName; + + private String phone; + + 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 String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/repositories/CompanyRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/repositories/CompanyRepository.java new file mode 100644 index 0000000000..f456b15652 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/repositories/CompanyRepository.java @@ -0,0 +1,18 @@ +package com.baeldung.embeddable.repositories; + +import com.baeldung.embeddable.model.Company; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface CompanyRepository extends JpaRepository { + + List findByContactPersonFirstName(String firstName); + + @Query("SELECT C FROM Company C WHERE C.contactPerson.firstName = ?1") + List findByContactPersonFirstNameWithJPQL(String firstName); + + @Query(value = "SELECT * FROM company WHERE contact_first_name = ?1", nativeQuery = true) + List findByContactPersonFirstNameWithNativeQuery(String firstName); +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/customer/Customer.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Customer.java similarity index 95% rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/customer/Customer.java rename to persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Customer.java index ed922c3075..efcae73853 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/customer/Customer.java +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Customer.java @@ -1,4 +1,4 @@ -package com.baeldung.customer; +package com.baeldung.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java index f82022e67e..d45ac33db8 100644 --- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java @@ -2,7 +2,9 @@ package com.baeldung.entity; import javax.persistence.Entity; import javax.persistence.Id; +import javax.xml.bind.annotation.XmlRootElement; +@XmlRootElement @Entity public class Fruit { diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Department.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Department.java new file mode 100644 index 0000000000..439f7532f5 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Department.java @@ -0,0 +1,45 @@ +package com.baeldung.joins.model; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Department { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + private String name; + + @OneToMany(mappedBy = "department") + private List employees; + + 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 List getEmployees() { + return employees; + } + + public void setEmployees(List employees) { + this.employees = employees; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Employee.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Employee.java new file mode 100644 index 0000000000..277274e61c --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Employee.java @@ -0,0 +1,69 @@ +package com.baeldung.joins.model; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "joins_employee") +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + private int age; + + @ManyToOne + private Department department; + + @OneToMany(mappedBy = "employee") + private List phones; + + 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 int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Department getDepartment() { + return department; + } + + public void setDepartment(Department department) { + this.department = department; + } + + public List getPhones() { + return phones; + } + + public void setPhones(List phones) { + this.phones = phones; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Phone.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Phone.java new file mode 100644 index 0000000000..41382915b1 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/joins/model/Phone.java @@ -0,0 +1,44 @@ +package com.baeldung.joins.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity +public class Phone { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String number; + + @ManyToOne + private Employee employee; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public Employee getEmployee() { + return employee; + } + + public void setEmployee(Employee employee) { + this.employee = employee; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/model/Address.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/model/Address.java new file mode 100644 index 0000000000..0c5a3eac60 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/model/Address.java @@ -0,0 +1,57 @@ +package com.baeldung.projection.model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class Address { + @Id + private Long id; + @OneToOne + private Person person; + private String state; + private String city; + private String street; + private String zipCode; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getZipCode() { + return zipCode; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/model/Person.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/model/Person.java new file mode 100644 index 0000000000..d18bd1c72d --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/model/Person.java @@ -0,0 +1,47 @@ +package com.baeldung.projection.model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Entity +public class Person { + @Id + private Long id; + private String firstName; + private String lastName; + @OneToOne(mappedBy = "person") + private Address address; + + 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 Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/repository/AddressRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/repository/AddressRepository.java new file mode 100644 index 0000000000..c1053f4867 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/repository/AddressRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.projection.repository; + +import com.baeldung.projection.view.AddressView; +import com.baeldung.projection.model.Address; +import org.springframework.data.repository.Repository; + +import java.util.List; + +public interface AddressRepository extends Repository { + List getAddressByState(String state); +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/repository/PersonRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/repository/PersonRepository.java new file mode 100644 index 0000000000..64bc7471e6 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/repository/PersonRepository.java @@ -0,0 +1,14 @@ +package com.baeldung.projection.repository; + +import com.baeldung.projection.model.Person; +import com.baeldung.projection.view.PersonDto; +import com.baeldung.projection.view.PersonView; +import org.springframework.data.repository.Repository; + +public interface PersonRepository extends Repository { + PersonView findByLastName(String lastName); + + PersonDto findByFirstName(String firstName); + + T findByLastName(String lastName, Class type); +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/AddressView.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/AddressView.java new file mode 100644 index 0000000000..7a24a1e9b9 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/AddressView.java @@ -0,0 +1,7 @@ +package com.baeldung.projection.view; + +public interface AddressView { + String getZipCode(); + + PersonView getPerson(); +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/PersonDto.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/PersonDto.java new file mode 100644 index 0000000000..1fd924450b --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/PersonDto.java @@ -0,0 +1,34 @@ +package com.baeldung.projection.view; + +import java.util.Objects; + +public class PersonDto { + private final String firstName; + private final String lastName; + + public PersonDto(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PersonDto personDto = (PersonDto) o; + return Objects.equals(firstName, personDto.firstName) && Objects.equals(lastName, personDto.lastName); + } + + @Override + public int hashCode() { + return Objects.hash(firstName, lastName); + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/PersonView.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/PersonView.java new file mode 100644 index 0000000000..36777ec26f --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/projection/view/PersonView.java @@ -0,0 +1,12 @@ +package com.baeldung.projection.view; + +import org.springframework.beans.factory.annotation.Value; + +public interface PersonView { + String getFirstName(); + + String getLastName(); + + @Value("#{target.firstName + ' ' + target.lastName}") + String getFullName(); +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/customer/CustomerRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/CustomerRepository.java similarity index 89% rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/customer/CustomerRepository.java rename to persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/CustomerRepository.java index c354ccbb58..65b22bbd84 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/customer/CustomerRepository.java +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/CustomerRepository.java @@ -1,5 +1,6 @@ -package com.baeldung.customer; +package com.baeldung.repository; +import com.baeldung.entity.Customer; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/apple-fruit-data.xml b/persistence-modules/spring-data-jpa-2/src/main/resources/apple-fruit-data.xml new file mode 100644 index 0000000000..d87ae28f1e --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/apple-fruit-data.xml @@ -0,0 +1,7 @@ + + + + 1 + apple + red + diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/application-joins.properties b/persistence-modules/spring-data-jpa-2/src/main/resources/application-joins.properties new file mode 100644 index 0000000000..fe2270293b --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/application-joins.properties @@ -0,0 +1 @@ +spring.datasource.data=classpath:db/import_joins.sql diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/db/import_joins.sql b/persistence-modules/spring-data-jpa-2/src/main/resources/db/import_joins.sql new file mode 100644 index 0000000000..e4772d6ff2 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/db/import_joins.sql @@ -0,0 +1,13 @@ +INSERT INTO department (id, name) VALUES (1, 'Infra'); +INSERT INTO department (id, name) VALUES (2, 'Accounting'); +INSERT INTO department (id, name) VALUES (3, 'Management'); + +INSERT INTO joins_employee (id, name, age, department_id) VALUES (1, 'Baeldung', '35', 1); +INSERT INTO joins_employee (id, name, age, department_id) VALUES (2, 'John', '35', 2); +INSERT INTO joins_employee (id, name, age, department_id) VALUES (3, 'Jane', '35', 2); + +INSERT INTO phone (id, number, employee_id) VALUES (1, '111', 1); +INSERT INTO phone (id, number, employee_id) VALUES (2, '222', 1); +INSERT INTO phone (id, number, employee_id) VALUES (3, '333', 1); + +COMMIT; diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/fruit-data.json b/persistence-modules/spring-data-jpa-2/src/main/resources/fruit-data.json new file mode 100644 index 0000000000..6dc44e2586 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/fruit-data.json @@ -0,0 +1,14 @@ +[ + { + "_class": "com.baeldung.entity.Fruit", + "name": "apple", + "color": "red", + "id": 1 + }, + { + "_class": "com.baeldung.entity.Fruit", + "name": "guava", + "color": "green", + "id": 2 + } +] \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/guava-fruit-data.xml b/persistence-modules/spring-data-jpa-2/src/main/resources/guava-fruit-data.xml new file mode 100644 index 0000000000..ffd75bb4bb --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/guava-fruit-data.xml @@ -0,0 +1,7 @@ + + + + 2 + guava + green + diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java new file mode 100644 index 0000000000..9e7e516735 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.datajpadelete; + +import com.baeldung.Application; +import com.baeldung.datajpadelete.entity.Book; +import com.baeldung.datajpadelete.repository.BookRepository; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {Application.class}) +public class DeleteFromRepositoryUnitTest { + + @Autowired + private BookRepository repository; + + Book book1; + Book book2; + + @Before + public void setup() { + book1 = new Book("The Hobbit"); + book2 = new Book("All Quiet on the Western Front"); + + repository.saveAll(Arrays.asList(book1, book2)); + } + + @After + public void teardown() { + repository.deleteAll(); + } + + @Test + public void whenDeleteByIdFromRepository_thenDeletingShouldBeSuccessful() { + repository.deleteById(book1.getId()); + + assertThat(repository.count() == 1).isTrue(); + } + + @Test + public void whenDeleteAllFromRepository_thenRepositoryShouldBeEmpty() { + repository.deleteAll(); + + assertThat(repository.count() == 0).isTrue(); + } + + @Test + @Transactional + public void whenDeleteFromDerivedQuery_thenDeletingShouldBeSuccessful() { + repository.deleteByTitle("The Hobbit"); + + assertThat(repository.count() == 1).isTrue(); + } + + @Test + @Transactional + public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful() { + repository.deleteBooks("The Hobbit"); + + assertThat(repository.count() == 1).isTrue(); + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java new file mode 100644 index 0000000000..56de8749b2 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.datajpadelete; + +import com.baeldung.Application; +import com.baeldung.datajpadelete.entity.Book; +import com.baeldung.datajpadelete.entity.Category; +import com.baeldung.datajpadelete.repository.BookRepository; +import com.baeldung.datajpadelete.repository.CategoryRepository; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {Application.class}) +public class DeleteInRelationshipsUnitTest { + + @Autowired + private BookRepository bookRepository; + + @Autowired + private CategoryRepository categoryRepository; + + @Before + public void setup() { + Book book1 = new Book("The Hobbit"); + Category category1 = new Category("Cat1", book1); + categoryRepository.save(category1); + + Book book2 = new Book("All Quiet on the Western Front"); + Category category2 = new Category("Cat2", book2); + categoryRepository.save(category2); + } + + @After + public void teardown() { + bookRepository.deleteAll(); + categoryRepository.deleteAll(); + } + + @Test + public void whenDeletingCategories_thenBooksShouldAlsoBeDeleted() { + categoryRepository.deleteAll(); + + assertThat(bookRepository.count() == 0).isTrue(); + assertThat(categoryRepository.count() == 0).isTrue(); + } + + @Test + public void whenDeletingBooks_thenCategoriesShouldAlsoBeDeleted() { + bookRepository.deleteAll(); + + assertThat(bookRepository.count() == 0).isTrue(); + assertThat(categoryRepository.count() == 2).isTrue(); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/embeddable/EmbeddableIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/embeddable/EmbeddableIntegrationTest.java new file mode 100644 index 0000000000..b4c365a2d9 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/embeddable/EmbeddableIntegrationTest.java @@ -0,0 +1,125 @@ +package com.baeldung.embeddable; + +import com.baeldung.Application; +import com.baeldung.embeddable.model.Company; +import com.baeldung.embeddable.model.ContactPerson; +import com.baeldung.embeddable.repositories.CompanyRepository; +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 org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {Application.class}) +public class EmbeddableIntegrationTest { + + @Autowired + private CompanyRepository companyRepository; + + @Test + @Transactional + public void whenInsertingCompany_thenEmbeddedContactPersonDetailsAreMapped() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("First"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + Company result = companyRepository.getOne(company.getId()); + + assertEquals("Company", result.getName()); + assertEquals("1st street", result.getAddress()); + assertEquals("987-654-321", result.getPhone()); + assertEquals("First", result.getContactPerson().getFirstName()); + assertEquals("Last", result.getContactPerson().getLastName()); + assertEquals("123-456-789", result.getContactPerson().getPhone()); + } + + @Test + @Transactional + public void whenFindingCompanyByContactPersonAttribute_thenCompanyIsReturnedProperly() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("Name"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + List result = companyRepository.findByContactPersonFirstName("Name"); + + assertEquals(1, result.size()); + + result = companyRepository.findByContactPersonFirstName("FirstName"); + + assertEquals(0, result.size()); + } + + @Test + @Transactional + public void whenFindingCompanyByContactPersonAttributeWithJPQL_thenCompanyIsReturnedProperly() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("@QueryName"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + List result = companyRepository.findByContactPersonFirstNameWithJPQL("@QueryName"); + + assertEquals(1, result.size()); + + result = companyRepository.findByContactPersonFirstNameWithJPQL("FirstName"); + + assertEquals(0, result.size()); + } + + @Test + @Transactional + public void whenFindingCompanyByContactPersonAttributeWithNativeQuery_thenCompanyIsReturnedProperly() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("NativeQueryName"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + List result = companyRepository.findByContactPersonFirstNameWithNativeQuery("NativeQueryName"); + + assertEquals(1, result.size()); + + result = companyRepository.findByContactPersonFirstNameWithNativeQuery("FirstName"); + + assertEquals(0, result.size()); + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java new file mode 100644 index 0000000000..9b0d23f3e4 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/joins/JpaJoinsIntegrationTest.java @@ -0,0 +1,142 @@ +package com.baeldung.joins; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.joins.model.Department; +import com.baeldung.joins.model.Phone; +import java.util.Collection; +import java.util.List; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@DataJpaTest +@ActiveProfiles("joins") +public class JpaJoinsIntegrationTest { + + @PersistenceContext + private EntityManager entityManager; + + @Test + public void whenPathExpressionIsUsedForSingleValuedAssociation_thenCreatesImplicitInnerJoin() { + TypedQuery query = entityManager.createQuery("SELECT e.department FROM Employee e", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Accounting"); + } + + @Test + public void whenJoinKeywordIsUsed_thenCreatesExplicitInnerJoin() { + TypedQuery query = entityManager.createQuery("SELECT d FROM Employee e JOIN e.department d", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Accounting"); + } + + @Test + public void whenInnerJoinKeywordIsUsed_thenCreatesExplicitInnerJoin() { + TypedQuery query = entityManager.createQuery("SELECT d FROM Employee e INNER JOIN e.department d", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Accounting"); + } + + @Test + public void whenEntitiesAreListedInFromAndMatchedInWhere_ThenCreatesJoin() { + TypedQuery query = entityManager.createQuery("SELECT d FROM Employee e, Department d WHERE e.department = d", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Accounting"); + } + + @Test + public void whenEntitiesAreListedInFrom_ThenCreatesCartesianProduct() { + TypedQuery query = entityManager.createQuery("SELECT d FROM Employee e, Department d", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(9); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Management", "Infra", "Accounting", "Management", "Infra", "Accounting", "Management"); + } + + @Test + public void whenCollectionValuedAssociationIsJoined_ThenCanSelect() { + TypedQuery query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.phones ph WHERE ph LIKE '1%'", Phone.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(1); + } + + @Test + public void whenMultipleEntitiesAreListedWithJoin_ThenCreatesMultipleJoins() { + TypedQuery query = entityManager.createQuery("SELECT ph FROM Employee e JOIN e.department d JOIN e.phones ph WHERE d.name IS NOT NULL", Phone.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("number") + .containsOnly("111", "222", "333"); + } + + @Test + public void whenLeftKeywordIsSpecified_thenCreatesOuterJoinAndIncludesNonMatched() { + TypedQuery query = entityManager.createQuery("SELECT DISTINCT d FROM Department d LEFT JOIN d.employees e", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Management"); + } + + @Test + public void whenFetchKeywordIsSpecified_ThenCreatesFetchJoin() { + TypedQuery query = entityManager.createQuery("SELECT d FROM Department d JOIN FETCH d.employees", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(3); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Accounting"); + } + + @Test + public void whenLeftAndFetchKeywordsAreSpecified_ThenCreatesOuterFetchJoin() { + TypedQuery query = entityManager.createQuery("SELECT d FROM Department d LEFT JOIN FETCH d.employees", Department.class); + + List resultList = query.getResultList(); + + assertThat(resultList).hasSize(4); + assertThat(resultList).extracting("name") + .containsOnly("Infra", "Accounting", "Accounting", "Management"); + } + + @Test + public void whenCollectionValuedAssociationIsSpecifiedInSelect_ThenReturnsCollections() { + TypedQuery query = entityManager.createQuery("SELECT e.phones FROM Employee e", Collection.class); + + List resultList = query.getResultList(); + + assertThat(resultList).extracting("number").containsOnly("111", "222", "333"); + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/projection/JpaProjectionIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/projection/JpaProjectionIntegrationTest.java new file mode 100644 index 0000000000..96eaf4ed07 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/projection/JpaProjectionIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.projection; + +import com.baeldung.projection.model.Person; +import com.baeldung.projection.repository.AddressRepository; +import com.baeldung.projection.repository.PersonRepository; +import com.baeldung.projection.view.AddressView; +import com.baeldung.projection.view.PersonDto; +import com.baeldung.projection.view.PersonView; +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.test.context.jdbc.Sql; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD; + +@DataJpaTest +@RunWith(SpringRunner.class) +@Sql(scripts = "/projection-insert-data.sql") +@Sql(scripts = "/projection-clean-up-data.sql", executionPhase = AFTER_TEST_METHOD) +public class JpaProjectionIntegrationTest { + @Autowired + private AddressRepository addressRepository; + + @Autowired + private PersonRepository personRepository; + + @Test + public void whenUsingClosedProjections_thenViewWithRequiredPropertiesIsReturned() { + AddressView addressView = addressRepository.getAddressByState("CA").get(0); + assertThat(addressView.getZipCode()).isEqualTo("90001"); + + PersonView personView = addressView.getPerson(); + assertThat(personView.getFirstName()).isEqualTo("John"); + assertThat(personView.getLastName()).isEqualTo("Doe"); + } + + @Test + public void whenUsingOpenProjections_thenViewWithRequiredPropertiesIsReturned() { + PersonView personView = personRepository.findByLastName("Doe"); + assertThat(personView.getFullName()).isEqualTo("John Doe"); + } + + @Test + public void whenUsingClassBasedProjections_thenDtoWithRequiredPropertiesIsReturned() { + PersonDto personDto = personRepository.findByFirstName("John"); + assertThat(personDto.getFirstName()).isEqualTo("John"); + assertThat(personDto.getLastName()).isEqualTo("Doe"); + } + + @Test + public void whenUsingDynamicProjections_thenObjectWithRequiredPropertiesIsReturned() { + Person person = personRepository.findByLastName("Doe", Person.class); + PersonView personView = personRepository.findByLastName("Doe", PersonView.class); + PersonDto personDto = personRepository.findByLastName("Doe", PersonDto.class); + + assertThat(person.getFirstName()).isEqualTo("John"); + assertThat(personView.getFirstName()).isEqualTo("John"); + assertThat(personDto.getFirstName()).isEqualTo("John"); + } +} diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/customer/CustomerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java similarity index 83% rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/customer/CustomerRepositoryIntegrationTest.java rename to persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java index c3bd821f52..5d6457ce30 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/customer/CustomerRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/CustomerRepositoryIntegrationTest.java @@ -1,8 +1,6 @@ -package com.baeldung.customer; +package com.baeldung.repository; -import com.baeldung.config.PersistenceConfiguration; -import com.baeldung.config.PersistenceProductConfiguration; -import com.baeldung.config.PersistenceUserConfiguration; +import com.baeldung.entity.Customer; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,7 +15,7 @@ import java.util.List; import static org.junit.Assert.assertEquals; -@DataJpaTest(excludeAutoConfiguration = { PersistenceConfiguration.class, PersistenceUserConfiguration.class, PersistenceProductConfiguration.class }) +@DataJpaTest @RunWith(SpringRunner.class) public class CustomerRepositoryIntegrationTest { diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java new file mode 100644 index 0000000000..29ef52dcef --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java @@ -0,0 +1,38 @@ +package com.baeldung.repository; + +import static org.junit.Assert.assertEquals; + +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.test.context.junit4.SpringRunner; + +import com.baeldung.entity.Fruit; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class FruitPopulatorTest { + + @Autowired + private FruitRepository fruitRepository; + + @Test + public void givenFruitJsonPopulatorThenShouldInsertRecordOnStart() { + + List fruits = fruitRepository.findAll(); + assertEquals("record count is not matching", 2, fruits.size()); + + fruits.forEach(fruit -> { + if (1 == fruit.getId()) { + assertEquals("apple", fruit.getName()); + assertEquals("red", fruit.getColor()); + } else if (2 == fruit.getId()) { + assertEquals("guava", fruit.getName()); + assertEquals("green", fruit.getColor()); + } + }); + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/projection-clean-up-data.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/projection-clean-up-data.sql new file mode 100644 index 0000000000..d34f6f0636 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/resources/projection-clean-up-data.sql @@ -0,0 +1,2 @@ +DELETE FROM address; +DELETE FROM person; \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/projection-insert-data.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/projection-insert-data.sql new file mode 100644 index 0000000000..544dcc4b88 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/resources/projection-insert-data.sql @@ -0,0 +1,2 @@ +INSERT INTO person(id,first_name,last_name) VALUES (1,'John','Doe'); +INSERT INTO address(id,person_id,state,city,street,zip_code) VALUES (1,1,'CA', 'Los Angeles', 'Standford Ave', '90001'); \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa/README.md b/persistence-modules/spring-data-jpa/README.md index 48c3180262..4e390c2faf 100644 --- a/persistence-modules/spring-data-jpa/README.md +++ b/persistence-modules/spring-data-jpa/README.md @@ -5,7 +5,7 @@ ### Relevant Articles: - [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases) - [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories) -- [Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced) +- [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) - [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8) diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java index b2d145899e..6c6c145942 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java @@ -9,6 +9,8 @@ interface PassengerRepository extends JpaRepository, CustomPass Passenger findFirstByOrderBySeatNumberAsc(); + Passenger findTopByOrderBySeatNumberAsc(); + List findByOrderBySeatNumberAsc(); List findByLastNameOrderBySeatNumberAsc(String lastName); diff --git a/pom.xml b/pom.xml index e74c5cd670..64710a39a6 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 1.0.0-SNAPSHOT parent-modules pom - + lombok-custom @@ -233,7 +233,7 @@ ${maven-war-plugin.version} - + com.vackosar.gitflowincrementalbuilder @@ -376,15 +376,20 @@ cdi checker-plugin core-groovy + core-groovy-2 - + core-java-8 + core-java-8-2 + core-java-lambdas core-java-arrays core-java-collections + core-java-collections-map core-java-collections-list + core-java-collections-set core-java-concurrency-basic core-java-concurrency-collections core-java-io @@ -393,6 +398,7 @@ core-java-lang core-java-lang-oop core-java-lang-oop-2 + core-java-modules core-java-networking core-java-perf core-java-sun @@ -401,7 +407,7 @@ core-scala couchbase custom-pmd - + dagger data-structures ddd @@ -409,13 +415,13 @@ disruptor dozer drools - dubbo - + dubbo + ethereum - + feign flyway-cdi-extension - + geotools google-cloud google-web-toolkit @@ -429,17 +435,19 @@ guava-modules guice - + hazelcast helidon httpclient + httpclient-simple hystrix - + image-processing immutables jackson jackson-2 + jackson-simple java-collections-conversions java-collections-maps java-collections-maps-2 @@ -481,10 +489,10 @@ kotlin-libraries - + libraries - libraries2 + libraries-2 libraries-data libraries-apache-commons libraries-security @@ -508,8 +516,8 @@ mustache mybatis - - + + optaplanner orika osgi @@ -519,9 +527,9 @@ performance-tests protobuffer - + persistence-modules - + rabbitmq ratpack @@ -533,15 +541,17 @@ rule-engines rsocket rxjava - rxjava-2 + rxjava-2 software-security/sql-injection-samples - + tensorflow-java - + spring-boot-flowable + spring-security-kerberos + - + default-second @@ -575,14 +585,15 @@ parent-spring-5 parent-java parent-kotlin - + saas spark-java - + spring-4 - + spring-5 spring-5-webflux + spring-5-data-reactive spring-5-mvc spring-5-reactive spring-5-reactive-client @@ -590,16 +601,17 @@ spring-5-reactive-security spring-5-security spring-5-security-oauth - + spring-activiti spring-akka spring-all spring-amqp + spring-amqp-simple spring-aop spring-apache-camel spring-batch spring-bom - + spring-boot spring-boot-admin spring-boot-angular @@ -609,6 +621,7 @@ spring-boot-camel spring-boot-client + spring-boot-configuration spring-boot-crud spring-boot-ctx-fluent spring-boot-custom-starter @@ -618,6 +631,7 @@ spring-boot-keycloak spring-boot-logging-log4j2 spring-boot-mvc + spring-boot-mvc-birt spring-boot-ops spring-boot-rest spring-boot-data @@ -626,41 +640,41 @@ spring-boot-testing spring-boot-vue spring-boot-libraries - + spring-cloud spring-cloud-bus spring-cloud-data-flow - + spring-core spring-cucumber - + spring-data-rest spring-data-rest-querydsl spring-dispatcher-servlet spring-drools - + spring-ehcache spring-ejb spring-exceptions - + spring-freemarker - + spring-groovy - + spring-integration - + spring-jenkins-pipeline spring-jersey spring-jinq spring-jms spring-jooq - + spring-kafka spring-katharsis - + spring-ldap - + spring-mobile spring-mockito spring-mvc-forms-jsp @@ -672,12 +686,12 @@ spring-mvc-velocity spring-mvc-webflow spring-mvc-xml - + spring-protobuf - + spring-quartz - + spring-reactive-kotlin spring-reactor spring-remoting @@ -693,9 +707,9 @@ spring-security-acl spring-security-angular/server spring-security-cache-control - + spring-security-client - + spring-security-core spring-security-mvc-boot spring-security-mvc-custom @@ -723,48 +737,50 @@ spring-state-machine spring-static-resources spring-swagger-codegen - + spring-thymeleaf - + spring-userservice - + spring-vault spring-vertx - + spring-webflux-amqp - + spring-zuul - + static-analysis stripe structurizr struts-2 - + testing-modules - + twilio Twitter4J - + undertow - + vavr vertx vertx-and-rxjava video-tutorials vraptor - + wicket - + xml xmlunit-2 xstream - + tensorflow-java - + spring-boot-flowable + spring-security-kerberos + - + spring-context @@ -806,6 +822,7 @@ spring-boot-bootstrap spring-boot-camel spring-boot-client + spring-boot-configuration spring-boot-custom-starter greeter-spring-boot-autoconfigure greeter-spring-boot-sample-app @@ -902,6 +919,9 @@ persistence-modules/spring-data-eclipselink persistence-modules/spring-data-solr persistence-modules/spring-hibernate-5 + + spring-boot-flowable + spring-security-kerberos @@ -939,10 +959,11 @@ parent-spring-5 parent-java parent-kotlin - + core-java-concurrency-advanced core-kotlin core-kotlin-2 + core-kotlin-io jenkins/hello-world jws @@ -950,17 +971,15 @@ libraries persistence-modules/hibernate5 + persistence-modules/hibernate-mapping persistence-modules/java-jpa persistence-modules/java-mongodb - persistence-modules/jnosql + persistence-modules/jnosql - spring-5-data-reactive - spring-amqp-simple - - vaadin + vaadin - + integration-lite-first @@ -1031,14 +1050,18 @@ cdi checker-plugin core-groovy + core-groovy-2 - + core-java-8 + core-java-8-2 core-java-arrays core-java-collections + core-java-collections-map core-java-collections-list + core-java-collections-set core-java-concurrency-basic core-java-concurrency-collections core-java-io @@ -1047,13 +1070,14 @@ core-java-lang core-java-lang-oop core-java-lang-oop-2 + core-java-modules core-java-networking core-java-perf core-java-sun core-scala couchbase custom-pmd - + dagger data-structures ddd @@ -1061,13 +1085,13 @@ disruptor dozer drools - dubbo - + dubbo + ethereum - + feign flyway-cdi-extension - + geotools google-cloud google-web-toolkit @@ -1081,17 +1105,19 @@ guava-modules guice - + hazelcast helidon httpclient + httpclient-simple hystrix - + image-processing immutables jackson jackson-2 + jackson-simple java-collections-conversions java-collections-maps java-collections-maps-2 @@ -1132,7 +1158,7 @@ kotlin-libraries - + libraries libraries-data @@ -1146,6 +1172,7 @@ mapstruct maven + maven-java-11 maven-archetype maven-polyglot/maven-polyglot-json-extension @@ -1158,8 +1185,8 @@ mustache mybatis - - + + optaplanner orika osgi @@ -1169,9 +1196,9 @@ performance-tests protobuffer - + persistence-modules - + rabbitmq ratpack @@ -1183,8 +1210,8 @@ rule-engines rsocket rxjava - rxjava-2 - + rxjava-2 + @@ -1218,13 +1245,14 @@ parent-spring-5 parent-java parent-kotlin - + saas spark-java - + spring-4 - + spring-5 + spring-5-data-reactive spring-5-mvc spring-5-reactive spring-5-reactive-client @@ -1232,16 +1260,17 @@ spring-5-reactive-security spring-5-security spring-5-security-oauth - + spring-activiti spring-akka spring-all spring-amqp + spring-amqp-simple spring-aop spring-apache-camel spring-batch spring-bom - + spring-boot spring-boot-admin spring-boot-angular @@ -1251,6 +1280,7 @@ spring-boot-camel spring-boot-client + spring-boot-configuration spring-boot-crud spring-boot-ctx-fluent spring-boot-custom-starter @@ -1260,47 +1290,48 @@ spring-boot-keycloak spring-boot-logging-log4j2 spring-boot-mvc + spring-boot-mvc-birt spring-boot-ops spring-boot-rest spring-boot-data spring-boot-property-exp spring-boot-security spring-boot-vue - + spring-cloud spring-cloud-bus spring-cloud-data-flow - + spring-core spring-cucumber - + spring-data-rest spring-data-rest-querydsl spring-dispatcher-servlet spring-drools - - spring-ehcache + + spring-ehcache spring-ejb spring-exceptions - + spring-freemarker - + spring-groovy - + spring-integration - + spring-jenkins-pipeline spring-jersey spring-jinq spring-jms spring-jooq - + spring-kafka spring-katharsis - + spring-ldap - + spring-mobile spring-mockito spring-mvc-forms-jsp @@ -1312,12 +1343,12 @@ spring-mvc-velocity spring-mvc-webflow spring-mvc-xml - + spring-protobuf - + spring-quartz - + spring-reactive-kotlin spring-reactor spring-remoting @@ -1330,13 +1361,13 @@ spring-rest-simple spring-resttemplate spring-roo - + spring-security-acl spring-security-angular/server spring-security-cache-control - + spring-security-client - + spring-security-core spring-security-mvc-boot spring-security-mvc-custom @@ -1363,42 +1394,42 @@ spring-state-machine spring-static-resources spring-swagger-codegen - + spring-thymeleaf - + spring-userservice - + spring-vault spring-vertx - + spring-webflux-amqp - + spring-zuul - + static-analysis stripe structurizr struts-2 - + testing-modules - + twilio Twitter4J - + undertow - + vavr vertx vertx-and-rxjava video-tutorials vraptor - + wicket - + xml xmlunit-2 xstream - + @@ -1432,8 +1463,8 @@ parent-spring-5 parent-java parent-kotlin - - core-java + + core-java core-java-concurrency-advanced core-kotlin core-kotlin-2 @@ -1446,12 +1477,9 @@ persistence-modules/hibernate5 persistence-modules/java-jpa persistence-modules/java-mongodb - persistence-modules/jnosql + persistence-modules/jnosql - spring-5-data-reactive - spring-amqp-simple - - vaadin + vaadin @@ -1472,20 +1500,21 @@ UTF-8 UTF-8 - refs/remotes/origin/master - true + refs/remotes/origin/master + true + false false false false - + 4.12 1.3 2.21.0 - + 1.7.21 1.1.7 - + 2.21.0 3.7.0 @@ -1514,7 +1543,7 @@ 0.3.1 2.5.1 0.0.1 - 3.4 + 3.8 2.3 3.8 diff --git a/rxjava-2/README.md b/rxjava-2/README.md index d0bdeec684..4182f3fa00 100644 --- a/rxjava-2/README.md +++ b/rxjava-2/README.md @@ -2,8 +2,8 @@ - [RxJava and Error Handling](http://www.baeldung.com/rxjava-error-handling) - [RxJava 2 – Flowable](http://www.baeldung.com/rxjava-2-flowable) -- [RxJava 2 - Completable](http://www.baeldung.com/rxjava-completable) - [RxJava Maybe](http://www.baeldung.com/rxjava-maybe) - [Introduction to RxRelay for RxJava](http://www.baeldung.com/rx-relay) - [Combining RxJava Completables](https://www.baeldung.com/rxjava-completable) - [Converting Synchronous and Asynchronous APIs to Observables using RxJava2](https://www.baeldung.com/rxjava-apis-to-observables) +- [RxJava Hooks](https://www.baeldung.com/rxjava-hooks) diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryManualTest.java similarity index 97% rename from spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryManualTest.java index f425826dce..d4b1d0eeda 100644 --- a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java +++ b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryManualTest.java @@ -17,7 +17,7 @@ import static org.junit.Assert.assertNotNull; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) -public class AccountCrudRepositoryIntegrationTest { +public class AccountCrudRepositoryManualTest { @Autowired AccountCrudRepository repository; diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryManualTest.java similarity index 97% rename from spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryManualTest.java index bfa6a789b2..2ca075aa5e 100644 --- a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java +++ b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryManualTest.java @@ -19,7 +19,7 @@ import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatc @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) -public class AccountMongoRepositoryIntegrationTest { +public class AccountMongoRepositoryManualTest { @Autowired AccountMongoRepository repository; diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryManualTest.java similarity index 97% rename from spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryManualTest.java index e9b3eb1c40..d91acd24e2 100644 --- a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java +++ b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryManualTest.java @@ -15,7 +15,7 @@ import static org.junit.Assert.assertNotNull; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) -public class AccountRxJavaRepositoryIntegrationTest { +public class AccountRxJavaRepositoryManualTest { @Autowired AccountRxJavaRepository repository; diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsManualTest.java similarity index 97% rename from spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsManualTest.java index 373da0e393..5fa0e39317 100644 --- a/spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java +++ b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsManualTest.java @@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.*; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Spring5ReactiveApplication.class) -public class AccountTemplateOperationsIntegrationTest { +public class AccountTemplateOperationsManualTest { @Autowired AccountTemplateOperations accountTemplate; diff --git a/spring-5-security-oauth/README.md b/spring-5-security-oauth/README.md index 5a444d4784..a5cec370c7 100644 --- a/spring-5-security-oauth/README.md +++ b/spring-5-security-oauth/README.md @@ -1,5 +1,5 @@ ## Relevant articles: -- [Spring Security 5 -OAuth2 Login](http://www.baeldung.com/spring-security-5-oauth2-login) +- [Spring Security 5 – OAuth2 Login](http://www.baeldung.com/spring-security-5-oauth2-login) - [Extracting Principal and Authorities using Spring Security OAuth](https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor) - [Customizing Authorization and Token Requests with Spring Security 5.1 Client](https://www.baeldung.com/spring-security-custom-oauth-requests) diff --git a/spring-5-security-oauth/src/main/java/com/baeldung/cognito/CognitoWebConfiguration.java b/spring-5-security-oauth/src/main/java/com/baeldung/cognito/CognitoWebConfiguration.java new file mode 100644 index 0000000000..ae03e0a802 --- /dev/null +++ b/spring-5-security-oauth/src/main/java/com/baeldung/cognito/CognitoWebConfiguration.java @@ -0,0 +1,16 @@ +package com.baeldung.cognito; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@PropertySource("cognito/application_cognito.yml") +public class CognitoWebConfiguration implements WebMvcConfigurer { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("home"); + } +} diff --git a/spring-5-security-oauth/src/main/java/com/baeldung/cognito/SpringCognitoApplication.java b/spring-5-security-oauth/src/main/java/com/baeldung/cognito/SpringCognitoApplication.java new file mode 100644 index 0000000000..7f7b751cd9 --- /dev/null +++ b/spring-5-security-oauth/src/main/java/com/baeldung/cognito/SpringCognitoApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.cognito; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("cognito/application_cognito.yml") +public class SpringCognitoApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringCognitoApplication.class, args); + } +} diff --git a/spring-5-security-oauth/src/main/resources/cognito/application_cognito.yml b/spring-5-security-oauth/src/main/resources/cognito/application_cognito.yml new file mode 100644 index 0000000000..0a28dbccb4 --- /dev/null +++ b/spring-5-security-oauth/src/main/resources/cognito/application_cognito.yml @@ -0,0 +1,15 @@ +spring: + security: + oauth2: + client: + registration: + cognito: + client-id: clientId + client-secret: clientSecret + scope: openid + redirectUriTemplate: "http://localhost:8080/login/oauth2/code/cognito" + clientName: cognito-client-name + provider: + cognito: + issuerUri: https://cognito-idp.{region}.amazonaws.com/{poolId} + usernameAttribute: cognito:username diff --git a/spring-5-security-oauth/src/main/resources/cognito/home.html b/spring-5-security-oauth/src/main/resources/cognito/home.html new file mode 100644 index 0000000000..f0bd9e52a8 --- /dev/null +++ b/spring-5-security-oauth/src/main/resources/cognito/home.html @@ -0,0 +1,32 @@ + + + + + + OAuth2 Cognito Demo + + + + + +
+
+
+

OAuth2 Spring Security Cognito Demo

+ +
+
+ Hello, ! +
+
+ + +
+
+
+ + diff --git a/spring-5-security-oauth/src/main/resources/cognito/style.css b/spring-5-security-oauth/src/main/resources/cognito/style.css new file mode 100644 index 0000000000..45190d6d70 --- /dev/null +++ b/spring-5-security-oauth/src/main/resources/cognito/style.css @@ -0,0 +1,9 @@ +.login { + background-color: #7289da; + color: #fff; +} + +.login:hover { + background-color: #697ec4; + color: #fff; +} diff --git a/spring-5-webflux/README.md b/spring-5-webflux/README.md new file mode 100644 index 0000000000..84c3d5a4ca --- /dev/null +++ b/spring-5-webflux/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [Spring Boot Reactor Netty Configuration](https://www.baeldung.com/spring-boot-reactor-netty) +- [How to Return 404 with Spring WebFlux](https://www.baeldung.com/spring-webflux-404) diff --git a/spring-all/README.md b/spring-all/README.md index a111d2e542..b0805e5477 100644 --- a/spring-all/README.md +++ b/spring-all/README.md @@ -14,7 +14,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Properties with Spring and Spring Boot](http://www.baeldung.com/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage - [Spring Profiles](http://www.baeldung.com/spring-profiles) - [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor) -- [What's New in Spring 4.3?](http://www.baeldung.com/whats-new-in-spring-4-3) +- [What’s New in Spring 4.3?](http://www.baeldung.com/whats-new-in-spring-4-3) - [Running Setup Data on Startup in Spring](http://www.baeldung.com/running-setup-logic-on-startup-in-spring) - [Quick Guide to Spring Controllers](http://www.baeldung.com/spring-controllers) - [Quick Guide to Spring Bean Scopes](http://www.baeldung.com/spring-bean-scopes) @@ -34,3 +34,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Events](https://www.baeldung.com/spring-events) - [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations) - [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) +- [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class) diff --git a/spring-batch/README.md b/spring-batch/README.md index 737e7e13f5..ddd830cd47 100644 --- a/spring-batch/README.md +++ b/spring-batch/README.md @@ -6,5 +6,5 @@ ### Relevant Articles: - [Introduction to Spring Batch](http://www.baeldung.com/introduction-to-spring-batch) - [Spring Batch using Partitioner](http://www.baeldung.com/spring-batch-partitioner) -- [Spring Batch Tasklets vs Chunks Approach](http://www.baeldung.com/spring-batch-tasklet-chunk) +- [Spring Batch – Tasklets vs Chunks](http://www.baeldung.com/spring-batch-tasklet-chunk) - [How to Trigger and Stop a Scheduled Spring Batch Job](http://www.baeldung.com/spring-batch-start-stop-job) diff --git a/spring-boot-configuration/.gitignore b/spring-boot-configuration/.gitignore new file mode 100644 index 0000000000..153c9335eb --- /dev/null +++ b/spring-boot-configuration/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### 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/ + +### VS Code ### +.vscode/ diff --git a/spring-boot-configuration/README.MD b/spring-boot-configuration/README.MD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-configuration/pom.xml b/spring-boot-configuration/pom.xml new file mode 100644 index 0000000000..2ecef7bb02 --- /dev/null +++ b/spring-boot-configuration/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + com.baeldung + spring-boot-configuration + 0.0.1-SNAPSHOT + spring-boot-configuration + Demo project for Spring Boot configuration + + + + 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/spring-boot-configuration/src/main/java/com/baeldung/springbootconfiguration/SpringBootConfigurationApplication.java b/spring-boot-configuration/src/main/java/com/baeldung/springbootconfiguration/SpringBootConfigurationApplication.java new file mode 100644 index 0000000000..b4f5681475 --- /dev/null +++ b/spring-boot-configuration/src/main/java/com/baeldung/springbootconfiguration/SpringBootConfigurationApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.springbootconfiguration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootConfigurationApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootConfigurationApplication.class, args); + } + +} diff --git a/spring-boot-configuration/src/main/resources/application-tomcat.properties b/spring-boot-configuration/src/main/resources/application-tomcat.properties new file mode 100644 index 0000000000..d7c1ba9ac3 --- /dev/null +++ b/spring-boot-configuration/src/main/resources/application-tomcat.properties @@ -0,0 +1,23 @@ +# server configuration +server.port=80 +server.address=127.0.0.1 + +## Error handling configuration +server.error.whitelabel.enabled=true +server.error.path=/user-error +server.error.include-exception=true +server.error.include-stacktrace=always + +## Server connections configuration +server.tomcat.max-threads=200 +server.connection-timeout=5s +server.max-http-header-size=8KB +server.tomcat.max-swallow-size=2MB +server.tomcat.max-http-post-size=2MB + +## Access logs configuration +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.directory=logs +server.tomcat.accesslog.file-date-format=yyyy-MM-dd +server.tomcat.accesslog.prefix=access_log +server.tomcat.accesslog.suffix=.log diff --git a/spring-boot-configuration/src/main/resources/application.properties b/spring-boot-configuration/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-configuration/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-configuration/src/test/java/com/baeldung/springbootconfiguration/SpringContextIntegrationTest.java b/spring-boot-configuration/src/test/java/com/baeldung/springbootconfiguration/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..d6b2b50a2f --- /dev/null +++ b/spring-boot-configuration/src/test/java/com/baeldung/springbootconfiguration/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.springbootconfiguration; + +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 SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-boot-data/README.md b/spring-boot-data/README.md index 21f7303c48..d93b8c3e93 100644 --- a/spring-boot-data/README.md +++ b/spring-boot-data/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Formatting JSON Dates in Spring ](https://www.baeldung.com/spring-boot-formatting-json-dates) \ No newline at end of file +- [Formatting JSON Dates in Spring Boot](https://www.baeldung.com/spring-boot-formatting-json-dates) diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/.gitignore b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/.gitignore new file mode 100644 index 0000000000..153c9335eb --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### 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/ + +### VS Code ### +.vscode/ diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/pom.xml b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/pom.xml new file mode 100644 index 0000000000..8237955aef --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.4.RELEASE + + + com.baeldung + pass-exception-to-client-json-spring-boot + 0.0.4-SNAPSHOT + pass-exception-to-client-json-spring-boot + Baeldung article code on how to pass exceptions to client in JSON format using Spring Boot + + + 1.8 + + + + + 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/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/CustomException.java b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/CustomException.java new file mode 100644 index 0000000000..56fe80cd9a --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/CustomException.java @@ -0,0 +1,11 @@ +package com.baeldung.passexceptiontoclientjsonspringboot; + +public class CustomException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public CustomException() { + super("Custom exception message."); + } + +} \ No newline at end of file diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/ErrorHandler.java b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/ErrorHandler.java new file mode 100644 index 0000000000..b39d2811dd --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/ErrorHandler.java @@ -0,0 +1,19 @@ +package com.baeldung.passexceptiontoclientjsonspringboot; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ControllerAdvice +@ResponseBody +public class ErrorHandler { + + @ExceptionHandler(CustomException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public CustomException handleCustomException(CustomException ce) { + return ce; + } + +} \ No newline at end of file diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/MainController.java b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/MainController.java new file mode 100644 index 0000000000..82c0c022a8 --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/MainController.java @@ -0,0 +1,14 @@ +package com.baeldung.passexceptiontoclientjsonspringboot; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class MainController { + + @GetMapping("/") + public void index() throws CustomException { + throw new CustomException(); + } + +} \ No newline at end of file diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/PassExceptionToClientJsonSpringBootApplication.java b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/PassExceptionToClientJsonSpringBootApplication.java new file mode 100644 index 0000000000..77833c28fd --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/java/com/baeldung/passexceptiontoclientjsonspringboot/PassExceptionToClientJsonSpringBootApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.passexceptiontoclientjsonspringboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PassExceptionToClientJsonSpringBootApplication { + + public static void main(String[] args) { + SpringApplication.run(PassExceptionToClientJsonSpringBootApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/application.properties b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/static/.gitignore b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/static/.gitignore new file mode 100644 index 0000000000..5e7d2734cf --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/static/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/templates/.gitignore b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/templates/.gitignore new file mode 100644 index 0000000000..5e7d2734cf --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/main/resources/templates/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/test/java/com/baeldung/passexceptiontoclientjsonspringboot/MainControllerIntegrationTest.java b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/test/java/com/baeldung/passexceptiontoclientjsonspringboot/MainControllerIntegrationTest.java new file mode 100644 index 0000000000..a615dc5096 --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/test/java/com/baeldung/passexceptiontoclientjsonspringboot/MainControllerIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.passexceptiontoclientjsonspringboot; + +import org.junit.Test; + +public class MainControllerIntegrationTest { + + @Test(expected = CustomException.class) + public void givenIndex_thenCustomException() throws CustomException { + + MainController mainController = new MainController(); + + mainController.index(); + + } + +} \ No newline at end of file diff --git a/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/test/java/com/baeldung/passexceptiontoclientjsonspringboot/PassExceptionToClientJsonSpringBootApplicationTests.java b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/test/java/com/baeldung/passexceptiontoclientjsonspringboot/PassExceptionToClientJsonSpringBootApplicationTests.java new file mode 100644 index 0000000000..5e35c21f4c --- /dev/null +++ b/spring-boot-exceptions/pass-exception-to-client-json-spring-boot/src/test/java/com/baeldung/passexceptiontoclientjsonspringboot/PassExceptionToClientJsonSpringBootApplicationTests.java @@ -0,0 +1,16 @@ +package com.baeldung.passexceptiontoclientjsonspringboot; + +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 PassExceptionToClientJsonSpringBootApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-boot-flowable/README.md b/spring-boot-flowable/README.md new file mode 100644 index 0000000000..8fb90d953b --- /dev/null +++ b/spring-boot-flowable/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [Introduction to Flowable](http://www.baeldung.com/flowable) diff --git a/spring-boot-flowable/pom.xml b/spring-boot-flowable/pom.xml new file mode 100644 index 0000000000..f9531a1e6a --- /dev/null +++ b/spring-boot-flowable/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + spring-boot-flowable + war + spring-boot-flowable + Spring Boot Flowable Module + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + org.springframework.boot + spring-boot-starter-web + + + com.h2database + h2 + runtime + + + org.flowable + flowable-spring-boot-starter-rest + ${flowable.version} + + + org.flowable + flowable-spring-boot-starter-actuator + ${flowable.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + 6.4.1 + + \ No newline at end of file diff --git a/spring-boot-flowable/src/main/java/com/baeldung/Application.java b/spring-boot-flowable/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..37dbe7dab8 --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/Application.java @@ -0,0 +1,13 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-boot-flowable/src/main/java/com/baeldung/controller/ArticleWorkflowController.java b/spring-boot-flowable/src/main/java/com/baeldung/controller/ArticleWorkflowController.java new file mode 100644 index 0000000000..3087d30af4 --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/controller/ArticleWorkflowController.java @@ -0,0 +1,32 @@ +package com.baeldung.controller; + +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.domain.Approval; +import com.baeldung.domain.Article; +import com.baeldung.service.ArticleWorkflowService; + +@RestController +public class ArticleWorkflowController { + @Autowired + private ArticleWorkflowService service; + @PostMapping("/submit") + public void submit(@RequestBody Article article) { + service.startProcess(article); + } + @GetMapping("/tasks") + public List
getTasks(@RequestParam String assignee) { + return service.getTasks(assignee); + } + @PostMapping("/review") + public void review(@RequestBody Approval approval) { + service.submitReview(approval); + } +} \ No newline at end of file diff --git a/spring-boot-flowable/src/main/java/com/baeldung/domain/Approval.java b/spring-boot-flowable/src/main/java/com/baeldung/domain/Approval.java new file mode 100644 index 0000000000..b0c9c99437 --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/domain/Approval.java @@ -0,0 +1,24 @@ +package com.baeldung.domain; + +public class Approval { + + private String id; + private boolean status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public boolean isStatus() { + return status; + } + + public void setStatus(boolean status) { + this.status = status; + } + +} diff --git a/spring-boot-flowable/src/main/java/com/baeldung/domain/Article.java b/spring-boot-flowable/src/main/java/com/baeldung/domain/Article.java new file mode 100644 index 0000000000..efa2eb431e --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/domain/Article.java @@ -0,0 +1,52 @@ +package com.baeldung.domain; + +public class Article { + + private String id; + private String author; + private String url; + + public Article() { + } + + public Article(String author, String url) { + this.author = author; + this.url = url; + } + + public Article(String id, String author, String url) { + this.id = id; + this.author = author; + this.url = url; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + @Override + public String toString() { + return ("[" + this.author + " " + this.url + "]"); + } + +} diff --git a/spring-boot-flowable/src/main/java/com/baeldung/service/ArticleWorkflowService.java b/spring-boot-flowable/src/main/java/com/baeldung/service/ArticleWorkflowService.java new file mode 100644 index 0000000000..b1e2a92354 --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/service/ArticleWorkflowService.java @@ -0,0 +1,55 @@ +package com.baeldung.service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; +import org.flowable.task.api.Task; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.domain.Approval; +import com.baeldung.domain.Article; + +@Service +public class ArticleWorkflowService { + @Autowired + private RuntimeService runtimeService; + @Autowired + private TaskService taskService; + + @Transactional + public void startProcess(Article article) { + Map variables = new HashMap(); + variables.put("author", article.getAuthor()); + variables.put("url", article.getUrl()); + runtimeService.startProcessInstanceByKey("articleReview", variables); + } + + @Transactional + public List
getTasks(String assignee) { + List tasks = taskService.createTaskQuery() + .taskCandidateGroup(assignee) + .list(); + + List
articles = tasks.stream() + .map(task -> { + Map variables = taskService.getVariables(task.getId()); + return new Article( + task.getId(), (String) variables.get("author"), (String) variables.get("url")); + }) + .collect(Collectors.toList()); + return articles; + } + + @Transactional + public void submitReview(Approval approval) { + Map variables = new HashMap(); + variables.put("approved", approval.isStatus()); + taskService.complete(approval.getId(), variables); + } +} \ No newline at end of file diff --git a/spring-boot-flowable/src/main/java/com/baeldung/service/PublishArticleService.java b/spring-boot-flowable/src/main/java/com/baeldung/service/PublishArticleService.java new file mode 100644 index 0000000000..b43f1dccdb --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/service/PublishArticleService.java @@ -0,0 +1,10 @@ +package com.baeldung.service; + +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.JavaDelegate; + +public class PublishArticleService implements JavaDelegate { + public void execute(DelegateExecution execution) { + System.out.println("Publishing the approved article."); + } +} diff --git a/spring-boot-flowable/src/main/java/com/baeldung/service/SendMailService.java b/spring-boot-flowable/src/main/java/com/baeldung/service/SendMailService.java new file mode 100644 index 0000000000..f80b16748f --- /dev/null +++ b/spring-boot-flowable/src/main/java/com/baeldung/service/SendMailService.java @@ -0,0 +1,10 @@ +package com.baeldung.service; + +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.JavaDelegate; + +public class SendMailService implements JavaDelegate { + public void execute(DelegateExecution execution) { + System.out.println("Sending rejection mail to author."); + } +} diff --git a/spring-boot-flowable/src/main/resources/application.properties b/spring-boot-flowable/src/main/resources/application.properties new file mode 100644 index 0000000000..c3afcaa0b5 --- /dev/null +++ b/spring-boot-flowable/src/main/resources/application.properties @@ -0,0 +1 @@ +management.endpoint.flowable.enabled=true \ No newline at end of file diff --git a/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml b/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml new file mode 100644 index 0000000000..6bf210dcee --- /dev/null +++ b/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowUnitTest.java b/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowUnitTest.java new file mode 100644 index 0000000000..ef5453623a --- /dev/null +++ b/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.processes; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; +import org.flowable.engine.test.Deployment; +import org.flowable.spring.impl.test.FlowableSpringExtension; +import org.flowable.task.api.Task; +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.junit.jupiter.SpringExtension; + +@ExtendWith(FlowableSpringExtension.class) +@ExtendWith(SpringExtension.class) +public class ArticleWorkflowUnitTest { + @Autowired + private RuntimeService runtimeService; + @Autowired + private TaskService taskService; + @Test + @Deployment(resources = { "processes/article-workflow.bpmn20.xml" }) + void articleApprovalTest() { + Map variables = new HashMap(); + variables.put("author", "test@baeldung.com"); + variables.put("url", "http://baeldung.com/dummy"); + runtimeService.startProcessInstanceByKey("articleReview", variables); + Task task = taskService.createTaskQuery() + .singleResult(); + assertEquals("Review the submitted tutorial", task.getName()); + variables.put("approved", true); + taskService.complete(task.getId(), variables); + assertEquals(0, runtimeService.createProcessInstanceQuery() + .count()); + } +} \ No newline at end of file diff --git a/spring-boot-mvc-birt/README.md b/spring-boot-mvc-birt/README.md new file mode 100644 index 0000000000..9fe3d94e2a --- /dev/null +++ b/spring-boot-mvc-birt/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [BIRT Reporting with Spring Boot](https://www.baeldung.com/birt-reports-spring-boot) diff --git a/spring-boot-mvc-birt/pom.xml b/spring-boot-mvc-birt/pom.xml new file mode 100644 index 0000000000..8f41e8410a --- /dev/null +++ b/spring-boot-mvc-birt/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + com.baeldung + spring-boot-mvc-birt + spring-boot-mvc-birt + 0.0.1-SNAPSHOT + jar + Module For Spring Boot Integration with BIRT + + org.springframework.boot + spring-boot-starter-parent + 2.1.1.RELEASE + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-logging + + + ch.qos.logback + logback-classic + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.innoventsolutions.birt.runtime + org.eclipse.birt.runtime_4.8.0-20180626 + 4.8.0 + + + + log4j + log4j + 1.2.17 + + + + org.projectlombok + lombok + 1.18.6 + provided + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 2.1.1.RELEASE + com.baeldung.birt.engine.ReportEngineApplication + 1.8 + 1.8 + + + diff --git a/spring-boot-mvc-birt/reports/csv_data_report.rptdesign b/spring-boot-mvc-birt/reports/csv_data_report.rptdesign new file mode 100644 index 0000000000..f390c5e69b --- /dev/null +++ b/spring-boot-mvc-birt/reports/csv_data_report.rptdesign @@ -0,0 +1,2032 @@ + + + Eclipse BIRT Designer Version 4.7.0.v201706222054 + new_report + + + queryText + 5 + + + HOME + 4 + + + URI + 4 + + + DELIMTYPE + 4 + + + CHARSET + 4 + + + INCLCOLUMNNAME + 4 + + + INCLTYPELINE + 4 + + + TRAILNULLCOLS + 4 + + + OdaConnProfileName + 4 + + + OdaConnProfileStorePath + 4 + + + in + /templates/blank_report.gif + ltr + 96 + + + reports/data.csv + COMMA + UTF-8 + YES + NO + NO + + + + + nulls lowest + + + Student + dimension + Student + + + Math + measure + Math + + + Geography + measure + Geography + + + History + measure + History + + + + + + + 1 + Student + string + + + 2 + Math + integer + + + 3 + Geography + integer + + + 4 + History + integer + + + + Data Source + + + 1 + Student + Student + string + 12 + + + 2 + Math + Math + integer + 12 + + + 3 + Geography + Geography + integer + 12 + + + 4 + History + History + integer + 12 + + + + + + 2.0 + + + + + + + Studen + 1 + + 12 + -1 + -1 + Unknown + + + Studen + + + + + + + Math + 2 + + 12 + -1 + -1 + Unknown + + + Math + + + + + + + Geography + 3 + + 12 + -1 + -1 + Unknown + + + Geography + + + + + + + History + 4 + + 12 + -1 + -1 + Unknown + + + History + + + + + + + +]]> + + + + + + + + + + + + 7.947916666666667in + + 2.15625in + + + + + 2 + 1 + + + 2.6.1 + Bar Chart + Side-by-side + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 3.0 + 3.0 + 3.0 + 3.0 + + -1 + -1 + -1 + -1 + + + 1 + + 255 + 0 + 0 + 0 + + false + + true + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 3.0 + 3.0 + 3.0 + 3.0 + + -1 + -1 + -1 + -1 + + + 1 + + 255 + 0 + 0 + 0 + + false + + true + 5 + 5 + + + + 0 + + 255 + 0 + 0 + 0 + + false + + + 0.0 + 0.0 + 0.0 + 0.0 + + + + + + 0.0 + 0.0 + 0.0 + 0.0 + + + 3.0 + 3.0 + 3.0 + 3.0 + + -1 + -1 + -1 + -1 + + + 1 + + 255 + 0 + 0 + 0 + + false + + true + + + + 0 + + 255 + 0 + 0 + 0 + + false + + + 2.0 + 2.0 + 2.0 + 2.0 + + + + + + + + + Vertical + Top_Bottom + + + 1 + + 255 + 0 + 0 + 0 + + true + + Right + Series + + <Caption> + <Value></Value> + <Font> + <Alignment/> + </Font> + </Caption> + <Background xsi:type="attribute:ColorDefinition"> + <Transparency>0</Transparency> + <Red>255</Red> + <Green>255</Green> + <Blue>255</Blue> + </Background> + <Outline> + <Style>Solid</Style> + <Thickness>1</Thickness> + <Color> + <Transparency>255</Transparency> + <Red>0</Red> + <Green>0</Green> + <Blue>0</Blue> + </Color> + <Visible>false</Visible> + </Outline> + <Insets> + <Top>0.0</Top> + <Left>2.0</Left> + <Bottom>0.0</Bottom> + <Right>3.0</Right> + </Insets> + <Visible>false</Visible> + + Above + false + + + 0.0 + 0.0 + 572.25 + 286.125 + + + 3.0 + 3.0 + 3.0 + 3.0 + + -1 + -1 + -1 + -1 + + + 1 + + 255 + 0 + 0 + 0 + + false + + true + + Two_Dimensional + Points + 10.0 + + enable.area.alt + false + + + + A, B, C + + + 5,4,12 + 0 + + + 10.0,8.0,24.0 + 1 + + + 15.0,12.0,36.0 + 2 + + + + ToggleSerieVisibility + + + + This chart contains no data. + + + Center + Center + + + + + 64 + 127 + 127 + 127 + + + + 128 + 127 + 127 + 127 + + true + + + 10.0 + 10.0 + 10.0 + 10.0 + + false + + + Text + + <Caption> + <Value>X-Axis Title</Value> + <Font> + <Size>14.0</Size> + <Bold>true</Bold> + <Alignment> + <horizontalAlignment>Center</horizontalAlignment> + <verticalAlignment>Center</verticalAlignment> + </Alignment> + </Font> + </Caption> + <Background xsi:type="attribute:ColorDefinition"> + <Transparency>0</Transparency> + <Red>255</Red> + <Green>255</Green> + <Blue>255</Blue> + </Background> + <Outline> + <Style>Solid</Style> + <Thickness>1</Thickness> + <Color> + <Transparency>255</Transparency> + <Red>0</Red> + <Green>0</Green> + <Blue>0</Blue> + </Color> + </Outline> + <Insets> + <Top>0.0</Top> + <Left>2.0</Left> + <Bottom>0.0</Bottom> + <Right>3.0</Right> + </Insets> + <Visible>false</Visible> + + Below + + Linear + + <Caption> + <Value>Y-Axis Title</Value> + <Font> + <Size>14.0</Size> + <Bold>true</Bold> + <Alignment> + <horizontalAlignment>Center</horizontalAlignment> + <verticalAlignment>Center</verticalAlignment> + </Alignment> + </Font> + </Caption> + <Background xsi:type="attribute:ColorDefinition"> + <Transparency>0</Transparency> + <Red>255</Red> + <Green>255</Green> + <Blue>255</Blue> + </Background> + <Outline> + <Style>Solid</Style> + <Thickness>1</Thickness> + <Color> + <Transparency>255</Transparency> + <Red>0</Red> + <Green>0</Green> + <Blue>0</Blue> + </Color> + </Outline> + <Insets> + <Top>0.0</Top> + <Left>2.0</Left> + <Bottom>0.0</Bottom> + <Right>3.0</Right> + </Insets> + <Visible>false</Visible> + + Left + + + + + Numeric + + + + + 255 + 80 + 166 + 218 + + + 255 + 242 + 88 + 106 + + + 255 + 232 + 172 + 57 + + + 255 + 128 + 255 + 128 + + + 255 + 64 + 128 + 128 + + + 255 + 128 + 128 + 192 + + + 255 + 170 + 85 + 85 + + + 255 + 128 + 128 + 0 + + + 255 + 192 + 192 + 192 + + + 255 + 255 + 255 + 128 + + + 255 + 128 + 192 + 128 + + + 255 + 7 + 146 + 94 + + + 255 + 0 + 128 + 255 + + + 255 + 255 + 128 + 192 + + + 255 + 0 + 255 + 255 + + + 255 + 255 + 128 + 128 + + + 255 + 0 + 128 + 192 + + + 255 + 255 + 0 + 255 + + + 255 + 128 + 64 + 64 + + + 255 + 255 + 128 + 64 + + + 255 + 80 + 240 + 120 + + + 255 + 0 + 64 + 128 + + + 255 + 128 + 0 + 64 + + + 255 + 255 + 0 + 128 + + + 255 + 128 + 128 + 64 + + + 255 + 128 + 128 + 128 + + + 255 + 255 + 128 + 255 + + + 255 + 0 + 64 + 0 + + + 255 + 0 + 0 + 0 + + + 255 + 255 + 255 + 255 + + + 255 + 255 + 128 + 0 + + + + true + + + row["Geography"] + + Text + Sum + + + Geo + + + Orthogonal_Value + + , + + Outside + false + + onmouseover + + Show_Tooltip + + + 200 + + + + Rectangle + + + Text + Sum + + + + + + + Numeric + + + + + 255 + 242 + 88 + 106 + + + 255 + 232 + 172 + 57 + + + 255 + 128 + 255 + 128 + + + 255 + 64 + 128 + 128 + + + 255 + 128 + 128 + 192 + + + 255 + 170 + 85 + 85 + + + 255 + 128 + 128 + 0 + + + 255 + 192 + 192 + 192 + + + 255 + 255 + 255 + 128 + + + 255 + 128 + 192 + 128 + + + 255 + 7 + 146 + 94 + + + 255 + 0 + 128 + 255 + + + 255 + 255 + 128 + 192 + + + 255 + 0 + 255 + 255 + + + 255 + 255 + 128 + 128 + + + 255 + 0 + 128 + 192 + + + 255 + 255 + 0 + 255 + + + 255 + 128 + 64 + 64 + + + 255 + 255 + 128 + 64 + + + 255 + 80 + 240 + 120 + + + 255 + 0 + 64 + 128 + + + 255 + 128 + 0 + 64 + + + 255 + 255 + 0 + 128 + + + 255 + 128 + 128 + 64 + + + 255 + 128 + 128 + 128 + + + 255 + 255 + 128 + 255 + + + 255 + 0 + 64 + 0 + + + 255 + 0 + 0 + 0 + + + 255 + 255 + 255 + 255 + + + 255 + 255 + 128 + 0 + + + 255 + 80 + 166 + 218 + + + + true + + + row["History"] + + false + Text + Sum + + + History + + + Orthogonal_Value + + , + + Outside + false + + onmouseover + + Show_Tooltip + + + 200 + + + + Rectangle + + + Text + Sum + + + + + + + Numeric + + + + + 255 + 232 + 172 + 57 + + + 255 + 128 + 255 + 128 + + + 255 + 64 + 128 + 128 + + + 255 + 128 + 128 + 192 + + + 255 + 170 + 85 + 85 + + + 255 + 128 + 128 + 0 + + + 255 + 192 + 192 + 192 + + + 255 + 255 + 255 + 128 + + + 255 + 128 + 192 + 128 + + + 255 + 7 + 146 + 94 + + + 255 + 0 + 128 + 255 + + + 255 + 255 + 128 + 192 + + + 255 + 0 + 255 + 255 + + + 255 + 255 + 128 + 128 + + + 255 + 0 + 128 + 192 + + + 255 + 255 + 0 + 255 + + + 255 + 128 + 64 + 64 + + + 255 + 255 + 128 + 64 + + + 255 + 80 + 240 + 120 + + + 255 + 0 + 64 + 128 + + + 255 + 128 + 0 + 64 + + + 255 + 255 + 0 + 128 + + + 255 + 128 + 128 + 64 + + + 255 + 128 + 128 + 128 + + + 255 + 255 + 128 + 255 + + + 255 + 0 + 64 + 0 + + + 255 + 0 + 0 + 0 + + + 255 + 255 + 255 + 255 + + + 255 + 255 + 128 + 0 + + + 255 + 80 + 166 + 218 + + + 255 + 242 + 88 + 106 + + + + true + + + row["Math"] + + false + Text + Sum + + + Math + + + Orthogonal_Value + + , + + Outside + false + + onmouseover + + Show_Tooltip + + + 200 + + + + Rectangle + + + Text + Sum + + + Vertical + + + 1 + + 255 + 0 + 0 + 0 + + true + + + Left + + + + 1 + + 255 + 196 + 196 + 196 + + false + + Across + + + 1 + + 255 + 196 + 196 + 196 + + true + + + + + + 1 + + 255 + 225 + 225 + 225 + + false + + Across + + + 1 + + 255 + 225 + 225 + 225 + + false + + + + 5 + + + Min + + 0.0 + + + true + false + + + + + + + + 255 + 80 + 166 + 218 + + + 255 + 242 + 88 + 106 + + + 255 + 232 + 172 + 57 + + + 255 + 128 + 255 + 128 + + + 255 + 64 + 128 + 128 + + + 255 + 128 + 128 + 192 + + + 255 + 170 + 85 + 85 + + + 255 + 128 + 128 + 0 + + + 255 + 192 + 192 + 192 + + + 255 + 255 + 255 + 128 + + + 255 + 128 + 192 + 128 + + + 255 + 7 + 146 + 94 + + + 255 + 0 + 128 + 255 + + + 255 + 255 + 128 + 192 + + + 255 + 0 + 255 + 255 + + + 255 + 255 + 128 + 128 + + + 255 + 0 + 128 + 192 + + + 255 + 255 + 0 + 255 + + + 255 + 128 + 64 + 64 + + + 255 + 255 + 128 + 64 + + + 255 + 80 + 240 + 120 + + + 255 + 0 + 64 + 128 + + + 255 + 128 + 0 + 64 + + + 255 + 255 + 0 + 128 + + + 255 + 128 + 128 + 64 + + + 255 + 128 + 128 + 128 + + + 255 + 255 + 128 + 255 + + + 255 + 0 + 64 + 0 + + + 255 + 0 + 0 + 0 + + + 255 + 255 + 255 + 255 + + + 255 + 255 + 128 + 0 + + + + true + + + row["Student"] + + + + + Orthogonal_Value + + , + + Outside + false + + + true + Text + Sum + + + Horizontal + + + 1 + + 255 + 0 + 0 + 0 + + true + + + Below + + + + 1 + + 255 + 196 + 196 + 196 + + false + + Across + + + 1 + + 255 + 196 + 196 + 196 + + true + + + + + + 1 + + 255 + 225 + 225 + 225 + + false + + Across + + + 1 + + 255 + 225 + 225 + 225 + + false + + + + 5 + + + Min + + 0.0 + + + true + true + false + + Vertical + 50.0 + + + -20.0 + 45.0 + 0.0 + None + + + +]]> + SVG + true + 286.125pt + 572.25pt + Data Set + + + Student + Student + dataSetRow["Student"] + string + + + Math + Math + dataSetRow["Math"] + integer + + + Geography + Geography + dataSetRow["Geography"] + integer + + + History + History + dataSetRow["History"] + integer + + + + + + + + 2 + 1 + + Data Set + + + Student + Student + dataSetRow["Student"] + string + + + Math + Math + dataSetRow["Math"] + integer + + + Geography + Geography + dataSetRow["Geography"] + integer + + + History + History + dataSetRow["History"] + integer + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + Student + + + + + Math + + + + + Geography + + + + + History + + + + +
+ + + + + + +
+
+
+
+
+ +
diff --git a/spring-boot-mvc-birt/reports/data.csv b/spring-boot-mvc-birt/reports/data.csv new file mode 100644 index 0000000000..d05e58415e --- /dev/null +++ b/spring-boot-mvc-birt/reports/data.csv @@ -0,0 +1,4 @@ +Student, Math, Geography, History +Bill, 10,3,8 +Tom, 5,6,5 +Anne, 7, 4,9 \ No newline at end of file diff --git a/spring-boot-mvc-birt/reports/static_report.rptdesign b/spring-boot-mvc-birt/reports/static_report.rptdesign new file mode 100644 index 0000000000..d96ff76856 --- /dev/null +++ b/spring-boot-mvc-birt/reports/static_report.rptdesign @@ -0,0 +1,27 @@ + + + Sample Report + + + + + + 100% + + + + + + url + "https://www.baeldung.com/wp-content/themes/baeldung/favicon/favicon-96x96.png" + + + + + + + + + diff --git a/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/designer/ReportDesignApplication.java b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/designer/ReportDesignApplication.java new file mode 100644 index 0000000000..f1e1619a58 --- /dev/null +++ b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/designer/ReportDesignApplication.java @@ -0,0 +1,93 @@ +package com.baeldung.birt.designer; + +import com.ibm.icu.util.ULocale; +import org.apache.log4j.Logger; +import org.eclipse.birt.core.exception.BirtException; +import org.eclipse.birt.core.framework.Platform; +import org.eclipse.birt.report.model.api.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +import java.io.File; +import java.io.IOException; + +@SpringBootApplication +public class ReportDesignApplication implements CommandLineRunner { + + private static final Logger log = Logger.getLogger(ReportDesignApplication.class); + + @Value("${reports.relative.path}") + private String REPORTS_FOLDER; + + public static void main(String[] args) { + new SpringApplicationBuilder(ReportDesignApplication.class).web(WebApplicationType.NONE).build().run(args); + } + + @Override public void run(String... args) throws Exception { + buildReport(); + } + + private void buildReport() throws IOException, BirtException { + final DesignConfig config = new DesignConfig(); + + final IDesignEngine engine; + try { + Platform.startup(config); + IDesignEngineFactory factory = (IDesignEngineFactory) Platform + .createFactoryObject(IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY); + engine = factory.createDesignEngine(config); + + } catch (Exception ex) { + log.error("Exception during creation of DesignEngine", ex); + throw ex; + } + + SessionHandle session = engine.newSessionHandle(ULocale.ENGLISH); + + ReportDesignHandle design = session.createDesign(); + design.setTitle("Sample Report"); + + // The element factory creates instances of the various BIRT elements. + ElementFactory factory = design.getElementFactory(); + + // Create a simple master page that describes how the report will + // appear when printed. + // + // Note: The report will fail to load in the BIRT designer + // unless you create a master page. + + DesignElementHandle element = factory.newSimpleMasterPage("Page Master"); //$NON-NLS-1$ + design.getMasterPages().add(element); + + // Create a grid + GridHandle grid = factory.newGridItem(null, 2 /* cols */, 1 /* row */); + design.getBody().add(grid); + grid.setWidth("100%"); + + RowHandle row0 = (RowHandle) grid.getRows().get(0); + + // Create an image and add it to the first cell. + ImageHandle image = factory.newImage(null); + CellHandle cell = (CellHandle) row0.getCells().get(0); + cell.getContent().add(image); + image.setURL("\"https://www.baeldung.com/wp-content/themes/baeldung/favicon/favicon-96x96.png\""); + + // Create a label and add it to the second cell. + LabelHandle label = factory.newLabel(null); + cell = (CellHandle) row0.getCells().get(1); + cell.getContent().add(label); + label.setText("Hello, Baeldung world!"); + + // Save the design and close it. + File report = new File(REPORTS_FOLDER); + report.mkdirs(); + + design.saveAs(new File(report, "static_report.rptdesign").getAbsolutePath()); + design.close(); + log.info("Report generated"); + } + +} diff --git a/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/ReportEngineApplication.java b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/ReportEngineApplication.java new file mode 100644 index 0000000000..6d72017c9d --- /dev/null +++ b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/ReportEngineApplication.java @@ -0,0 +1,29 @@ +package com.baeldung.birt.engine; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@SpringBootApplication +@EnableWebMvc +public class ReportEngineApplication implements WebMvcConfigurer { + @Value("${reports.relative.path}") + private String reportsPath; + @Value("${images.relative.path}") + private String imagesPath; + + public static void main(final String[] args) { + SpringApplication.run(ReportEngineApplication.class, args); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry + .addResourceHandler(reportsPath + imagesPath + "/**") + .addResourceLocations("file:///" + System.getProperty("user.dir") + "/" + reportsPath + imagesPath); + } + +} \ No newline at end of file diff --git a/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/controller/BirtReportController.java b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/controller/BirtReportController.java new file mode 100644 index 0000000000..e2405d02ec --- /dev/null +++ b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/controller/BirtReportController.java @@ -0,0 +1,51 @@ +package com.baeldung.birt.engine.controller; + +import com.baeldung.birt.engine.dto.OutputType; +import com.baeldung.birt.engine.dto.Report; +import com.baeldung.birt.engine.service.BirtReportService; +import org.apache.log4j.Logger; +import org.eclipse.birt.report.engine.api.EngineException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +@Controller +public class BirtReportController { + private static final Logger log = Logger.getLogger(BirtReportController.class); + + @Autowired + private BirtReportService reportService; + + @RequestMapping(produces = "application/json", method = RequestMethod.GET, value = "/report") + @ResponseBody + public List listReports() { + return reportService.getReports(); + } + + @RequestMapping(produces = "application/json", method = RequestMethod.GET, value = "/report/reload") + @ResponseBody + public ResponseEntity reloadReports(HttpServletResponse response) { + try { + log.info("Reloading reports"); + reportService.loadReports(); + } catch (EngineException e) { + log.error("There was an error reloading the reports in memory: ", e); + return ResponseEntity.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).build(); + } + return ResponseEntity.ok().build(); + } + + @RequestMapping(method = RequestMethod.GET, value = "/report/{name}") + @ResponseBody + public void generateFullReport(HttpServletResponse response, HttpServletRequest request, + @PathVariable("name") String name, @RequestParam("output") String output) { + log.info("Generating full report: " + name + "; format: " + output); + OutputType format = OutputType.from(output); + reportService.generateMainReport(name, format, response, request); + } +} diff --git a/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/dto/OutputType.java b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/dto/OutputType.java new file mode 100644 index 0000000000..3180a347ba --- /dev/null +++ b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/dto/OutputType.java @@ -0,0 +1,21 @@ +package com.baeldung.birt.engine.dto; + +import org.eclipse.birt.report.engine.api.IRenderOption; + +public enum OutputType { + HTML(IRenderOption.OUTPUT_FORMAT_HTML), + PDF(IRenderOption.OUTPUT_FORMAT_PDF), + INVALID("invalid"); + + String val; + OutputType(String val) { + this.val = val; + } + + public static OutputType from(String text) { + for (OutputType output : values()) { + if(output.val.equalsIgnoreCase(text)) return output; + } + return INVALID; + } +} diff --git a/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/dto/Report.java b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/dto/Report.java new file mode 100644 index 0000000000..a2d2444b80 --- /dev/null +++ b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/dto/Report.java @@ -0,0 +1,37 @@ +package com.baeldung.birt.engine.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * Report DTO class + */ +@Data +@NoArgsConstructor +public class Report { + private String title; + private String name; + private List parameters; + + public Report(String title, String name) { + this.title = title; + this.name = name; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Parameter { + private String title; + private String name; + private ParameterType type; + + } + + public enum ParameterType { + INT, STRING + } +} diff --git a/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/service/BirtReportService.java b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/service/BirtReportService.java new file mode 100644 index 0000000000..540bbbb530 --- /dev/null +++ b/spring-boot-mvc-birt/src/main/java/com/baeldung/birt/engine/service/BirtReportService.java @@ -0,0 +1,168 @@ +package com.baeldung.birt.engine.service; + +import com.baeldung.birt.engine.dto.OutputType; +import com.baeldung.birt.engine.dto.Report; +import org.eclipse.birt.core.exception.BirtException; +import org.eclipse.birt.core.framework.Platform; +import org.eclipse.birt.report.engine.api.*; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.io.ResourceLoader; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.util.*; + +@Service +public class BirtReportService implements ApplicationContextAware, DisposableBean { + @Value("${reports.relative.path}") + private String reportsPath; + @Value("${images.relative.path}") + private String imagesPath; + + private HTMLServerImageHandler htmlImageHandler = new HTMLServerImageHandler(); + + @Autowired + private ResourceLoader resourceLoader; + @Autowired + private ServletContext servletContext; + + private IReportEngine birtEngine; + private ApplicationContext context; + private String imageFolder; + + private Map reports = new HashMap<>(); + + @SuppressWarnings("unchecked") + @PostConstruct + protected void initialize() throws BirtException { + EngineConfig config = new EngineConfig(); + config.getAppContext().put("spring", this.context); + Platform.startup(config); + IReportEngineFactory factory = (IReportEngineFactory) Platform + .createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY); + birtEngine = factory.createReportEngine(config); + imageFolder = System.getProperty("user.dir") + File.separatorChar + reportsPath + imagesPath; + loadReports(); + } + + @Override + public void setApplicationContext(ApplicationContext context) { + this.context = context; + } + + /** + * Load report files to memory + * + */ + public void loadReports() throws EngineException { + File folder = new File(reportsPath); + for (String file : Objects.requireNonNull(folder.list())) { + if (!file.endsWith(".rptdesign")) { + continue; + } + + reports.put(file.replace(".rptdesign", ""), + birtEngine.openReportDesign(folder.getAbsolutePath() + File.separator + file)); + + } + } + + public List getReports() { + List response = new ArrayList<>(); + for (Map.Entry entry : reports.entrySet()) { + IReportRunnable report = reports.get(entry.getKey()); + IGetParameterDefinitionTask task = birtEngine.createGetParameterDefinitionTask(report); + Report reportItem = new Report(report.getDesignHandle().getProperty("title").toString(), entry.getKey()); + for (Object h : task.getParameterDefns(false)) { + IParameterDefn def = (IParameterDefn) h; + reportItem.getParameters() + .add(new Report.Parameter(def.getPromptText(), def.getName(), getParameterType(def))); + } + response.add(reportItem); + } + return response; + } + + private Report.ParameterType getParameterType(IParameterDefn param) { + if (IParameterDefn.TYPE_INTEGER == param.getDataType()) { + return Report.ParameterType.INT; + } + return Report.ParameterType.STRING; + } + + public void generateMainReport(String reportName, OutputType output, HttpServletResponse response, HttpServletRequest request) { + switch (output) { + case HTML: + generateHTMLReport(reports.get(reportName), response, request); + break; + case PDF: + generatePDFReport(reports.get(reportName), response, request); + break; + default: + throw new IllegalArgumentException("Output type not recognized:" + output); + } + } + + /** + * Generate a report as HTML + */ + @SuppressWarnings("unchecked") + private void generateHTMLReport(IReportRunnable report, HttpServletResponse response, HttpServletRequest request) { + IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask(report); + response.setContentType(birtEngine.getMIMEType("html")); + IRenderOption options = new RenderOption(); + HTMLRenderOption htmlOptions = new HTMLRenderOption(options); + htmlOptions.setOutputFormat("html"); + htmlOptions.setBaseImageURL("/" + reportsPath + imagesPath); + htmlOptions.setImageDirectory(imageFolder); + htmlOptions.setImageHandler(htmlImageHandler); + runAndRenderTask.setRenderOption(htmlOptions); + runAndRenderTask.getAppContext().put(EngineConstants.APPCONTEXT_BIRT_VIEWER_HTTPSERVET_REQUEST, request); + + try { + htmlOptions.setOutputStream(response.getOutputStream()); + runAndRenderTask.run(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + runAndRenderTask.close(); + } + } + + /** + * Generate a report as PDF + */ + @SuppressWarnings("unchecked") + private void generatePDFReport(IReportRunnable report, HttpServletResponse response, HttpServletRequest request) { + IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask(report); + response.setContentType(birtEngine.getMIMEType("pdf")); + IRenderOption options = new RenderOption(); + PDFRenderOption pdfRenderOption = new PDFRenderOption(options); + pdfRenderOption.setOutputFormat("pdf"); + runAndRenderTask.setRenderOption(pdfRenderOption); + runAndRenderTask.getAppContext().put(EngineConstants.APPCONTEXT_PDF_RENDER_CONTEXT, request); + + try { + pdfRenderOption.setOutputStream(response.getOutputStream()); + runAndRenderTask.run(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + runAndRenderTask.close(); + } + } + + @Override + public void destroy() { + birtEngine.destroy(); + Platform.shutdown(); + } +} diff --git a/spring-boot-mvc-birt/src/main/resources/application.properties b/spring-boot-mvc-birt/src/main/resources/application.properties new file mode 100644 index 0000000000..5b015c70b1 --- /dev/null +++ b/spring-boot-mvc-birt/src/main/resources/application.properties @@ -0,0 +1,2 @@ +reports.relative.path=reports/ +images.relative.path=images/ \ No newline at end of file diff --git a/spring-boot-rest/README.md b/spring-boot-rest/README.md index af372077f0..b28192cf62 100644 --- a/spring-boot-rest/README.md +++ b/spring-boot-rest/README.md @@ -1,13 +1,18 @@ Module for the articles that are part of the Spring REST E-book: 1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration) -2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring) -3. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring) -4. [Build a REST API with Spring and Java Config](http://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration) -5. [HATEOAS for a Spring REST Service](http://www.baeldung.com/rest-api-discoverability-with-spring) -6. [REST API Discoverability and HATEOAS](http://www.baeldung.com/restful-web-service-discoverability) -7. [Versioning a REST API](http://www.baeldung.com/rest-versioning) -8. [Http Message Converters with the Spring Framework](http://www.baeldung.com/spring-httpmessageconverter-rest) -9. [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring) -10. [Testing REST with multiple MIME types](http://www.baeldung.com/testing-rest-api-with-multiple-media-types) -11. [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections) +2. [Build a REST API with Spring and Java Config](http://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration) +3. [Http Message Converters with the Spring Framework](http://www.baeldung.com/spring-httpmessageconverter-rest) +4. [Spring’s RequestBody and ResponseBody Annotations](https://www.baeldung.com/spring-request-response-body) +5. [Entity To DTO Conversion for a Spring REST API](https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application) +6. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring) +7. [REST API Discoverability and HATEOAS](http://www.baeldung.com/restful-web-service-discoverability) +8. [An Intro to Spring HATEOAS](http://www.baeldung.com/spring-hateoas-tutorial) +9. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring) +10. [Test a REST API with Java](http://www.baeldung.com/integration-testing-a-rest-api) + +- [HATEOAS for a Spring REST Service](http://www.baeldung.com/rest-api-discoverability-with-spring) +- [Versioning a REST API](http://www.baeldung.com/rest-versioning) +- [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring) +- [Testing REST with multiple MIME types](http://www.baeldung.com/testing-rest-api-with-multiple-media-types) +- [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections) diff --git a/spring-boot-rest/pom.xml b/spring-boot-rest/pom.xml index decaccd148..598b589ea0 100644 --- a/spring-boot-rest/pom.xml +++ b/spring-boot-rest/pom.xml @@ -44,6 +44,12 @@ org.springframework.boot spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-hateoas + @@ -63,6 +69,11 @@ htmlunit test + + org.modelmapper + modelmapper + ${modelmapper.version} + @@ -78,5 +89,6 @@ com.baeldung.SpringBootRestApplication 27.0.1-jre 1.4.11.1 + 2.3.3 diff --git a/spring-boot-rest/src/main/java/com/baeldung/SpringBootRestApplication.java b/spring-boot-rest/src/main/java/com/baeldung/SpringBootRestApplication.java index 62aae7619d..1c0d0d19e8 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/SpringBootRestApplication.java +++ b/spring-boot-rest/src/main/java/com/baeldung/SpringBootRestApplication.java @@ -1,7 +1,9 @@ package com.baeldung; +import org.modelmapper.ModelMapper; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringBootRestApplication { @@ -9,5 +11,10 @@ public class SpringBootRestApplication { public static void main(String[] args) { SpringApplication.run(SpringBootRestApplication.class, args); } + + @Bean + public ModelMapper modelMapper() { + return new ModelMapper(); + } } diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java similarity index 99% rename from spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java index c0cbca5220..68c17975d4 100644 --- a/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java @@ -21,6 +21,7 @@ import com.baeldung.modelmapper.service.IPostService; import com.baeldung.modelmapper.service.IUserService; @Controller +@RequestMapping("/posts") public class PostRestController { @Autowired diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/dto/PostDto.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/dto/PostDto.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/dto/UserDto.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/dto/UserDto.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/model/Post.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/model/Post.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/model/Preference.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/model/Preference.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/model/User.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/model/User.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/IPostService.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/IPostService.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/IUserService.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/IUserService.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/PostService.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/PostService.java diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java b/spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/UserService.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java rename to spring-boot-rest/src/main/java/com/baeldung/modelmapper/service/UserService.java diff --git a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Customer.java b/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Customer.java similarity index 97% rename from spring-security-rest/src/main/java/org/baeldung/persistence/model/Customer.java rename to spring-boot-rest/src/main/java/com/baeldung/persistence/model/Customer.java index b302ec057a..10da2e10f0 100644 --- a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Customer.java +++ b/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Customer.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package com.baeldung.persistence.model; import java.util.Map; diff --git a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Order.java b/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Order.java similarity index 96% rename from spring-security-rest/src/main/java/org/baeldung/persistence/model/Order.java rename to spring-boot-rest/src/main/java/com/baeldung/persistence/model/Order.java index ca551423e8..7aea9bce5c 100644 --- a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Order.java +++ b/spring-boot-rest/src/main/java/com/baeldung/persistence/model/Order.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package com.baeldung.persistence.model; import org.springframework.hateoas.ResourceSupport; diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerService.java b/spring-boot-rest/src/main/java/com/baeldung/services/CustomerService.java similarity index 64% rename from spring-security-rest/src/main/java/org/baeldung/web/service/CustomerService.java rename to spring-boot-rest/src/main/java/com/baeldung/services/CustomerService.java index da016af2d5..a5e95e693b 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerService.java +++ b/spring-boot-rest/src/main/java/com/baeldung/services/CustomerService.java @@ -1,8 +1,8 @@ -package org.baeldung.web.service; +package com.baeldung.services; import java.util.List; -import org.baeldung.persistence.model.Customer; +import com.baeldung.persistence.model.Customer; public interface CustomerService { diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerServiceImpl.java b/spring-boot-rest/src/main/java/com/baeldung/services/CustomerServiceImpl.java similarity index 92% rename from spring-security-rest/src/main/java/org/baeldung/web/service/CustomerServiceImpl.java rename to spring-boot-rest/src/main/java/com/baeldung/services/CustomerServiceImpl.java index e179de2554..58030483ec 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/service/CustomerServiceImpl.java +++ b/spring-boot-rest/src/main/java/com/baeldung/services/CustomerServiceImpl.java @@ -1,12 +1,13 @@ -package org.baeldung.web.service; +package com.baeldung.services; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.baeldung.persistence.model.Customer; import org.springframework.stereotype.Service; +import com.baeldung.persistence.model.Customer; + @Service public class CustomerServiceImpl implements CustomerService { diff --git a/spring-rest/src/main/java/com/baeldung/services/ExampleService.java b/spring-boot-rest/src/main/java/com/baeldung/services/ExampleService.java similarity index 100% rename from spring-rest/src/main/java/com/baeldung/services/ExampleService.java rename to spring-boot-rest/src/main/java/com/baeldung/services/ExampleService.java diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderService.java b/spring-boot-rest/src/main/java/com/baeldung/services/OrderService.java similarity index 70% rename from spring-security-rest/src/main/java/org/baeldung/web/service/OrderService.java rename to spring-boot-rest/src/main/java/com/baeldung/services/OrderService.java index 9a23488c50..775701e042 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderService.java +++ b/spring-boot-rest/src/main/java/com/baeldung/services/OrderService.java @@ -1,8 +1,8 @@ -package org.baeldung.web.service; +package com.baeldung.services; import java.util.List; -import org.baeldung.persistence.model.Order; +import com.baeldung.persistence.model.Order; public interface OrderService { diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java b/spring-boot-rest/src/main/java/com/baeldung/services/OrderServiceImpl.java similarity index 93% rename from spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java rename to spring-boot-rest/src/main/java/com/baeldung/services/OrderServiceImpl.java index 0a6d4708a1..fffdf88969 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java +++ b/spring-boot-rest/src/main/java/com/baeldung/services/OrderServiceImpl.java @@ -1,14 +1,15 @@ -package org.baeldung.web.service; +package com.baeldung.services; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.baeldung.persistence.model.Customer; -import org.baeldung.persistence.model.Order; import org.springframework.stereotype.Service; +import com.baeldung.persistence.model.Customer; +import com.baeldung.persistence.model.Order; + @Service public class OrderServiceImpl implements OrderService { diff --git a/spring-boot-rest/src/main/java/com/baeldung/spring/PersistenceConfig.java b/spring-boot-rest/src/main/java/com/baeldung/spring/PersistenceConfig.java index 5179c66978..2e967751ad 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/spring/PersistenceConfig.java +++ b/spring-boot-rest/src/main/java/com/baeldung/spring/PersistenceConfig.java @@ -24,8 +24,8 @@ import com.google.common.base.Preconditions; @Configuration @EnableTransactionManagement @PropertySource({ "classpath:persistence-${envTarget:h2}.properties" }) -@ComponentScan({ "com.baeldung.persistence" }) -@EnableJpaRepositories(basePackages = "com.baeldung.persistence.dao") +@ComponentScan(basePackages = { "com.baeldung.persistence", "com.baeldung.modelmapper" }) +@EnableJpaRepositories(basePackages = {"com.baeldung.persistence.dao", "com.baeldung.modelmapper.repository"}) public class PersistenceConfig { @Autowired @@ -39,7 +39,7 @@ public class PersistenceConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); + em.setPackagesToScan(new String[] { "com.baeldung.persistence.model", "com.baeldung.modelmapper.model" }); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); // vendorAdapter.set diff --git a/spring-boot-rest/src/main/java/com/baeldung/transfer/LoginForm.java b/spring-boot-rest/src/main/java/com/baeldung/transfer/LoginForm.java new file mode 100644 index 0000000000..caafcdb500 --- /dev/null +++ b/spring-boot-rest/src/main/java/com/baeldung/transfer/LoginForm.java @@ -0,0 +1,31 @@ +package com.baeldung.transfer; + +public class LoginForm { + private String username; + private String password; + + public LoginForm() { + } + + public LoginForm(String username, String password) { + super(); + this.username = username; + this.password = password; + } + + 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; + } +} \ No newline at end of file diff --git a/spring-rest/src/main/java/com/baeldung/transfer/ResponseTransfer.java b/spring-boot-rest/src/main/java/com/baeldung/transfer/ResponseTransfer.java similarity index 100% rename from spring-rest/src/main/java/com/baeldung/transfer/ResponseTransfer.java rename to spring-boot-rest/src/main/java/com/baeldung/transfer/ResponseTransfer.java diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java b/spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java similarity index 64% rename from spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java rename to spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java index e1db105d18..91aa9f2144 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/controller/CustomerController.java @@ -1,24 +1,25 @@ -package org.baeldung.web.controller; +package com.baeldung.web.controller; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import java.util.List; -import org.baeldung.persistence.model.Customer; -import org.baeldung.persistence.model.Order; -import org.baeldung.web.service.CustomerService; -import org.baeldung.web.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.Link; import org.springframework.hateoas.Resources; import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; +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.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import com.baeldung.persistence.model.Customer; +import com.baeldung.persistence.model.Order; +import com.baeldung.services.CustomerService; +import com.baeldung.services.OrderService; + @RestController @RequestMapping(value = "/customers") @EnableHypermediaSupport(type = HypermediaType.HAL) @@ -29,45 +30,49 @@ public class CustomerController { @Autowired private OrderService orderService; - @RequestMapping(value = "/{customerId}", method = RequestMethod.GET) + @GetMapping("/{customerId}") public Customer getCustomerById(@PathVariable final String customerId) { return customerService.getCustomerDetail(customerId); } - @RequestMapping(value = "/{customerId}/{orderId}", method = RequestMethod.GET) + @GetMapping("/{customerId}/{orderId}") public Order getOrderById(@PathVariable final String customerId, @PathVariable final String orderId) { return orderService.getOrderByIdForCustomer(customerId, orderId); } - @RequestMapping(value = "/{customerId}/orders", method = RequestMethod.GET , produces = {"application/hal+json"}) + @GetMapping(value = "/{customerId}/orders", produces = { "application/hal+json" }) public Resources getOrdersForCustomer(@PathVariable final String customerId) { final List orders = orderService.getAllOrdersForCustomer(customerId); for (final Order order : orders) { - final Link selfLink = linkTo(methodOn(CustomerController.class).getOrderById(customerId, order.getOrderId())).withSelfRel(); + final Link selfLink = linkTo( + methodOn(CustomerController.class).getOrderById(customerId, order.getOrderId())).withSelfRel(); order.add(selfLink); } - - Link link =linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withSelfRel(); - Resources result = new Resources<>(orders,link); + + Link link = linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withSelfRel(); + Resources result = new Resources<>(orders, link); return result; } - @RequestMapping(method = RequestMethod.GET, produces = {"application/hal+json"}) + @GetMapping(produces = { "application/hal+json" }) public Resources getAllCustomers() { final List allCustomers = customerService.allCustomers(); - + for (final Customer customer : allCustomers) { String customerId = customer.getCustomerId(); - Link selfLink = linkTo(CustomerController.class).slash(customerId).withSelfRel(); + Link selfLink = linkTo(CustomerController.class).slash(customerId) + .withSelfRel(); customer.add(selfLink); - if (orderService.getAllOrdersForCustomer(customerId).size() > 0) { - final Link ordersLink = linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withRel("allOrders"); + if (orderService.getAllOrdersForCustomer(customerId) + .size() > 0) { + final Link ordersLink = linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)) + .withRel("allOrders"); customer.add(ordersLink); } } - - Link link =linkTo(CustomerController.class).withSelfRel(); - Resources result = new Resources<>(allCustomers,link); + + Link link = linkTo(CustomerController.class).withSelfRel(); + Resources result = new Resources<>(allCustomers, link); return result; } diff --git a/spring-rest/src/main/java/com/baeldung/controllers/ExamplePostController.java b/spring-boot-rest/src/main/java/com/baeldung/web/controller/ExamplePostController.java similarity index 97% rename from spring-rest/src/main/java/com/baeldung/controllers/ExamplePostController.java rename to spring-boot-rest/src/main/java/com/baeldung/web/controller/ExamplePostController.java index 93f96756b4..1519d95d4d 100644 --- a/spring-rest/src/main/java/com/baeldung/controllers/ExamplePostController.java +++ b/spring-boot-rest/src/main/java/com/baeldung/web/controller/ExamplePostController.java @@ -1,4 +1,4 @@ -package com.baeldung.controllers; +package com.baeldung.web.controller; import com.baeldung.services.ExampleService; import com.baeldung.transfer.ResponseTransfer; diff --git a/spring-boot-rest/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/SpringContextIntegrationTest.java index 25fbc4cc02..3db1ecb462 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/SpringContextIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/SpringContextIntegrationTest.java @@ -6,7 +6,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(classes = {SpringBootRestApplication.class}) public class SpringContextIntegrationTest { @Test diff --git a/spring-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java similarity index 92% rename from spring-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java rename to spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java index 94b8bf40e7..fc533072c8 100644 --- a/spring-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerRequestIntegrationTest.java @@ -1,8 +1,10 @@ package com.baeldung.controllers; -import com.baeldung.sampleapp.config.MainApplication; -import com.baeldung.services.ExampleService; -import com.baeldung.transfer.LoginForm; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -14,13 +16,13 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.baeldung.SpringBootRestApplication; +import com.baeldung.services.ExampleService; +import com.baeldung.transfer.LoginForm; +import com.baeldung.web.controller.ExamplePostController; @RunWith(SpringRunner.class) -@SpringBootTest(classes = MainApplication.class) +@SpringBootTest(classes = SpringBootRestApplication.class) public class ExamplePostControllerRequestIntegrationTest { MockMvc mockMvc; diff --git a/spring-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java similarity index 92% rename from spring-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java rename to spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java index 5743ad450b..cbe21b1d90 100644 --- a/spring-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/controllers/ExamplePostControllerResponseIntegrationTest.java @@ -1,8 +1,11 @@ package com.baeldung.controllers; -import com.baeldung.sampleapp.config.MainApplication; -import com.baeldung.services.ExampleService; -import com.baeldung.transfer.LoginForm; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -11,18 +14,16 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; - import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.baeldung.SpringBootRestApplication; +import com.baeldung.services.ExampleService; +import com.baeldung.transfer.LoginForm; +import com.baeldung.web.controller.ExamplePostController; @RunWith(SpringRunner.class) -@SpringBootTest(classes = MainApplication.class) +@SpringBootTest(classes = SpringBootRestApplication.class) public class ExamplePostControllerResponseIntegrationTest { MockMvc mockMvc; diff --git a/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java b/spring-boot-rest/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java similarity index 100% rename from spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java rename to spring-boot-rest/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java diff --git a/spring-boot-rest/src/test/java/com/baeldung/rest/GitHubUser.java b/spring-boot-rest/src/test/java/com/baeldung/rest/GitHubUser.java new file mode 100644 index 0000000000..da5085ab12 --- /dev/null +++ b/spring-boot-rest/src/test/java/com/baeldung/rest/GitHubUser.java @@ -0,0 +1,21 @@ +package com.baeldung.rest; + +public class GitHubUser { + + private String login; + + public GitHubUser() { + super(); + } + + // API + + public String getLogin() { + return login; + } + + public void setLogin(final String login) { + this.login = login; + } + +} diff --git a/testing-modules/rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java similarity index 98% rename from testing-modules/rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java rename to spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java index acac82c8f4..3082b34421 100644 --- a/testing-modules/rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/rest/GithubBasicLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung.rest; +package com.baeldung.rest; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.equalTo; diff --git a/spring-boot-rest/src/test/java/com/baeldung/rest/RetrieveUtil.java b/spring-boot-rest/src/test/java/com/baeldung/rest/RetrieveUtil.java new file mode 100644 index 0000000000..0ec36bc3ae --- /dev/null +++ b/spring-boot-rest/src/test/java/com/baeldung/rest/RetrieveUtil.java @@ -0,0 +1,21 @@ +package com.baeldung.rest; + +import java.io.IOException; + +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class RetrieveUtil { + + // API + + public static T retrieveResourceFromResponse(final HttpResponse response, final Class clazz) throws IOException { + final String jsonFromResponse = EntityUtils.toString(response.getEntity()); + final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper.readValue(jsonFromResponse, clazz); + } + +} diff --git a/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java new file mode 100644 index 0000000000..b08da6d2cd --- /dev/null +++ b/spring-boot-rest/src/test/java/com/baeldung/springhateoas/CustomerControllerIntegrationTest.java @@ -0,0 +1,98 @@ +package com.baeldung.springhateoas; + +import static org.hamcrest.Matchers.is; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.Collections; +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.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.hateoas.MediaTypes; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.persistence.model.Customer; +import com.baeldung.persistence.model.Order; +import com.baeldung.services.CustomerService; +import com.baeldung.services.OrderService; +import com.baeldung.web.controller.CustomerController; + +@RunWith(SpringRunner.class) +@WebMvcTest(CustomerController.class) +public class CustomerControllerIntegrationTest { + + @Autowired + private MockMvc mvc; + + @MockBean + private CustomerService customerService; + + @MockBean + private OrderService orderService; + + private static final String DEFAULT_CUSTOMER_ID = "customer1"; + private static final String DEFAULT_ORDER_ID = "order1"; + + @Test + public void givenExistingCustomer_whenCustomerRequested_thenResourceRetrieved() throws Exception { + given(this.customerService.getCustomerDetail(DEFAULT_CUSTOMER_ID)) + .willReturn(new Customer(DEFAULT_CUSTOMER_ID, "customerJohn", "companyOne")); + + this.mvc.perform(get("/customers/" + DEFAULT_CUSTOMER_ID)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links").doesNotExist()) + .andExpect(jsonPath("$.customerId", is(DEFAULT_CUSTOMER_ID))); + } + + @Test + public void givenExistingOrder_whenOrderRequested_thenResourceRetrieved() throws Exception { + given(this.orderService.getOrderByIdForCustomer(DEFAULT_CUSTOMER_ID, DEFAULT_ORDER_ID)) + .willReturn(new Order(DEFAULT_ORDER_ID, 1., 1)); + + this.mvc.perform(get("/customers/" + DEFAULT_CUSTOMER_ID + "/" + DEFAULT_ORDER_ID)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links").doesNotExist()) + .andExpect(jsonPath("$.orderId", is(DEFAULT_ORDER_ID))); + } + + @Test + public void givenExistingCustomerWithOrders_whenOrdersRequested_thenHalResourceRetrieved() throws Exception { + Order order1 = new Order(DEFAULT_ORDER_ID, 1., 1); + List orders = Collections.singletonList(order1); + given(this.orderService.getAllOrdersForCustomer(DEFAULT_CUSTOMER_ID)).willReturn(orders); + + this.mvc.perform(get("/customers/" + DEFAULT_CUSTOMER_ID + "/orders").accept(MediaTypes.HAL_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.orderList[0]._links.self.href", + is("http://localhost/customers/customer1/order1"))) + .andExpect(jsonPath("$._links.self.href", is("http://localhost/customers/customer1/orders"))); + } + + @Test + public void givenExistingCustomer_whenAllCustomersRequested_thenHalResourceRetrieved() throws Exception { + // customers + Customer retrievedCustomer = new Customer(DEFAULT_CUSTOMER_ID, "customerJohn", "companyOne"); + List customers = Collections.singletonList(retrievedCustomer); + given(this.customerService.allCustomers()).willReturn(customers); + // orders + Order order1 = new Order(DEFAULT_ORDER_ID, 1., 1); + List orders = Collections.singletonList(order1); + given(this.orderService.getAllOrdersForCustomer(DEFAULT_CUSTOMER_ID)).willReturn(orders); + + this.mvc.perform(get("/customers/").accept(MediaTypes.HAL_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect( + jsonPath("$._embedded.customerList[0]._links.self.href", is("http://localhost/customers/customer1"))) + .andExpect(jsonPath("$._embedded.customerList[0]._links.allOrders.href", + is("http://localhost/customers/customer1/orders"))) + .andExpect(jsonPath("$._links.self.href", is("http://localhost/customers"))); + } + +} diff --git a/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java b/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java new file mode 100644 index 0000000000..97f001a9e5 --- /dev/null +++ b/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java @@ -0,0 +1,19 @@ +package com.baeldung.component; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class OtherComponent { + + private static final Logger LOG = LoggerFactory.getLogger(OtherComponent.class); + + public void processData() { + LOG.trace("This is a TRACE log from another package"); + LOG.debug("This is a DEBUG log from another package"); + LOG.info("This is an INFO log from another package"); + LOG.error("This is an ERROR log from another package"); + } + +} diff --git a/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java new file mode 100644 index 0000000000..ed8218c6a3 --- /dev/null +++ b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.testloglevel; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.baeldung.boot.Application; + +@SpringBootApplication(scanBasePackages = {"com.baeldung.testloglevel", "com.baeldung.component"}) +public class TestLogLevelApplication { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java new file mode 100644 index 0000000000..22078562b4 --- /dev/null +++ b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java @@ -0,0 +1,31 @@ +package com.baeldung.testloglevel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.component.OtherComponent; + +@RestController +public class TestLogLevelController { + + private static final Logger LOG = LoggerFactory.getLogger(TestLogLevelController.class); + + @Autowired + private OtherComponent otherComponent; + + @GetMapping("/testLogLevel") + public String testLogLevel() { + LOG.trace("This is a TRACE log"); + LOG.debug("This is a DEBUG log"); + LOG.info("This is an INFO log"); + LOG.error("This is an ERROR log"); + + otherComponent.processData(); + + return "Added some log output to console..."; + } + +} diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java new file mode 100644 index 0000000000..7a1eb4adbe --- /dev/null +++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java @@ -0,0 +1,70 @@ +package com.baeldung.testloglevel; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class) +@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@ActiveProfiles("logback-test2") +public class LogbackMultiProfileTestLogLevelIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String baseUrl = "/testLogLevel"; + + @Test + public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenPrintTraceLogsForOurPackage() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("TRACE"); + } + + @Test + public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenNoTraceLogsForOtherPackages() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputDoesntContainLogForOtherPackages("TRACE"); + } + + @Test + public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenPrintErrorLogs() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("ERROR"); + assertThatOutputContainsLogForOtherPackages("ERROR"); + } + + private void assertThatOutputContainsLogForOurPackage(String level) { + assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*"); + } + + private void assertThatOutputDoesntContainLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level); + } + + private void assertThatOutputContainsLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level); + } + +} diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java new file mode 100644 index 0000000000..af3bafdc2e --- /dev/null +++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java @@ -0,0 +1,70 @@ +package com.baeldung.testloglevel; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class) +@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@ActiveProfiles("logback-test") +public class LogbackTestLogLevelIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String baseUrl = "/testLogLevel"; + + @Test + public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintDebugLogsForOurPackage() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("DEBUG"); + } + + @Test + public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenNoDebugLogsForOtherPackages() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputDoesntContainLogForOtherPackages("DEBUG"); + } + + @Test + public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintErrorLogs() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("ERROR"); + assertThatOutputContainsLogForOtherPackages("ERROR"); + } + + private void assertThatOutputContainsLogForOurPackage(String level) { + assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*"); + } + + private void assertThatOutputDoesntContainLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level); + } + + private void assertThatOutputContainsLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level); + } + +} diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java new file mode 100644 index 0000000000..5609ce6c01 --- /dev/null +++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java @@ -0,0 +1,70 @@ +package com.baeldung.testloglevel; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class) +@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@ActiveProfiles("logging-test") +public class TestLogLevelWithProfileIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String baseUrl = "/testLogLevel"; + + @Test + public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintDebugLogsForOurPackage() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("DEBUG"); + } + + @Test + public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenNoDebugLogsForOtherPackages() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputDoesntContainLogForOtherPackages("DEBUG"); + } + + @Test + public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintInfoLogs() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("INFO"); + assertThatOutputContainsLogForOtherPackages("INFO"); + } + + private void assertThatOutputContainsLogForOurPackage(String level) { + assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*"); + } + + private void assertThatOutputDoesntContainLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level); + } + + private void assertThatOutputContainsLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level); + } + +} diff --git a/spring-boot-testing/src/test/resources/application-logback-test.properties b/spring-boot-testing/src/test/resources/application-logback-test.properties new file mode 100644 index 0000000000..587302fa01 --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-logback-test.properties @@ -0,0 +1 @@ +logging.config=classpath:logback-test.xml diff --git a/spring-boot-testing/src/test/resources/application-logback-test2.properties b/spring-boot-testing/src/test/resources/application-logback-test2.properties new file mode 100644 index 0000000000..aeed46e3ca --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-logback-test2.properties @@ -0,0 +1 @@ +logging.config=classpath:logback-multiprofile.xml \ No newline at end of file diff --git a/spring-boot-testing/src/test/resources/application-logging-test.properties b/spring-boot-testing/src/test/resources/application-logging-test.properties new file mode 100644 index 0000000000..b5adb4cc11 --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-logging-test.properties @@ -0,0 +1,2 @@ +logging.level.com.baeldung.testloglevel=DEBUG +logging.level.root=INFO \ No newline at end of file diff --git a/spring-boot-testing/src/test/resources/logback-multiprofile.xml b/spring-boot-testing/src/test/resources/logback-multiprofile.xml new file mode 100644 index 0000000000..be790234f2 --- /dev/null +++ b/spring-boot-testing/src/test/resources/logback-multiprofile.xml @@ -0,0 +1,18 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + diff --git a/spring-boot-testing/src/test/resources/logback-test.xml b/spring-boot-testing/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..0528aa88f3 --- /dev/null +++ b/spring-boot-testing/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/spring-boot/README.MD b/spring-boot/README.MD index 7d270c9c25..c0392d38de 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -6,12 +6,12 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Guide to Spring in Eclipse STS](http://www.baeldung.com/eclipse-sts-spring) - [The @ServletComponentScan Annotation in Spring Boot](http://www.baeldung.com/spring-servletcomponentscan) - [Intro to Building an Application with Spring Boot](http://www.baeldung.com/intro-to-spring-boot) -- [How to Register a Servlet in a Java Web Application](http://www.baeldung.com/register-servlet) +- [How to Register a Servlet in Java](http://www.baeldung.com/register-servlet) - [Guide to Spring WebUtils and ServletRequestUtils](http://www.baeldung.com/spring-webutils-servletrequestutils) - [Using Custom Banners in Spring Boot](http://www.baeldung.com/spring-boot-custom-banners) - [Guide to Internationalization in Spring Boot](http://www.baeldung.com/spring-boot-internationalization) - [Create a Custom FailureAnalyzer with Spring Boot](http://www.baeldung.com/spring-boot-failure-analyzer) -- [Dynamic DTO Validation Config Retrieved from DB](http://www.baeldung.com/spring-dynamic-dto-validation) +- [Dynamic DTO Validation Config Retrieved from the Database](http://www.baeldung.com/spring-dynamic-dto-validation) - [Custom Information in Spring Boot Info Endpoint](http://www.baeldung.com/spring-boot-info-actuator-custom) - [Using @JsonComponent in Spring Boot](http://www.baeldung.com/spring-boot-jsoncomponent) - [Testing in Spring Boot](http://www.baeldung.com/spring-boot-testing) @@ -21,7 +21,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Getting Started with GraphQL and Spring Boot](http://www.baeldung.com/spring-graphql) - [Guide to Spring Type Conversions](http://www.baeldung.com/spring-type-conversions) - [An Introduction to Kong](http://www.baeldung.com/kong) -- [Spring Boot Customize Whitelabel Error Page](http://www.baeldung.com/spring-boot-custom-error-page) +- [Spring Boot: Customize Whitelabel Error Page](http://www.baeldung.com/spring-boot-custom-error-page) - [Spring Boot: Configuring a Main Class](http://www.baeldung.com/spring-boot-main-class) - [A Quick Intro to the SpringBootServletInitializer](http://www.baeldung.com/spring-boot-servlet-initializer) - [How to Define a Spring Boot Filter?](http://www.baeldung.com/spring-boot-add-filter) @@ -35,5 +35,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Display Auto-Configuration Report in Spring Boot](https://www.baeldung.com/spring-boot-auto-configuration-report) - [Injecting Git Information Into Spring](https://www.baeldung.com/spring-git-information) - [Validation in Spring Boot](https://www.baeldung.com/spring-boot-bean-validation) -- [Entity To DTO Conversion for a Spring REST API](https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application) - [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar) diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index ed2d8259df..401e0289e8 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -153,12 +153,6 @@ javax.validation validation-api - - - org.modelmapper - modelmapper - ${modelmapper.version} - @@ -256,7 +250,6 @@ 5.2.4 18.0 2.2.4 - 2.3.2 diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java b/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java deleted file mode 100644 index 7684c43648..0000000000 --- a/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.modelmapper; - -import org.modelmapper.ModelMapper; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; - -@SpringBootApplication -public class PostApplication { - - public static void main(String[] args) { - SpringApplication.run(PostApplication.class, args); - } - - @Bean - public ModelMapper modelMapper() { - return new ModelMapper(); - } - -} diff --git a/spring-boot/src/main/java/org/baeldung/properties/ConfigProperties.java b/spring-boot/src/main/java/org/baeldung/properties/ConfigProperties.java index 3698d8ef30..1a3c985fe4 100644 --- a/spring-boot/src/main/java/org/baeldung/properties/ConfigProperties.java +++ b/spring-boot/src/main/java/org/baeldung/properties/ConfigProperties.java @@ -9,6 +9,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.Pattern; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.validation.annotation.Validated; @@ -80,4 +81,10 @@ public class ConfigProperties { public void setCredentials(Credentials credentials) { this.credentials = credentials; } + + @Bean + @ConfigurationProperties(prefix = "item") + public Item item(){ + return new Item(); + } } diff --git a/spring-boot/src/main/java/org/baeldung/properties/Item.java b/spring-boot/src/main/java/org/baeldung/properties/Item.java new file mode 100644 index 0000000000..0314654ada --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/Item.java @@ -0,0 +1,31 @@ +package org.baeldung.properties; + +public class Item { + + private String name; + private int size; + + public Item() { + } + + public Item(String name, int size) { + this.name = name; + this.size = size; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } +} diff --git a/spring-boot/src/main/resources/configprops.properties b/spring-boot/src/main/resources/configprops.properties index 2dad11f9cc..424b3632f9 100644 --- a/spring-boot/src/main/resources/configprops.properties +++ b/spring-boot/src/main/resources/configprops.properties @@ -17,4 +17,8 @@ mail.credentials.username=john mail.credentials.password=password mail.credentials.authMethod=SHA1 +#Bean method properties +item.name=Item name +item.size=42 + diff --git a/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java index 4ba6bf29d8..f864fd4f8c 100644 --- a/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java @@ -53,4 +53,11 @@ public class ConfigPropertiesIntegrationTest { Assert.assertEquals("Incorrectly bound object property, username", "john", credentials.getUsername()); Assert.assertEquals("Incorrectly bound object property, password", "password", credentials.getPassword()); } + + @Test + public void whenBeanMethodAnnotatedThenPropertiesCorrectlyBound(){ + Item item = properties.item(); + Assert.assertEquals("Incorrectly bound object property, item.name","Test item name", item.getName()); + Assert.assertEquals("Incorrectly bound object property, item.size", 21, item.getSize()); + } } diff --git a/spring-boot/src/test/resources/configprops-test.properties b/spring-boot/src/test/resources/configprops-test.properties index 697771ae6e..ea11f2159e 100644 --- a/spring-boot/src/test/resources/configprops-test.properties +++ b/spring-boot/src/test/resources/configprops-test.properties @@ -17,3 +17,6 @@ mail.credentials.username=john mail.credentials.password=password mail.credentials.authMethod=SHA1 +#Bean method properties +item.name=Test item name +item.size=21 diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index bf70e0284c..baf86a4386 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -32,7 +32,6 @@ spring-cloud-zuul-eureka-integration spring-cloud-contract spring-cloud-kubernetes - spring-cloud-kubernetes-2 spring-cloud-archaius spring-cloud-functions spring-cloud-vault diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java index 2948606c0b..d49a8dfa7e 100644 --- a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java @@ -5,21 +5,18 @@ import static org.assertj.core.api.Assertions.assertThat; import java.util.Collections; import org.junit.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit4.SpringRunner; import com.netflix.config.DynamicPropertyFactory; import com.netflix.config.DynamicStringProperty; -@RunWith(JUnitPlatform.class) -@ExtendWith(SpringExtension.class) +@RunWith(SpringRunner.class) @SpringBootTest public class ArchaiusBasicConfigurationIntegrationTest { diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/SpringContextLiveTest.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/SpringContextLiveTest.java new file mode 100644 index 0000000000..a1a6c46c60 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/SpringContextLiveTest.java @@ -0,0 +1,20 @@ +package com.baeldung.spring.cloud.archaius.dynamosources; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * To run this Live Test we need to: + * * start a dynamodb instance locally on port 8000(e.g. with the following command `docker run -p 8000:8000 --name bael-dynamodb amazon/dynamodb-local`) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = DynamoSourcesApplication.class) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..b3cd01e684 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = JdbcSourcesApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/SpringContextLiveTest.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/SpringContextLiveTest.java new file mode 100644 index 0000000000..a827b8e27d --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/SpringContextLiveTest.java @@ -0,0 +1,20 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * This Live tTest requires: + * * A Zookeeper instance running locally on port 2181 (e.g. using `docker run --name bael-zookeeper -p 2181:2181 --restart always zookeeper`) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ZookeeperConfigApplication.class) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/README.md b/spring-cloud/spring-cloud-aws/README.md index 36d0c7080e..3b7b4dbcd7 100644 --- a/spring-cloud/spring-cloud-aws/README.md +++ b/spring-cloud/spring-cloud-aws/README.md @@ -8,7 +8,7 @@ #### Running the Integration Tests -To run the Integration Tests, we need to have an AWS account and have API keys generated for programmatic access. Edit +To run the Live Tests, we need to have an AWS account and have API keys generated for programmatic access. Edit the `application.properties` file to add the following properties: ``` diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringContextLiveTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringContextLiveTest.java new file mode 100644 index 0000000000..90ad9c518c --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringContextLiveTest.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.aws; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * + * To run this Live Test, we need to have an AWS account and have API keys generated for programmatic access. + * + * Check the README file in this module for more information. + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringCloudAwsApplication.class) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataLiveTest.java similarity index 86% rename from spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java rename to spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataLiveTest.java index 1e75134194..853777ed25 100644 --- a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataLiveTest.java @@ -16,12 +16,19 @@ import org.springframework.test.context.junit4.SpringRunner; import com.amazonaws.regions.Regions; import com.amazonaws.services.ec2.AmazonEC2; +/** + * + * To run this Live Test, we need to have an AWS account and have API keys generated for programmatic access. + * + * Check the README file in this module for more information. + * + */ @SpringBootTest @RunWith(SpringRunner.class) @TestPropertySource("classpath:application-test.properties") -public class EC2MetadataIntegrationTest { +public class EC2MetadataLiveTest { - private static final Logger logger = LoggerFactory.getLogger(EC2MetadataIntegrationTest.class); + private static final Logger logger = LoggerFactory.getLogger(EC2MetadataLiveTest.class); private boolean serverEc2; diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSLiveTest.java similarity index 85% rename from spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java rename to spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSLiveTest.java index 9e163d6dc4..e7004c6b9f 100644 --- a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSLiveTest.java @@ -14,9 +14,16 @@ import java.sql.Statement; import static org.assertj.core.api.Assertions.assertThat; +/** + * + * To run this Live Test, we need to have an AWS account and have API keys generated for programmatic access. + * + * Check the README file in this module for more information. + * + */ @SpringBootTest @RunWith(SpringRunner.class) -public class SpringCloudRDSIntegrationTest { +public class SpringCloudRDSLiveTest { @Autowired DataSource dataSource; diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3LiveTest.java similarity index 94% rename from spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java rename to spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3LiveTest.java index a866287dec..dff3a06fe0 100644 --- a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3LiveTest.java @@ -23,10 +23,17 @@ import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +/** + * + * To run this Live Test, we need to have an AWS account and have API keys generated for programmatic access. + * + * Check the README file in this module for more information. + * + */ @SpringBootTest @RunWith(SpringRunner.class) @TestPropertySource("classpath:application-test.properties") -public class SpringCloudS3IntegrationTest { +public class SpringCloudS3LiveTest { @Autowired private SpringCloudS3 springCloudS3; diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSLiveTest.java similarity index 88% rename from spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java rename to spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSLiveTest.java index e1f23d5c76..b773520089 100644 --- a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSLiveTest.java @@ -16,10 +16,17 @@ import com.amazonaws.services.sns.model.CreateTopicResult; import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; import com.baeldung.spring.cloud.aws.sqs.Greeting; +/** + * + * To run this Live Test, we need to have an AWS account and have API keys generated for programmatic access. + * + * Check the README file in this module for more information. + * + */ @SpringBootTest @RunWith(SpringRunner.class) @TestPropertySource("classpath:application-test.properties") -public class SpringCloudSNSIntegrationTest { +public class SpringCloudSNSLiveTest { @Autowired private SNSMessageSender snsMessageSender; diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSLiveTest.java similarity index 95% rename from spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java rename to spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSLiveTest.java index 76d2fd7c0d..24917e52f1 100644 --- a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSLiveTest.java @@ -26,12 +26,19 @@ import java.util.concurrent.CountDownLatch; import static org.assertj.core.api.Assertions.assertThat; +/** + * + * To run this Live Test, we need to have an AWS account and have API keys generated for programmatic access. + * + * Check the README file in this module for more information. + * + */ @SpringBootTest @RunWith(SpringRunner.class) @TestPropertySource("classpath:application-test.properties") -public class SpringCloudSQSIntegrationTest { +public class SpringCloudSQSLiveTest { - private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQSIntegrationTest.class); + private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQSLiveTest.class); @Autowired @Lazy diff --git a/spring-cloud/spring-cloud-bootstrap/README.MD b/spring-cloud/spring-cloud-bootstrap/README.MD index 5185200469..7a3a94c8e3 100644 --- a/spring-cloud/spring-cloud-bootstrap/README.MD +++ b/spring-cloud/spring-cloud-bootstrap/README.MD @@ -6,7 +6,7 @@ - [Spring Cloud – Adding Angular 4](http://www.baeldung.com/spring-cloud-angular) - To run the project: - - copy the appliction-config folder to c:\Users\{username}\ on Windows or /Users/{username}/ on *nix. Then open a git bash terminal in application-config and run: + - copy the appliction-config folder to c:\Users\{username}\ on Windows or /home/{username}/ on *nix. Then open a git bash terminal in application-config and run: - git init - git add . - git commit -m "First commit" diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 70% rename from spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextLiveTest.java index 1e2db33395..e4e2e95e04 100644 --- a/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -7,9 +7,15 @@ import org.springframework.test.context.junit4.SpringRunner; import com.baeldung.spring.cloud.bootstrap.discovery.DiscoveryApplication; +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ @RunWith(SpringRunner.class) @SpringBootTest(classes = DiscoveryApplication.class) -public class SpringContextIntegrationTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml index 2efa926e3a..4f9c60a26a 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml @@ -98,6 +98,6 @@ - Brixton.SR7 + Dalston.RELEASE \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java index 10ed66bfd4..79785a3f20 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java @@ -71,7 +71,7 @@ public class GatewayApplication { InstanceInfo instance = eurekaClient.getNextServerFromEureka("zipkin", false); if (!(baseUrl != null && instance.getHomePageUrl().equals(baseUrl))) { baseUrl = instance.getHomePageUrl(); - delegate = new HttpZipkinSpanReporter(baseUrl, zipkinProperties.getFlushInterval(), zipkinProperties.getCompression().isEnabled(), spanMetricReporter); + delegate = new HttpZipkinSpanReporter(new RestTemplate(), baseUrl, zipkinProperties.getFlushInterval(), spanMetricReporter); if (!span.name.matches(skipPattern)) delegate.report(span); } if (!span.name.matches(skipPattern)) delegate.report(span); diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 70% rename from spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextLiveTest.java index ef3bb5ef95..e0342cf82c 100644 --- a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -7,9 +7,15 @@ import org.springframework.test.context.junit4.SpringRunner; import com.baeldung.spring.cloud.bootstrap.gateway.GatewayApplication; +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ @RunWith(SpringRunner.class) @SpringBootTest(classes = GatewayApplication.class) -public class SpringContextIntegrationTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/resources/bootstrap.properties new file mode 100644 index 0000000000..c76df21ff1 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/resources/bootstrap.properties @@ -0,0 +1,2 @@ +# This property would be provided by the config service in a real-case scenario +spring.sleuth.web.skipPattern=(^cleanup.|.+favicon.) \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml b/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml index eb855a91e3..a88b77dda0 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml @@ -72,7 +72,7 @@ - Brixton.SR7 + Dalston.RELEASE \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java index 3d55a59dbc..91fd23e32d 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java @@ -12,6 +12,8 @@ import org.springframework.cloud.sleuth.zipkin.HttpZipkinSpanReporter; import org.springframework.cloud.sleuth.zipkin.ZipkinProperties; import org.springframework.cloud.sleuth.zipkin.ZipkinSpanReporter; import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; + import zipkin.Span; @SpringBootApplication @@ -42,7 +44,7 @@ public class BookServiceApplication { InstanceInfo instance = eurekaClient.getNextServerFromEureka("zipkin", false); if (!(baseUrl != null && instance.getHomePageUrl().equals(baseUrl))) { baseUrl = instance.getHomePageUrl(); - delegate = new HttpZipkinSpanReporter(baseUrl, zipkinProperties.getFlushInterval(), zipkinProperties.getCompression().isEnabled(), spanMetricReporter); + delegate = new HttpZipkinSpanReporter(new RestTemplate(), baseUrl, zipkinProperties.getFlushInterval(), spanMetricReporter); if (!span.name.matches(skipPattern)) delegate.report(span); } } diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 70% rename from spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextLiveTest.java index 0ffc2410e3..2e437aa3f7 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -7,9 +7,15 @@ import org.springframework.test.context.junit4.SpringRunner; import com.baeldung.spring.cloud.bootstrap.svcbook.BookServiceApplication; +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ @RunWith(SpringRunner.class) @SpringBootTest(classes = BookServiceApplication.class) -public class SpringContextIntegrationTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties new file mode 100644 index 0000000000..c76df21ff1 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/resources/bootstrap.properties @@ -0,0 +1,2 @@ +# This property would be provided by the config service in a real-case scenario +spring.sleuth.web.skipPattern=(^cleanup.|.+favicon.) \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml b/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml index 7c1e93bad1..f0b19922d8 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml @@ -81,7 +81,7 @@ - Brixton.SR7 + Dalston.RELEASE \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java index 31ca69c139..8dacbaa79d 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java @@ -16,6 +16,7 @@ import org.springframework.context.annotation.Primary; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.client.RestTemplate; import com.netflix.appinfo.InstanceInfo; import com.netflix.discovery.EurekaClient; @@ -52,7 +53,7 @@ public class RatingServiceApplication { InstanceInfo instance = eurekaClient.getNextServerFromEureka("zipkin", false); if (!(baseUrl != null && instance.getHomePageUrl().equals(baseUrl))) { baseUrl = instance.getHomePageUrl(); - delegate = new HttpZipkinSpanReporter(baseUrl, zipkinProperties.getFlushInterval(), zipkinProperties.getCompression().isEnabled(), spanMetricReporter); + delegate = new HttpZipkinSpanReporter(new RestTemplate(), baseUrl, zipkinProperties.getFlushInterval(), spanMetricReporter); if (!span.name.matches(skipPattern)) delegate.report(span); } if (!span.name.matches(skipPattern)) delegate.report(span); diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextLiveTest.java similarity index 70% rename from spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextLiveTest.java index 3589666f17..e2921f0308 100644 --- a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -7,9 +7,16 @@ import org.springframework.test.context.junit4.SpringRunner; import com.baeldung.spring.cloud.bootstrap.svcrating.RatingServiceApplication; + +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ @RunWith(SpringRunner.class) @SpringBootTest(classes = RatingServiceApplication.class) -public class SpringContextIntegrationTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties new file mode 100644 index 0000000000..c76df21ff1 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/resources/bootstrap.properties @@ -0,0 +1,2 @@ +# This property would be provided by the config service in a real-case scenario +spring.sleuth.web.skipPattern=(^cleanup.|.+favicon.) \ No newline at end of file diff --git a/spring-cloud/spring-cloud-config/client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-config/client/src/test/java/com/baeldung/spring/cloud/config/client/SpringContextLiveTest.java similarity index 69% rename from spring-cloud/spring-cloud-config/client/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-config/client/src/test/java/com/baeldung/spring/cloud/config/client/SpringContextLiveTest.java index d727772cf9..3fb43b169d 100644 --- a/spring-cloud/spring-cloud-config/client/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-config/client/src/test/java/com/baeldung/spring/cloud/config/client/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung.spring.cloud.config.client; import org.junit.Test; import org.junit.runner.RunWith; @@ -6,12 +6,15 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; -import com.baeldung.spring.cloud.config.client.ConfigClient; - +/** + * + * The app needs the server running on port 8888. Can be started with docker + * + */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = ConfigClient.class) @WebAppConfiguration -public class SpringContextIntegrationTest { +public class SpringContextLiveTest { @Test public void contextLoads() { } diff --git a/spring-cloud/spring-cloud-config/server/src/test/java/com/baeldung/spring/cloud/config/server/SpringContextLiveTest.java b/spring-cloud/spring-cloud-config/server/src/test/java/com/baeldung/spring/cloud/config/server/SpringContextIntegrationTest.java similarity index 79% rename from spring-cloud/spring-cloud-config/server/src/test/java/com/baeldung/spring/cloud/config/server/SpringContextLiveTest.java rename to spring-cloud/spring-cloud-config/server/src/test/java/com/baeldung/spring/cloud/config/server/SpringContextIntegrationTest.java index 793b4abb6c..b2c6ef85ea 100644 --- a/spring-cloud/spring-cloud-config/server/src/test/java/com/baeldung/spring/cloud/config/server/SpringContextLiveTest.java +++ b/spring-cloud/spring-cloud-config/server/src/test/java/com/baeldung/spring/cloud/config/server/SpringContextIntegrationTest.java @@ -6,16 +6,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; - -/** - * - * The context will load successfully with some properties provided by docker - * - */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = ConfigServer.class) @WebAppConfiguration -public class SpringContextLiveTest { +public class SpringContextIntegrationTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { } diff --git a/spring-cloud/spring-cloud-config/server/src/test/resources/application.properties b/spring-cloud/spring-cloud-config/server/src/test/resources/application.properties new file mode 100644 index 0000000000..67cc81ff67 --- /dev/null +++ b/spring-cloud/spring-cloud-config/server/src/test/resources/application.properties @@ -0,0 +1,2 @@ +### This should be provided by the docker config +spring.cloud.config.server.git.uri=classpath:. diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties b/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties index d2f1c89dc5..571f325824 100644 --- a/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties @@ -4,5 +4,6 @@ spring.datasource.maxIdle=5 spring.datasource.minIdle=2 spring.datasource.initialSize=5 spring.datasource.removeAbandoned=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=update \ No newline at end of file diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-connectors-heroku/src/test/java/com/baeldung/spring/cloud/connectors/heroku/SpringContextIntegrationTest.java similarity index 90% rename from spring-cloud/spring-cloud-connectors-heroku/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-connectors-heroku/src/test/java/com/baeldung/spring/cloud/connectors/heroku/SpringContextIntegrationTest.java index a705f18bc6..dca4c25c71 100644 --- a/spring-cloud/spring-cloud-connectors-heroku/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-connectors-heroku/src/test/java/com/baeldung/spring/cloud/connectors/heroku/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung.spring.cloud.connectors.heroku; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/test/resources/application.properties b/spring-cloud/spring-cloud-connectors-heroku/src/test/resources/application.properties new file mode 100644 index 0000000000..7b139ae07d --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/test/resources/application.properties @@ -0,0 +1,2 @@ +spring.jpa.hibernate.ddl-auto=create +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-consul/src/test/java/com/baeldung/spring/cloud/consul/SpringContextLiveTest.java similarity index 74% rename from spring-cloud/spring-cloud-consul/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-consul/src/test/java/com/baeldung/spring/cloud/consul/SpringContextLiveTest.java index 6290ccc03e..7c87add43e 100644 --- a/spring-cloud/spring-cloud-consul/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-consul/src/test/java/com/baeldung/spring/cloud/consul/SpringContextLiveTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung.spring.cloud.consul; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,10 +9,18 @@ import com.baeldung.spring.cloud.consul.discovery.DiscoveryClientApplication; import com.baeldung.spring.cloud.consul.health.ServiceDiscoveryApplication; import com.baeldung.spring.cloud.consul.properties.DistributedPropertiesApplication; + +/** + * + * This Live test requires: + * * a Consul instance running on port 8500 + * * Consul configured with particular properties (e.g. 'my.prop') + * + */ @RunWith(SpringRunner.class) @SpringBootTest(classes = { DiscoveryClientApplication.class, ServiceDiscoveryApplication.class, DistributedPropertiesApplication.class }) -public class SpringContextIntegrationTest { +public class SpringContextLiveTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { diff --git a/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..beee84246d --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.cloudfunction.aws; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = CloudFunctionAwsApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes-2/pom.xml b/spring-cloud/spring-cloud-kubernetes-2/pom.xml deleted file mode 100644 index c5681e8e7d..0000000000 --- a/spring-cloud/spring-cloud-kubernetes-2/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - com.baeldung.spring.cloud - spring-cloud-kubernetes-2 - 1.0-SNAPSHOT - spring-cloud-kubernetes-2 - pom - - - client-service - travel-agency-service - - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - - 2.0.6.RELEASE - - - diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/travel-agency-config.yaml b/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/travel-agency-config.yaml deleted file mode 100644 index 93a67e3777..0000000000 --- a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/travel-agency-config.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: travel-agency-service -data: - application.properties: |- - bean.message=Testing reload ! Message from backend is: %s
Services : %s - diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/.gitignore b/spring-cloud/spring-cloud-kubernetes/client-service/.gitignore similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/.gitignore rename to spring-cloud/spring-cloud-kubernetes/client-service/.gitignore diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/Dockerfile b/spring-cloud/spring-cloud-kubernetes/client-service/Dockerfile similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/Dockerfile rename to spring-cloud/spring-cloud-kubernetes/client-service/Dockerfile diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/client-config.yaml b/spring-cloud/spring-cloud-kubernetes/client-service/client-config.yaml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/client-config.yaml rename to spring-cloud/spring-cloud-kubernetes/client-service/client-config.yaml diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/client-service-deployment.yaml b/spring-cloud/spring-cloud-kubernetes/client-service/client-service-deployment.yaml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/client-service-deployment.yaml rename to spring-cloud/spring-cloud-kubernetes/client-service/client-service-deployment.yaml diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/pom.xml b/spring-cloud/spring-cloud-kubernetes/client-service/pom.xml similarity index 97% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/pom.xml rename to spring-cloud/spring-cloud-kubernetes/client-service/pom.xml index 718e445e0c..a4de796ee3 100644 --- a/spring-cloud/spring-cloud-kubernetes-2/client-service/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/client-service/pom.xml @@ -3,12 +3,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 client-service - client-service + client-service 1.0-SNAPSHOT com.baeldung.spring.cloud - spring-cloud-kubernetes-2 + spring-cloud-kubernetes 1.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/Application.java b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/Application.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/Application.java rename to spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/Application.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientConfig.java b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientConfig.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientConfig.java rename to spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientConfig.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientController.java b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientController.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientController.java rename to spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/ClientController.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/RibbonConfiguration.java b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/RibbonConfiguration.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/RibbonConfiguration.java rename to spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/RibbonConfiguration.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/TravelAgencyService.java b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/TravelAgencyService.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/TravelAgencyService.java rename to spring-cloud/spring-cloud-kubernetes/client-service/src/main/java/com/baeldung/spring/cloud/kubernetes/client/TravelAgencyService.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/resources/application.yaml b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/resources/application.yaml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/main/resources/application.yaml rename to spring-cloud/spring-cloud-kubernetes/client-service/src/main/resources/application.yaml diff --git a/spring-cloud/spring-cloud-kubernetes/client-service/src/main/resources/logback.xml b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/client-service/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes-2/client-service/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-kubernetes/client-service/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/client-service/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-kubernetes/client-service/src/test/java/org/baeldung/SpringContextIntegrationTest.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/deployment-all.sh b/spring-cloud/spring-cloud-kubernetes/deployment-travel-client.sh similarity index 72% rename from spring-cloud/spring-cloud-kubernetes-2/deployment-all.sh rename to spring-cloud/spring-cloud-kubernetes/deployment-travel-client.sh index 9c088b7422..90f92f31a6 100755 --- a/spring-cloud/spring-cloud-kubernetes-2/deployment-all.sh +++ b/spring-cloud/spring-cloud-kubernetes/deployment-travel-client.sh @@ -1,9 +1,9 @@ -### build the repository -mvn clean install - ### set docker env eval $(minikube docker-env) +### build the repository +#mvn clean install + ### build the docker images on minikube cd travel-agency-service docker build -t travel-agency-service . @@ -12,11 +12,11 @@ docker build -t client-service . cd .. ### secret and mongodb -kubectl delete -f secret.yaml -kubectl delete -f mongo-deployment.yaml +kubectl delete -f travel-agency-service/secret.yaml +kubectl delete -f travel-agency-service/mongo-deployment.yaml -kubectl create -f secret.yaml -kubectl create -f mongo-deployment.yaml +kubectl create -f travel-agency-service/secret.yaml +kubectl create -f travel-agency-service/mongo-deployment.yaml ### travel-agency-service kubectl delete -f travel-agency-service/travel-agency-deployment.yaml @@ -31,4 +31,4 @@ kubectl create -f client-service/client-config.yaml kubectl create -f client-service/client-service-deployment.yaml # Check that the pods are running -kubectl get pods \ No newline at end of file +kubectl get pods diff --git a/spring-cloud/spring-cloud-kubernetes/pom.xml b/spring-cloud/spring-cloud-kubernetes/pom.xml index b3c59b7127..a9563fc582 100644 --- a/spring-cloud/spring-cloud-kubernetes/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/pom.xml @@ -20,6 +20,8 @@ demo-backend liveness-example readiness-example + client-service + travel-agency-service \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/Dockerfile b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/Dockerfile similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/Dockerfile rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/Dockerfile diff --git a/spring-cloud/spring-cloud-kubernetes-2/mongo-deployment.yaml b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/mongo-deployment.yaml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/mongo-deployment.yaml rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/mongo-deployment.yaml diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/pom.xml b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/pom.xml similarity index 97% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/pom.xml rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/pom.xml index fd5aa5f9d6..19eea2612c 100755 --- a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/pom.xml @@ -6,7 +6,7 @@ com.baeldung.spring.cloud - spring-cloud-kubernetes-2 + spring-cloud-kubernetes 1.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-kubernetes-2/secret.yaml b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/secret.yaml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/secret.yaml rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/secret.yaml diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/Application.java b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/Application.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/Application.java rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/Application.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/controller/TravelAgencyController.java b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/controller/TravelAgencyController.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/controller/TravelAgencyController.java rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/controller/TravelAgencyController.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/model/TravelDeal.java b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/model/TravelDeal.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/model/TravelDeal.java rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/model/TravelDeal.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/repository/TravelDealRepository.java b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/repository/TravelDealRepository.java similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/repository/TravelDealRepository.java rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/java/com/baeldung/spring/cloud/kubernetes/travelagency/repository/TravelDealRepository.java diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/resources/application.properties b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/resources/application.properties similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/resources/application.properties rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/resources/application.properties diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/resources/logback-spring.xml b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/resources/logback-spring.xml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/resources/logback-spring.xml rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/resources/logback-spring.xml diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/resources/logback.xml b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/resources/logback.xml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/src/main/resources/logback.xml rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/main/resources/logback.xml diff --git a/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/test/java/com/baeldung/spring/cloud/kubernetes/travelagency/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/test/java/com/baeldung/spring/cloud/kubernetes/travelagency/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2f901d39f6 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/src/test/java/com/baeldung/spring/cloud/kubernetes/travelagency/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.kubernetes.travelagency; + + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/travel-agency-deployment.yaml b/spring-cloud/spring-cloud-kubernetes/travel-agency-service/travel-agency-deployment.yaml similarity index 100% rename from spring-cloud/spring-cloud-kubernetes-2/travel-agency-service/travel-agency-deployment.yaml rename to spring-cloud/spring-cloud-kubernetes/travel-agency-service/travel-agency-deployment.yaml diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/SpringContextIntegrationTest.java similarity index 77% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/SpringContextIntegrationTest.java index 24e758ff82..77d294093c 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/SpringContextIntegrationTest.java @@ -1,4 +1,5 @@ -package org.baeldung; +package com.baeldung.cloud.openfeign; + import org.junit.Test; import org.junit.runner.RunWith; @@ -6,10 +7,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = BooksApiApplication.class) +@SpringBootTest(classes = ExampleApplication.class) public class SpringContextIntegrationTest { - + @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { } -} +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextLiveTest.java new file mode 100644 index 0000000000..eb56c16c6a --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -0,0 +1,21 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BooksApiApplication.class) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextLiveTest.java new file mode 100644 index 0000000000..01266a3bda --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -0,0 +1,21 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringCloudRestServerApplication.class) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextLiveTest.java new file mode 100644 index 0000000000..070abd246f --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -0,0 +1,21 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * + * This Live Test requires: + * * A Redis instance running in port 6379 (e.g. using `docker run --name some-redis -p 6379:6379 -d redis`) + * + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BookReviewsApiApplication.class) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/com/baeldung/twitterhdfs/aggregate/SpringContextIntegrationTest.java similarity index 79% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/com/baeldung/twitterhdfs/aggregate/SpringContextIntegrationTest.java index 07d7db0505..b5cef1b5ed 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/com/baeldung/twitterhdfs/aggregate/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package com.baeldung.twitterhdfs.aggregate; import org.junit.Test; import org.junit.runner.RunWith; @@ -6,7 +6,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = BookReviewsApiApplication.class) +@SpringBootTest(classes = AggregateApp.class) public class SpringContextIntegrationTest { @Test diff --git a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 3d370e7b48..0000000000 --- a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import com.baeldung.twitterhdfs.aggregate.AggregateApp; -import com.baeldung.twitterhdfs.processor.ProcessorApp; -import com.baeldung.twitterhdfs.sink.SinkApp; -import com.baeldung.twitterhdfs.source.SourceApp; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = {AggregateApp.class, ProcessorApp.class, SinkApp.class, SourceApp.class}) -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/application.yml b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/application.yml index 1187c12fe7..71275793ec 100644 --- a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/application.yml @@ -3,11 +3,11 @@ logging: org: springframework: cloud: - task=DEBUG + task: DEBUG spring: application: - name=helloWorld + name: helloWorld datasource: url: jdbc:mysql://localhost:3306/springcloud?useSSL=false username: root diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextIntegrationTest.java deleted file mode 100644 index 4b5aff2db8..0000000000 --- a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.baeldung.task.JobConfiguration; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = JobConfiguration.class) -public class SpringContextIntegrationTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextLiveTest.java b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextLiveTest.java new file mode 100644 index 0000000000..ddbcbf65ea --- /dev/null +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextLiveTest.java @@ -0,0 +1,29 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.task.JobConfiguration; +import com.baeldung.task.TaskDemo; + +/** + * This Live Test requires: + * * a MySql instance running, that allows a root user with no password, and with a database named + * + * (e.g. with the following command `docker run -p 3306:3306 --name bael-mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true -e MYSQL_DATABASE=springcloud mysql:latest`) + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootApplication +@ContextConfiguration(classes = { JobConfiguration.class, TaskDemo.class }, initializers = { + ConfigFileApplicationContextInitializer.class }) +public class SpringContextLiveTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextIntegrationTest.java similarity index 76% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextIntegrationTest.java index e22359a016..e1eb2f8e24 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung; +package org.baeldung.spring.cloud.vaultsample; import org.junit.Test; import org.junit.runner.RunWith; @@ -6,10 +6,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringCloudRestServerApplication.class) +@SpringBootTest(classes = VaultSampleApplication.class) public class SpringContextIntegrationTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { } -} +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml b/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml index 262b059544..0da0f7503e 100644 --- a/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml +++ b/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml @@ -34,6 +34,12 @@ + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-zookeeper/HelloWorld/src/test/java/com/baeldung/spring/cloud/helloworld/SpringContextIntegrationTest.java similarity index 76% rename from spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-zookeeper/HelloWorld/src/test/java/com/baeldung/spring/cloud/helloworld/SpringContextIntegrationTest.java index e0026ce441..2770649aa3 100644 --- a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-zookeeper/HelloWorld/src/test/java/com/baeldung/spring/cloud/helloworld/SpringContextIntegrationTest.java @@ -1,4 +1,5 @@ -package com.baeldung.spring.cloud.aws; +package com.baeldung.spring.cloud.helloworld; + import org.junit.Test; import org.junit.runner.RunWith; @@ -6,10 +7,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringCloudAwsApplication.class) +@SpringBootTest(classes = HelloWorldApplication.class) public class SpringContextIntegrationTest { - + @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { } -} +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zookeeper/README.md b/spring-cloud/spring-cloud-zookeeper/README.md index a639833452..a49a448833 100644 --- a/spring-cloud/spring-cloud-zookeeper/README.md +++ b/spring-cloud/spring-cloud-zookeeper/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [An Introduction to Spring Cloud Zookeeper](http://www.baeldung.com/spring-cloud-zookeeper) +- [An Intro to Spring Cloud Zookeeper](http://www.baeldung.com/spring-cloud-zookeeper) diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-zuul/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/SpringContextIntegrationTest.java similarity index 62% rename from spring-cloud/spring-cloud-bootstrap/discovery/java/org/baeldung/SpringContextIntegrationTest.java rename to spring-cloud/spring-cloud-zuul/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/SpringContextIntegrationTest.java index 6016788eab..dbcdbdd434 100644 --- a/spring-cloud/spring-cloud-bootstrap/discovery/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-cloud/spring-cloud-zuul/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/SpringContextIntegrationTest.java @@ -1,17 +1,17 @@ -package org.baeldung; +package com.baeldung.spring.cloud.zuulratelimitdemo.controller; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.spring.cloud.bootstrap.config.ConfigApplication; +import com.baeldung.spring.cloud.zuulratelimitdemo.ZuulRatelimitDemoApplication; @RunWith(SpringRunner.class) -@SpringBootTest(classes = ConfigApplication.class) +@SpringBootTest(classes = ZuulRatelimitDemoApplication.class) public class SpringContextIntegrationTest { @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { } -} +} \ No newline at end of file diff --git a/spring-core/pom.xml b/spring-core/pom.xml index d348d742e7..814addecdd 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-spring-4 + parent-spring-5 0.0.1-SNAPSHOT - ../parent-spring-4 + ../parent-spring-5 diff --git a/spring-data-rest/README.md b/spring-data-rest/README.md index 1624a3abfd..abbacb69cc 100644 --- a/spring-data-rest/README.md +++ b/spring-data-rest/README.md @@ -22,3 +22,4 @@ To view the running application, visit [http://localhost:8080](http://localhost: - [Spring Data REST Events with @RepositoryEventHandler](http://www.baeldung.com/spring-data-rest-events) - [Customizing HTTP Endpoints in Spring Data REST](https://www.baeldung.com/spring-data-rest-customize-http-endpoints) - [Spring Boot with SQLite](https://www.baeldung.com/spring-boot-sqlite) +- [Spring Data Web Support](https://www.baeldung.com/spring-data-web-support) diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml index e563a6a3b5..525c88c9d8 100644 --- a/spring-data-rest/pom.xml +++ b/spring-data-rest/pom.xml @@ -1,9 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-data-rest - 1.0 spring-data-rest jar @@ -21,6 +20,10 @@ org.springframework.boot spring-boot-starter + + org.springframework.boot + spring-boot-starter-web + org.springframework.boot spring-boot-starter-data-rest @@ -30,12 +33,21 @@ spring-boot-starter-data-jpa - com.h2database - h2 + org.springframework.boot + spring-boot-autoconfigure org.springframework.boot - spring-boot-autoconfigure + spring-boot-starter-test + test + + + com.querydsl + querydsl-apt + + + com.querydsl + querydsl-jpa org.xerial @@ -45,9 +57,33 @@ ${project.artifactId} + + + com.mysema.maven + maven-apt-plugin + 1.0 + + + generate-sources + + process + + + target/generated-sources + com.querydsl.apt.jpa.JPAAnnotationProcessor + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + UTF-8 com.baeldung.SpringDataRestApplication diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/Application.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/Application.java new file mode 100644 index 0000000000..fe2f996d37 --- /dev/null +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/Application.java @@ -0,0 +1,28 @@ +package com.baeldung.springdatawebsupport.application; + +import com.baeldung.springdatawebsupport.application.entities.User; +import com.baeldung.springdatawebsupport.application.repositories.UserRepository; +import java.util.stream.Stream; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + CommandLineRunner initialize(UserRepository userRepository) { + return args -> { + Stream.of("John", "Robert", "Nataly", "Helen", "Mary").forEach(name -> { + User user = new User(name); + userRepository.save(user); + }); + userRepository.findAll().forEach(System.out::println); + }; + } +} diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java new file mode 100644 index 0000000000..8258c3b7aa --- /dev/null +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java @@ -0,0 +1,47 @@ +package com.baeldung.springdatawebsupport.application.controllers; + +import com.baeldung.springdatawebsupport.application.entities.User; +import com.baeldung.springdatawebsupport.application.repositories.UserRepository; +import com.querydsl.core.types.Predicate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.querydsl.binding.QuerydslPredicate; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class UserController { + + private final UserRepository userRepository; + + @Autowired + public UserController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping("/users/{id}") + public User findUserById(@PathVariable("id") User user) { + return user; + } + + @GetMapping("/users") + public Page findAllUsers(Pageable pageable) { + return userRepository.findAll(pageable); + } + + @GetMapping("/sortedusers") + public Page findAllUsersSortedByName() { + Pageable pageable = PageRequest.of(0, 5, Sort.by("name")); + return userRepository.findAll(pageable); + } + + @GetMapping("/filteredusers") + public Iterable getUsersByQuerydslPredicate(@QuerydslPredicate(root = User.class) Predicate predicate) { + return userRepository.findAll(predicate); + } +} diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java new file mode 100644 index 0000000000..e9aaeb119a --- /dev/null +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/entities/User.java @@ -0,0 +1,38 @@ +package com.baeldung.springdatawebsupport.application.entities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + private final String name; + + public User() { + this.name = ""; + } + + public User(String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "User{" + "id=" + id + ", name=" + name + '}'; + } +} diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java new file mode 100644 index 0000000000..41d7ed9d98 --- /dev/null +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java @@ -0,0 +1,14 @@ +package com.baeldung.springdatawebsupport.application.repositories; + +import com.baeldung.springdatawebsupport.application.entities.User; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends PagingAndSortingRepository, + QuerydslPredicateExecutor { + +} diff --git a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java new file mode 100644 index 0000000000..db522b1413 --- /dev/null +++ b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java @@ -0,0 +1,74 @@ +package com.baeldung.springdatawebsupport.application.test; + +import com.baeldung.springdatawebsupport.application.controllers.UserController; +import static org.assertj.core.api.Assertions.assertThat; +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; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class UserControllerIntegrationTest { + + @Autowired + private UserController userController; + + @Autowired + private MockMvc mockMvc; + + @Test + public void whenUserControllerInjected_thenNotNull() throws Exception { + assertThat(userController).isNotNull(); + } + + @Test + public void whenGetRequestToUsersEndPointWithIdPathVariable_thenCorrectResponse() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/users/{id}", "1") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1")); + } + + @Test + public void whenGetRequestToUsersEndPoint_thenCorrectResponse() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/users") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$['pageable']['paged']").value("true")); + + } + + @Test + public void whenGetRequestToUserEndPointWithNameRequestParameter_thenCorrectResponse() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/user") + .param("name", "John") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$['content'][0].['name']").value("John")); + } + + @Test + public void whenGetRequestToSorteredUsersEndPoint_thenCorrectResponse() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/sortedusers") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$['sort']['sorted']").value("true")); + } + + @Test + public void whenGetRequestToFilteredUsersEndPoint_thenCorrectResponse() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/filteredusers") + .param("name", "John") + .contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("John")); + } +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index 497b0f4c1f..3deeb21afc 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -19,7 +19,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Introduction to HtmlUnit](http://www.baeldung.com/htmlunit) - [Spring @RequestMapping New Shortcut Annotations](http://www.baeldung.com/spring-new-requestmapping-shortcuts) - [Guide to Spring Handler Mappings](http://www.baeldung.com/spring-handler-mappings) -- [Uploading and Displaying Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) +- [Upload and Display Excel Files with Spring MVC](http://www.baeldung.com/spring-mvc-excel-files) - [Spring MVC Custom Validation](http://www.baeldung.com/spring-mvc-custom-validator) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) - [The HttpMediaTypeNotAcceptableException in Spring MVC](http://www.baeldung.com/spring-httpmediatypenotacceptable) @@ -31,3 +31,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) - [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) - [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters) +- [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml) diff --git a/spring-mvc-xml/README.md b/spring-mvc-xml/README.md index dbc6125424..216517f52d 100644 --- a/spring-mvc-xml/README.md +++ b/spring-mvc-xml/README.md @@ -14,3 +14,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp) - [Exploring SpringMVC’s Form Tag Library](http://www.baeldung.com/spring-mvc-form-tags) - [web.xml vs Initializer with Spring](http://www.baeldung.com/spring-xml-vs-java-config) +- [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml) diff --git a/spring-rest-shell/README.md b/spring-rest-shell/README.md index 901d9a51ee..b250f06a4b 100644 --- a/spring-rest-shell/README.md +++ b/spring-rest-shell/README.md @@ -2,4 +2,4 @@ ### Relevant Articles -- [Spring REST Shell](http://www.baeldung.com/spring-rest-shell) \ No newline at end of file +- [Introduction to Spring REST Shell](http://www.baeldung.com/spring-rest-shell) diff --git a/spring-rest/README.md b/spring-rest/README.md index 9a2c1fd96c..6d3aac3eb8 100644 --- a/spring-rest/README.md +++ b/spring-rest/README.md @@ -20,5 +20,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Using the Spring RestTemplate Interceptor](http://www.baeldung.com/spring-rest-template-interceptor) - [Get and Post Lists of Objects with RestTemplate](http://www.baeldung.com/spring-rest-template-list) - [How to Set a Header on a Response with Spring 5](http://www.baeldung.com/spring-response-header) -- [Spring’s RequestBody and ResponseBody Annotations](https://www.baeldung.com/spring-request-response-body) - [Uploading MultipartFile with Spring RestTemplate](http://www.baeldung.com/spring-rest-template-multipart-upload) diff --git a/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/controller/PersonAPI.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/controller/PersonAPI.java new file mode 100644 index 0000000000..b1b56ec2f3 --- /dev/null +++ b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/controller/PersonAPI.java @@ -0,0 +1,38 @@ +package org.baeldung.resttemplate.web.controller; + +import javax.servlet.http.HttpServletResponse; + +import org.baeldung.resttemplate.web.dto.Person; +import org.baeldung.resttemplate.web.service.PersonService; +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.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +@RestController +public class PersonAPI { + + @Autowired + private PersonService personService; + + @GetMapping("/") + public String home() { + return "Spring boot is working!"; + } + + @PostMapping(value = "/createPerson", consumes = "application/json", produces = "application/json") + public Person createPerson(@RequestBody Person person) { + return personService.saveUpdatePerson(person); + } + + @PostMapping(value = "/updatePerson", consumes = "application/json", produces = "application/json") + public Person updatePerson(@RequestBody Person person, HttpServletResponse response) { + response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath() + .path("/findPerson/" + person.getId()) + .toUriString()); + return personService.saveUpdatePerson(person); + } + +} \ No newline at end of file diff --git a/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/dto/Person.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/dto/Person.java new file mode 100644 index 0000000000..4b7679638f --- /dev/null +++ b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/dto/Person.java @@ -0,0 +1,32 @@ +package org.baeldung.resttemplate.web.dto; + +public class Person { + private Integer id; + private String name; + + public Person() { + + } + + public Person(Integer id, String name) { + this.id = id; + this.name = name; + } + + 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; + } + +} diff --git a/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/service/PersonService.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/service/PersonService.java new file mode 100644 index 0000000000..c5ad39e101 --- /dev/null +++ b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/service/PersonService.java @@ -0,0 +1,10 @@ +package org.baeldung.resttemplate.web.service; + +import org.baeldung.resttemplate.web.dto.Person; + +public interface PersonService { + + public Person saveUpdatePerson(Person person); + + public Person findPersonById(Integer id); +} \ No newline at end of file diff --git a/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/service/PersonServiceImpl.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/service/PersonServiceImpl.java new file mode 100644 index 0000000000..658e0fade0 --- /dev/null +++ b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/web/service/PersonServiceImpl.java @@ -0,0 +1,19 @@ +package org.baeldung.resttemplate.web.service; + +import org.baeldung.resttemplate.web.dto.Person; +import org.springframework.stereotype.Component; + +@Component +public class PersonServiceImpl implements PersonService { + + @Override + public Person saveUpdatePerson(Person person) { + return person; + } + + @Override + public Person findPersonById(Integer id) { + return new Person(id, "John"); + } + +} diff --git a/spring-resttemplate/src/test/java/org/baeldung/resttemplate/PersonAPILiveTest.java b/spring-resttemplate/src/test/java/org/baeldung/resttemplate/PersonAPILiveTest.java new file mode 100644 index 0000000000..de18f6db09 --- /dev/null +++ b/spring-resttemplate/src/test/java/org/baeldung/resttemplate/PersonAPILiveTest.java @@ -0,0 +1,96 @@ +package org.baeldung.resttemplate; + +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.net.URI; + +import org.baeldung.resttemplate.web.dto.Person; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = RestTemplateConfigurationApplication.class) +public class PersonAPILiveTest { + + private static String createPersonUrl; + private static String updatePersonUrl; + + private static RestTemplate restTemplate; + + private static HttpHeaders headers; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + private static JSONObject personJsonObject; + + @BeforeClass + public static void runBeforeAllTestMethods() throws JSONException { + createPersonUrl = "http://localhost:8082/spring-rest/createPerson"; + updatePersonUrl = "http://localhost:8082/spring-rest/updatePerson"; + + restTemplate = new RestTemplate(); + + headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + personJsonObject = new JSONObject(); + personJsonObject.put("id", 1); + personJsonObject.put("name", "John"); + } + + @Test + public void givenDataIsJson_whenDataIsPostedByPostForObject_thenResponseBodyIsNotNull() throws IOException { + HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); + String personResultAsJsonStr = restTemplate.postForObject(createPersonUrl, request, String.class); + JsonNode root = objectMapper.readTree(personResultAsJsonStr); + + Person person = restTemplate.postForObject(createPersonUrl, request, Person.class); + + assertNotNull(personResultAsJsonStr); + assertNotNull(root); + assertNotNull(root.path("name") + .asText()); + + assertNotNull(person); + assertNotNull(person.getName()); + } + + @Test + public void givenDataIsJson_whenDataIsPostedByPostForEntity_thenResponseBodyIsNotNull() throws IOException { + HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); + ResponseEntity responseEntityStr = restTemplate.postForEntity(createPersonUrl, request, String.class); + JsonNode root = objectMapper.readTree(responseEntityStr.getBody()); + + ResponseEntity responseEntityPerson = restTemplate.postForEntity(createPersonUrl, request, Person.class); + + assertNotNull(responseEntityStr.getBody()); + assertNotNull(root.path("name") + .asText()); + + assertNotNull(responseEntityPerson.getBody()); + assertNotNull(responseEntityPerson.getBody() + .getName()); + } + + @Test + public void givenDataIsJson_whenDataIsPostedByPostForLocation_thenResponseBodyIsTheLocationHeader() throws JsonProcessingException { + HttpEntity request = new HttpEntity(personJsonObject.toString(), headers); + URI locationHeader = restTemplate.postForLocation(updatePersonUrl, request); + + assertNotNull(locationHeader); + } +} \ No newline at end of file diff --git a/spring-security-kerberos/README.md b/spring-security-kerberos/README.md new file mode 100644 index 0000000000..0338c2058c --- /dev/null +++ b/spring-security-kerberos/README.md @@ -0,0 +1,10 @@ +## @PreFilter and @PostFilter annotations + +### Build the Project ### + +``` +mvn clean install +``` + +### Relevant Articles: +- [Spring Security – Kerberos](http://www.baeldung.com/xxxxxx) diff --git a/spring-security-kerberos/pom.xml b/spring-security-kerberos/pom.xml new file mode 100644 index 0000000000..35c4ba4926 --- /dev/null +++ b/spring-security-kerberos/pom.xml @@ -0,0 +1,61 @@ + + 4.0.0 + com.baeldung + spring-security-kerberos + 0.1-SNAPSHOT + spring-security-kerberos + war + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security.kerberos + spring-security-kerberos-core + 1.0.1.RELEASE + + + org.springframework.security.kerberos + spring-security-kerberos-web + 1.0.1.RELEASE + + + org.springframework.security.kerberos + spring-security-kerberos-client + 1.0.1.RELEASE + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + org.apache.maven.plugins + maven-war-plugin + + + + diff --git a/spring-security-kerberos/src/main/java/org/baeldung/Application.java b/spring-security-kerberos/src/main/java/org/baeldung/Application.java new file mode 100644 index 0000000000..39c2b51356 --- /dev/null +++ b/spring-security-kerberos/src/main/java/org/baeldung/Application.java @@ -0,0 +1,13 @@ +package org.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java b/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java new file mode 100644 index 0000000000..49a1cf0a8e --- /dev/null +++ b/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java @@ -0,0 +1,87 @@ +package org.baeldung.config; + +import org.baeldung.security.DummyUserDetailsService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; +import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider; +import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; +import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator; +import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter; +import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .anyRequest() + .authenticated() + .and() + .addFilterBefore(spnegoAuthenticationProcessingFilter(authenticationManagerBean()), BasicAuthenticationFilter.class); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(kerberosAuthenticationProvider()) + .authenticationProvider(kerberosServiceAuthenticationProvider()); + } + + @Bean + public KerberosAuthenticationProvider kerberosAuthenticationProvider() { + KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider(); + SunJaasKerberosClient client = new SunJaasKerberosClient(); + client.setDebug(true); + provider.setKerberosClient(client); + provider.setUserDetailsService(dummyUserDetailsService()); + return provider; + } + + @Bean + public SpnegoEntryPoint spnegoEntryPoint() { + return new SpnegoEntryPoint("/login"); + } + + @Bean + public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(AuthenticationManager authenticationManager) { + SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter(); + filter.setAuthenticationManager(authenticationManager); + return filter; + } + + @Bean + public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() { + KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider(); + provider.setTicketValidator(sunJaasKerberosTicketValidator()); + provider.setUserDetailsService(dummyUserDetailsService()); + return provider; + } + + @Bean + public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { + SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); + ticketValidator.setServicePrincipal("HTTP/demo.kerberos.bealdung.com@baeldung.com"); + ticketValidator.setKeyTabLocation(new FileSystemResource("baeldung.keytab")); + ticketValidator.setDebug(true); + return ticketValidator; + } + + @Bean + public DummyUserDetailsService dummyUserDetailsService() { + return new DummyUserDetailsService(); + } + +} \ No newline at end of file diff --git a/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java b/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java new file mode 100644 index 0000000000..10d71fca8f --- /dev/null +++ b/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java @@ -0,0 +1,16 @@ +package org.baeldung.security; + +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +public class DummyUserDetailsService implements UserDetailsService { + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return new User(username, "notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER")); + } + +} \ No newline at end of file diff --git a/spring-security-mvc-ldap/README.md b/spring-security-mvc-ldap/README.md index ac080c138d..6f03143183 100644 --- a/spring-security-mvc-ldap/README.md +++ b/spring-security-mvc-ldap/README.md @@ -5,7 +5,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Article: -- [Spring Security - security none, filters none, access permitAll](http://www.baeldung.com/security-none-filters-none-access-permitAll) +- [Spring Security – security none, filters none, access permitAll](http://www.baeldung.com/security-none-filters-none-access-permitAll) - [Intro to Spring Security LDAP](http://www.baeldung.com/spring-security-ldap) ### Notes diff --git a/spring-security-mvc-login/README.md b/spring-security-mvc-login/README.md index c19cbc87a5..983d949cb8 100644 --- a/spring-security-mvc-login/README.md +++ b/spring-security-mvc-login/README.md @@ -10,7 +10,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [Spring Security Logout](http://www.baeldung.com/spring-security-logout) - [Spring Security Expressions – hasRole Example](http://www.baeldung.com/spring-security-expressions-basic) - [Spring HTTP/HTTPS Channel Security](http://www.baeldung.com/spring-channel-security-https) -- [Spring Security - Customize the 403 Forbidden/Access Denied Page](http://www.baeldung.com/spring-security-custom-access-denied-page) +- [Spring Security – Customize the 403 Forbidden/Access Denied Page](http://www.baeldung.com/spring-security-custom-access-denied-page) - [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login) - [Spring Security Custom AuthenticationFailureHandler](http://www.baeldung.com/spring-security-custom-authentication-failure-handler) diff --git a/spring-security-mvc-persisted-remember-me/README.md b/spring-security-mvc-persisted-remember-me/README.md index e505537be1..db2ae890f9 100644 --- a/spring-security-mvc-persisted-remember-me/README.md +++ b/spring-security-mvc-persisted-remember-me/README.md @@ -6,7 +6,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: -- [Spring Security Persisted Remember Me](http://www.baeldung.com/spring-security-persistent-remember-me) +- [Spring Security – Persistent Remember Me](http://www.baeldung.com/spring-security-persistent-remember-me) ### Build the Project ``` diff --git a/spring-security-rest-basic-auth/README.md b/spring-security-rest-basic-auth/README.md index 30da3afbcf..0a48a747c2 100644 --- a/spring-security-rest-basic-auth/README.md +++ b/spring-security-rest-basic-auth/README.md @@ -8,6 +8,5 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Basic Authentication with the RestTemplate](http://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring) - [HttpClient Timeout](http://www.baeldung.com/httpclient-timeout) -- [HttpClient with SSL](http://www.baeldung.com/httpclient-ssl) - [A Custom Filter in the Spring Security Filter Chain](http://www.baeldung.com/spring-security-custom-filter) - [Spring Security Basic Authentication](http://www.baeldung.com/spring-security-basic-authentication) diff --git a/spring-security-rest-basic-auth/pom.xml b/spring-security-rest-basic-auth/pom.xml index ca5c4c38e6..3c7f8eaa2b 100644 --- a/spring-security-rest-basic-auth/pom.xml +++ b/spring-security-rest-basic-auth/pom.xml @@ -272,8 +272,8 @@ - 4.4.5 - 4.5.3 + 4.4.11 + 4.5.8 1.2 diff --git a/spring-security-rest/README.md b/spring-security-rest/README.md index f71eead9ae..f450a514b2 100644 --- a/spring-security-rest/README.md +++ b/spring-security-rest/README.md @@ -11,7 +11,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [Spring REST Service Security](http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/) - [Setting Up Swagger 2 with a Spring REST API](http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) - [Custom Error Message Handling for REST API](http://www.baeldung.com/global-error-handler-in-a-spring-rest-api) -- [An Intro to Spring HATEOAS](http://www.baeldung.com/spring-hateoas-tutorial) - [Spring Security Context Propagation with @Async](http://www.baeldung.com/spring-security-async-principal-propagation) - [Servlet 3 Async Support with Spring MVC and Spring Security](http://www.baeldung.com/spring-mvc-async-security) - [Intro to Spring Security Expressions](http://www.baeldung.com/spring-security-expressions) diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index 24f1c5807a..b6039ce9d3 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -84,13 +84,6 @@ ${spring.version} - - - org.springframework.hateoas - spring-hateoas - ${org.springframework.hateoas.version} - - @@ -273,9 +266,6 @@ - - 0.25.0.RELEASE - 3.1.0 1.1.0.Final diff --git a/spring-security-sso/README.md b/spring-security-sso/README.md index 11b5f011d5..d0c1b2f7cf 100644 --- a/spring-security-sso/README.md +++ b/spring-security-sso/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Simple Single Sign On with Spring Security OAuth2](http://www.baeldung.com/sso-spring-security-oauth2) +- [Simple Single Sign-On with Spring Security OAuth2](http://www.baeldung.com/sso-spring-security-oauth2) diff --git a/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/KerberosClientApp.java b/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/KerberosClientApp.java index a353961854..9fb86e7658 100644 --- a/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/KerberosClientApp.java +++ b/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/KerberosClientApp.java @@ -12,6 +12,8 @@ class KerberosClientApp { System.setProperty("java.security.krb5.conf", Paths.get(".\\krb-test-workdir\\krb5.conf").normalize().toAbsolutePath().toString()); System.setProperty("sun.security.krb5.debug", "true"); + // disable usage of local kerberos ticket cache + System.setProperty("http.use.global.creds", "false"); } public static void main(String[] args) { diff --git a/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/SampleService.java b/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/SampleClient.java similarity index 87% rename from spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/SampleService.java rename to spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/SampleClient.java index 4145cf0c1a..745193e3b0 100644 --- a/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/SampleService.java +++ b/spring-security-sso/spring-security-sso-kerberos/src/main/java/kerberos/client/SampleClient.java @@ -5,14 +5,14 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service -class SampleService { +class SampleClient { @Value("${app.access-url}") private String endpoint; private RestTemplate restTemplate; - public SampleService(RestTemplate restTemplate) { + public SampleClient(RestTemplate restTemplate) { this.restTemplate = restTemplate; } diff --git a/spring-security-sso/spring-security-sso-kerberos/src/test/java/kerberos/client/SampleServiceManualTest.java b/spring-security-sso/spring-security-sso-kerberos/src/test/java/kerberos/client/SampleClientManualTest.java similarity index 59% rename from spring-security-sso/spring-security-sso-kerberos/src/test/java/kerberos/client/SampleServiceManualTest.java rename to spring-security-sso/spring-security-sso-kerberos/src/test/java/kerberos/client/SampleClientManualTest.java index d0d9f0ae4b..fdb1b12531 100644 --- a/spring-security-sso/spring-security-sso-kerberos/src/test/java/kerberos/client/SampleServiceManualTest.java +++ b/spring-security-sso/spring-security-sso-kerberos/src/test/java/kerberos/client/SampleClientManualTest.java @@ -1,6 +1,5 @@ package kerberos.client; -import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,7 +9,6 @@ import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; /** @@ -23,21 +21,19 @@ import static org.junit.jupiter.api.Assertions.assertThrows; */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@FixMethodOrder -public class SampleServiceManualTest { +public class SampleClientManualTest { @Autowired - private SampleService sampleService; + private SampleClient sampleClient; @Test - public void a_givenKerberizedRestTemplate_whenServiceCall_thenSuccess() { - assertNotNull(sampleService); - assertEquals("data from kerberized server", sampleService.getData()); + public void givenKerberizedRestTemplate_whenServiceCall_thenSuccess() { + assertEquals("data from kerberized server", sampleClient.getData()); } @Test - public void b_givenRestTemplate_whenServiceCall_thenFail() { - sampleService.setRestTemplate(new RestTemplate()); - assertThrows(RestClientException.class, sampleService::getData); + public void givenRestTemplate_whenServiceCall_thenFail() { + sampleClient.setRestTemplate(new RestTemplate()); + assertThrows(RestClientException.class, sampleClient::getData); } } \ No newline at end of file diff --git a/spring-thymeleaf/README.md b/spring-thymeleaf/README.md index f9e7dd90a7..b6824003db 100644 --- a/spring-thymeleaf/README.md +++ b/spring-thymeleaf/README.md @@ -8,7 +8,7 @@ - [Thymeleaf: Custom Layout Dialect](http://www.baeldung.com/thymeleaf-spring-layouts) - [Spring and Thymeleaf 3: Expressions](http://www.baeldung.com/spring-thymeleaf-3-expressions) - [Spring MVC + Thymeleaf 3.0: New Features](http://www.baeldung.com/spring-thymeleaf-3) -- [How to Work with Dates in Thymeleaef](http://www.baeldung.com/dates-in-thymeleaf) +- [How to Work with Dates in Thymeleaf](http://www.baeldung.com/dates-in-thymeleaf) - [How to Create an Executable JAR with Maven](http://www.baeldung.com/executable-jar-with-maven) - [Working with Boolean in Thymeleaf](http://www.baeldung.com/thymeleaf-boolean) - [Working with Fragments in Thymeleaf](http://www.baeldung.com/spring-thymeleaf-fragments) diff --git a/tensorflow-java/README.md b/tensorflow-java/README.md index aa9e9e56b9..f826375ac1 100644 --- a/tensorflow-java/README.md +++ b/tensorflow-java/README.md @@ -1,3 +1,3 @@ ## Relevant articles: -- [TensorFlow for Java](https://www.baeldung.com/tensorflow-java) +- [Introduction to Tensorflow for Java](https://www.baeldung.com/tensorflow-java) diff --git a/testing-modules/groovy-spock/README.md b/testing-modules/groovy-spock/README.md index a98df27172..e61c56d470 100644 --- a/testing-modules/groovy-spock/README.md +++ b/testing-modules/groovy-spock/README.md @@ -2,3 +2,4 @@ - [Introduction to Testing with Spock and Groovy](http://www.baeldung.com/groovy-spock) - [Difference Between Stub, Mock, and Spy in the Spock Framework](https://www.baeldung.com/spock-stub-mock-spy) +- [Guide to Spock Extensions](https://www.baeldung.com/spock-extensions) diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml index d6097af208..35d8f5034f 100644 --- a/testing-modules/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -48,7 +48,7 @@
- 1.3-RC1-groovy-2.4 + 1.3-groovy-2.4 2.4.7 1.5 diff --git a/testing-modules/groovy-spock/src/test/groovy/extensions/IgnoreIfTest.groovy b/testing-modules/groovy-spock/src/test/groovy/extensions/IgnoreIfTest.groovy index 91da2ff1ec..9010481220 100644 --- a/testing-modules/groovy-spock/src/test/groovy/extensions/IgnoreIfTest.groovy +++ b/testing-modules/groovy-spock/src/test/groovy/extensions/IgnoreIfTest.groovy @@ -7,6 +7,16 @@ import spock.lang.Specification class IgnoreIfTest extends Specification { @IgnoreIf({System.getProperty("os.name").contains("windows")}) - def "I won't run on windows"() { } + def "I won't run on windows"() { + expect: + true + } + + @IgnoreIf({ os.isWindows() }) + def "I'm using Spock helper classes to run only on windows"() { + expect: + true + } + } diff --git a/testing-modules/groovy-spock/src/test/resources/SpockConfig.groovy b/testing-modules/groovy-spock/src/test/resources/SpockConfig.groovy index ed94e61cbf..4b017aeefc 100644 --- a/testing-modules/groovy-spock/src/test/resources/SpockConfig.groovy +++ b/testing-modules/groovy-spock/src/test/resources/SpockConfig.groovy @@ -2,7 +2,10 @@ import extensions.TimeoutTest import spock.lang.Issue runner { - filterStackTrace true + + if (System.getenv("FILTER_STACKTRACE") == null) { + filterStackTrace false + } report { issueNamePrefix 'Bug ' diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index d686396a1d..aafdd75e81 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -6,7 +6,7 @@ - [A Guide to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) - [Inject Parameters into JUnit Jupiter Unit Tests](http://www.baeldung.com/junit-5-parameters) - [Mockito and JUnit 5 – Using ExtendWith](http://www.baeldung.com/mockito-junit-5-extension) -- [JUnit 5 – @RunWith](http://www.baeldung.com/junit-5-runwith) +- [JUnit 5 @RunWith](http://www.baeldung.com/junit-5-runwith) - [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) - [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) - [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) diff --git a/testing-modules/rest-assured/README.md b/testing-modules/rest-assured/README.md index de15515f9d..d44fd08335 100644 --- a/testing-modules/rest-assured/README.md +++ b/testing-modules/rest-assured/README.md @@ -1,3 +1,4 @@ ###Relevant Articles: - [A Guide to REST-assured](http://www.baeldung.com/rest-assured-tutorial) - [REST-assured Support for Spring MockMvc](https://www.baeldung.com/spring-mock-mvc-rest-assured) +- [Getting and Verifying Response Data with REST-assured](https://www.baeldung.com/rest-assured-response) diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index cd342ccd11..c528a34e21 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -162,6 +162,11 @@ commons-collections ${commons-collections.version} + + + org.springframework.boot + spring-boot-starter-security + @@ -179,6 +184,12 @@ json-schema-validator test + + com.github.scribejava + scribejava-apis + ${scribejava.version} + test + @@ -211,6 +222,8 @@ 3.0.1 3.0.1 + + 2.5.3 diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicAuthenticationLiveTest.java new file mode 100644 index 0000000000..aff765dfa3 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicAuthenticationLiveTest.java @@ -0,0 +1,38 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * For this Live Test we need: + * * a running instance of the service located in the spring-security-rest-basic-auth module. + * @see spring-security-rest-basic-auth module + * + */ +public class BasicAuthenticationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SVC_URL = "http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.UNAUTHORIZED.value()); + } + + @Test + public void givenBasicAuthentication_whenRequestSecuredResource_thenResourceRetrieved() { + given().auth() + .basic(USER, PASSWORD) + .when() + .get(SVC_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicPreemtiveAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicPreemtiveAuthenticationLiveTest.java new file mode 100644 index 0000000000..02138f22e3 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicPreemtiveAuthenticationLiveTest.java @@ -0,0 +1,56 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * For this Live Test we need: + * * a running instance of the service located in the spring-boot-admin/spring-boot-admin-server module. + * @see spring-boot-admin/spring-boot-admin-server module + * + */ +public class BasicPreemtiveAuthenticationLiveTest { + + private static final String USER = "admin"; + private static final String PASSWORD = "admin"; + private static final String SVC_URL = "http://localhost:8080/api/applications/"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("spring-security-mvc-digest-auth module + * + */ +public class DigestAuthenticationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SVC_URL = "http://localhost:8080/spring-security-mvc-digest-auth/homepage.html"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.UNAUTHORIZED.value()); + } + + @Test + public void givenFormAuthentication_whenRequestSecuredResource_thenResourceRetrieved() { + given().auth() + .digest(USER, PASSWORD) + .when() + .get(SVC_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("This is the body of the sample view")); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/FormAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/FormAuthenticationLiveTest.java new file mode 100644 index 0000000000..66ae9fb162 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/FormAuthenticationLiveTest.java @@ -0,0 +1,57 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.isEmptyString; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.authentication.FormAuthConfig; + +/** + * For this Live Test we need: + * * a running instance of the service located in the spring-security-mvc-login module. + * @see spring-security-mvc-login module + * + */ +public class FormAuthenticationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SVC_URL = "http://localhost:8080/spring-security-mvc-login/secured"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenLoginFormResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("spring-boot-admin/spring-boot-admin-server module + * + */ +public class FormAutoconfAuthenticationLiveTest { + + private static final String USER = "admin"; + private static final String PASSWORD = "admin"; + private static final String SVC_URL = "http://localhost:8080/ger1/api/applications/"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("spring-security-oauth/oauth-authorization-server module + * + * * a running instance of the service located in the spring-security-oauth repo - oauth-resource-server-1 module. + * @see spring-security-oauth/oauth-resource-server-1 module + * + */ +public class OAuth2AuthenticationLiveTest { + + private static final String USER = "john"; + private static final String PASSWORD = "123"; + private static final String CLIENT_ID = "fooClientIdPassword"; + private static final String SECRET = "secret"; + private static final String AUTH_SVC_TOKEN_URL = "http://localhost:8081/spring-security-oauth-server/oauth/token"; + private static final String RESOURCE_SVC_URL = "http://localhost:8082/spring-security-oauth-resource/foos/1"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(RESOURCE_SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.UNAUTHORIZED.value()); + } + + @Test + public void givenAccessTokenAuthentication_whenRequestSecuredResource_thenResourceRetrieved() { + String accessToken = given().auth() + .basic(CLIENT_ID, SECRET) + .formParam("grant_type", "password") + .formParam("username", USER) + .formParam("password", PASSWORD) + .formParam("scope", "read foo") + .when() + .post(AUTH_SVC_TOKEN_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .extract() + .path("access_token"); + + given().auth() + .oauth2(accessToken) + .when() + .get(RESOURCE_SVC_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .body("$", hasKey("id")) + .body("$", hasKey("name")); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/OAuthAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/OAuthAuthenticationLiveTest.java new file mode 100644 index 0000000000..c720bc04e4 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/OAuthAuthenticationLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.hasKey; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.http.ContentType; + +/** + * For this Live Test we need to obtain a valid Access Token and Token Secret: + * * start spring-mvc-simple application in debug mode + * @see spring-mvc-simple module + * * calling localhost:8080/spring-mvc-simple/twitter/authorization/ using the browser + * * debug the callback function where we can obtain the fields + */ +public class OAuthAuthenticationLiveTest { + + // We can obtain these two from the spring-mvc-simple / TwitterController class + private static final String OAUTH_API_KEY = "PSRszoHhRDVhyo2RIkThEbWko"; + private static final String OAUTH_API_SECRET = "prpJbz03DcGRN46sb4ucdSYtVxG8unUKhcnu3an5ItXbEOuenL"; + private static final String TWITTER_ENDPOINT = "https://api.twitter.com/1.1/account/settings.json"; + /* We can obtain the following by: + * - starting the spring-mvc-simple application + * - calling localhost:8080/spring-mvc-simple/twitter/authorization/ + * - debugging the callback function */ + private static final String ACCESS_TOKEN = "..."; + private static final String TOKEN_SECRET = "..."; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(TWITTER_ENDPOINT).then() + .assertThat() + .statusCode(HttpStatus.BAD_REQUEST.value()); + } + + @Test + public void givenAccessTokenAuthentication_whenRequestSecuredResource_thenResourceIsRequested() { + given().accept(ContentType.JSON) + .auth() + .oauth(OAUTH_API_KEY, OAUTH_API_SECRET, ACCESS_TOKEN, TOKEN_SECRET) + .when() + .get(TWITTER_ENDPOINT) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .body("$", hasKey("geo_enabled")) + .body("$", hasKey("language")); + } + +} diff --git a/testing-modules/rest-testing/README.md b/testing-modules/rest-testing/README.md index 25e036ba5d..2d366bd550 100644 --- a/testing-modules/rest-testing/README.md +++ b/testing-modules/rest-testing/README.md @@ -6,9 +6,8 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Test a REST API with Java](http://www.baeldung.com/integration-testing-a-rest-api) - [Introduction to WireMock](http://www.baeldung.com/introduction-to-wiremock) -- [Using WireMock Scenarios](http://www.baeldung.com/using-wiremock-scenarios) +- [Using WireMock Scenarios](https://www.baeldung.com/wiremock-scenarios) - [REST API Testing with Cucumber](http://www.baeldung.com/cucumber-rest-api-testing) - [Testing a REST API with JBehave](http://www.baeldung.com/jbehave-rest-testing) - [REST API Testing with Karate](http://www.baeldung.com/karate-rest-api-testing) diff --git a/testing-modules/testing/README.md b/testing-modules/testing/README.md index e96b26ab41..4a7829e867 100644 --- a/testing-modules/testing/README.md +++ b/testing-modules/testing/README.md @@ -18,6 +18,6 @@ - [Custom JUnit 4 Test Runners](http://www.baeldung.com/junit-4-custom-runners) - [Guide to JSpec](http://www.baeldung.com/jspec) - [Custom Assertions with AssertJ](http://www.baeldung.com/assertj-custom-assertion) -- [Using Conditions with AssertJ](http://www.baeldung.com/assertj-conditions) -- [Guide to JavaFaker](https://www.baeldung.com/java-faker) +- [Using Conditions with AssertJ Assertions](http://www.baeldung.com/assertj-conditions) +- [A Guide to JavaFaker](https://www.baeldung.com/java-faker) - [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) diff --git a/vaadin/pom.xml b/vaadin/pom.xml index d24b3dff1b..ec69e240e2 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -33,22 +33,6 @@ javax.servlet-api provided - - com.vaadin - vaadin-server - - - com.vaadin - vaadin-push - - - com.vaadin - vaadin-client-compiled - - - com.vaadin - vaadin-themes - org.springframework.boot @@ -86,17 +70,6 @@ com.vaadin vaadin-maven-plugin ${vaadin.plugin.version} - - - - update-theme - update-widgetset - compile - - compile-theme - - - org.apache.maven.plugins @@ -183,9 +156,9 @@ 3.0.1 - 7.7.10 - 8.0.6 - 10.0.1 + 10.0.11 + 10.0.11 + 10.0.11 9.3.9.v20160517 UTF-8 1.8 diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java deleted file mode 100644 index 1b3733ad74..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.baeldung.introduction; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.servlet.annotation.WebServlet; - -import com.vaadin.annotations.Push; -import com.vaadin.annotations.Theme; -import com.vaadin.annotations.VaadinServletConfiguration; -import com.vaadin.data.Validator.InvalidValueException; -import com.vaadin.data.fieldgroup.BeanFieldGroup; -import com.vaadin.data.validator.StringLengthValidator; -import com.vaadin.server.ExternalResource; -import com.vaadin.server.FontAwesome; -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinServlet; -import com.vaadin.ui.Button; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.DateField; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Grid; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.InlineDateField; -import com.vaadin.ui.Label; -import com.vaadin.ui.Link; -import com.vaadin.ui.ListSelect; -import com.vaadin.ui.NativeButton; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.Panel; -import com.vaadin.ui.PasswordField; -import com.vaadin.ui.RichTextArea; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; -import com.vaadin.ui.TwinColSelect; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; - -@SuppressWarnings("serial") -@Push -@Theme("mytheme") -public class VaadinUI extends UI { - - private Label currentTime; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - protected void init(VaadinRequest vaadinRequest) { - final VerticalLayout verticalLayout = new VerticalLayout(); - verticalLayout.setSpacing(true); - verticalLayout.setMargin(true); - final GridLayout gridLayout = new GridLayout(3, 2); - gridLayout.setSpacing(true); - gridLayout.setMargin(true); - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSpacing(true); - horizontalLayout.setMargin(true); - final FormLayout formLayout = new FormLayout(); - formLayout.setSpacing(true); - formLayout.setMargin(true); - final GridLayout buttonLayout = new GridLayout(3, 5); - buttonLayout.setMargin(true); - buttonLayout.setSpacing(true); - - final Label label = new Label(); - label.setId("Label"); - label.setValue("Label Value"); - label.setCaption("Label"); - gridLayout.addComponent(label); - - final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/")); - link.setId("Link"); - link.setTargetName("_blank"); - gridLayout.addComponent(link); - - final TextField textField = new TextField(); - textField.setId("TextField"); - textField.setCaption("TextField:"); - textField.setValue("TextField Value"); - textField.setIcon(FontAwesome.USER); - gridLayout.addComponent(textField); - - final TextArea textArea = new TextArea(); - textArea.setCaption("TextArea"); - textArea.setId("TextArea"); - textArea.setValue("TextArea Value"); - gridLayout.addComponent(textArea); - - final DateField dateField = new DateField("DateField", new Date(0)); - dateField.setId("DateField"); - gridLayout.addComponent(dateField); - - final PasswordField passwordField = new PasswordField(); - passwordField.setId("PasswordField"); - passwordField.setCaption("PasswordField:"); - passwordField.setValue("password"); - gridLayout.addComponent(passwordField); - - final RichTextArea richTextArea = new RichTextArea(); - richTextArea.setCaption("Rich Text Area"); - richTextArea.setValue("

RichTextArea

"); - richTextArea.setSizeFull(); - - Panel richTextPanel = new Panel(); - richTextPanel.setContent(richTextArea); - - final InlineDateField inlineDateField = new InlineDateField(); - inlineDateField.setValue(new Date(0)); - inlineDateField.setCaption("Inline Date Field"); - horizontalLayout.addComponent(inlineDateField); - - Button normalButton = new Button("Normal Button"); - normalButton.setId("NormalButton"); - normalButton.addClickListener(e -> { - label.setValue("CLICK"); - }); - buttonLayout.addComponent(normalButton); - - Button tinyButton = new Button("Tiny Button"); - tinyButton.addStyleName("tiny"); - buttonLayout.addComponent(tinyButton); - - Button smallButton = new Button("Small Button"); - smallButton.addStyleName("small"); - buttonLayout.addComponent(smallButton); - - Button largeButton = new Button("Large Button"); - largeButton.addStyleName("large"); - buttonLayout.addComponent(largeButton); - - Button hugeButton = new Button("Huge Button"); - hugeButton.addStyleName("huge"); - buttonLayout.addComponent(hugeButton); - - Button disabledButton = new Button("Disabled Button"); - disabledButton.setDescription("This button cannot be clicked"); - disabledButton.setEnabled(false); - buttonLayout.addComponent(disabledButton); - - Button dangerButton = new Button("Danger Button"); - dangerButton.addStyleName("danger"); - buttonLayout.addComponent(dangerButton); - - Button friendlyButton = new Button("Friendly Button"); - friendlyButton.addStyleName("friendly"); - buttonLayout.addComponent(friendlyButton); - - Button primaryButton = new Button("Primary Button"); - primaryButton.addStyleName("primary"); - buttonLayout.addComponent(primaryButton); - - NativeButton nativeButton = new NativeButton("Native Button"); - buttonLayout.addComponent(nativeButton); - - Button iconButton = new Button("Icon Button"); - iconButton.setIcon(FontAwesome.ALIGN_LEFT); - buttonLayout.addComponent(iconButton); - - Button borderlessButton = new Button("BorderLess Button"); - borderlessButton.addStyleName("borderless"); - buttonLayout.addComponent(borderlessButton); - - Button linkButton = new Button("Link Button"); - linkButton.addStyleName("link"); - buttonLayout.addComponent(linkButton); - - Button quietButton = new Button("Quiet Button"); - quietButton.addStyleName("quiet"); - buttonLayout.addComponent(quietButton); - - horizontalLayout.addComponent(buttonLayout); - - final CheckBox checkbox = new CheckBox("CheckBox"); - checkbox.setValue(true); - checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue())); - formLayout.addComponent(checkbox); - - List numbers = new ArrayList(); - numbers.add("One"); - numbers.add("Ten"); - numbers.add("Eleven"); - ComboBox comboBox = new ComboBox("ComboBox"); - comboBox.addItems(numbers); - formLayout.addComponent(comboBox); - - ListSelect listSelect = new ListSelect("ListSelect"); - listSelect.addItems(numbers); - listSelect.setRows(2); - formLayout.addComponent(listSelect); - - NativeSelect nativeSelect = new NativeSelect("NativeSelect"); - nativeSelect.addItems(numbers); - formLayout.addComponent(nativeSelect); - - TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); - twinColSelect.addItems(numbers); - - Grid grid = new Grid("Grid"); - grid.setColumns("Column1", "Column2", "Column3"); - grid.addRow("Item1", "Item2", "Item3"); - grid.addRow("Item4", "Item5", "Item6"); - - Panel panel = new Panel("Panel"); - panel.setContent(grid); - panel.setSizeUndefined(); - - Panel serverPushPanel = new Panel("Server Push"); - FormLayout timeLayout = new FormLayout(); - timeLayout.setSpacing(true); - timeLayout.setMargin(true); - currentTime = new Label("No TIME..."); - timeLayout.addComponent(currentTime); - serverPushPanel.setContent(timeLayout); - serverPushPanel.setSizeUndefined(); - ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1); - Runnable task = () -> { - currentTime.setValue("Current Time : " + Instant.now()); - }; - scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); - - FormLayout dataBindingLayout = new FormLayout(); - dataBindingLayout.setSpacing(true); - dataBindingLayout.setMargin(true); - - BindData bindData = new BindData("BindData"); - BeanFieldGroup beanFieldGroup = new BeanFieldGroup(BindData.class); - beanFieldGroup.setItemDataSource(bindData); - TextField bindedTextField = (TextField) beanFieldGroup.buildAndBind("BindName", "bindName"); - bindedTextField.setWidth("250px"); - dataBindingLayout.addComponent(bindedTextField); - - FormLayout validatorLayout = new FormLayout(); - validatorLayout.setSpacing(true); - validatorLayout.setMargin(true); - - HorizontalLayout textValidatorLayout = new HorizontalLayout(); - textValidatorLayout.setSpacing(true); - textValidatorLayout.setMargin(true); - - TextField stringValidator = new TextField(); - stringValidator.setNullSettingAllowed(true); - stringValidator.setNullRepresentation(""); - stringValidator.addValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5, true)); - stringValidator.setValidationVisible(false); - textValidatorLayout.addComponent(stringValidator); - Button buttonStringValidator = new Button("Validate String"); - buttonStringValidator.addClickListener(e -> { - try { - stringValidator.setValidationVisible(false); - stringValidator.validate(); - } catch (InvalidValueException err) { - stringValidator.setValidationVisible(true); - } - }); - textValidatorLayout.addComponent(buttonStringValidator); - - validatorLayout.addComponent(textValidatorLayout); - verticalLayout.addComponent(gridLayout); - verticalLayout.addComponent(richTextPanel); - verticalLayout.addComponent(horizontalLayout); - verticalLayout.addComponent(formLayout); - verticalLayout.addComponent(twinColSelect); - verticalLayout.addComponent(panel); - verticalLayout.addComponent(serverPushPanel); - verticalLayout.addComponent(dataBindingLayout); - verticalLayout.addComponent(validatorLayout); - setContent(verticalLayout); - } - - @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) - @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false) - public static class MyUIServlet extends VaadinServlet { - } -}