Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-10982
This commit is contained in:
		
						commit
						b28e7741e3
					
				
							
								
								
									
										37
									
								
								core-groovy/src/main/groovy/com/baeldung/Person.groovy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								core-groovy/src/main/groovy/com/baeldung/Person.groovy
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | package com.baeldung | ||||||
|  | 
 | ||||||
|  | class Person { | ||||||
|  |     private String firstname | ||||||
|  |     private String lastname | ||||||
|  |     private Integer age | ||||||
|  | 
 | ||||||
|  |     Person(String firstname, String lastname, Integer age) { | ||||||
|  |         this.firstname = firstname | ||||||
|  |         this.lastname = lastname | ||||||
|  |         this.age = age | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     String getFirstname() { | ||||||
|  |         return firstname | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void setFirstname(String firstname) { | ||||||
|  |         this.firstname = firstname | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     String getLastname() { | ||||||
|  |         return lastname | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void setLastname(String lastname) { | ||||||
|  |         this.lastname = lastname | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Integer getAge() { | ||||||
|  |         return age | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void setAge(Integer age) { | ||||||
|  |         this.age = age | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -129,13 +129,13 @@ class ListTest{ | |||||||
|         assertTrue(filterList.findAll{it > 3} == [4, 5, 6, 76]) |         assertTrue(filterList.findAll{it > 3} == [4, 5, 6, 76]) | ||||||
| 
 | 
 | ||||||
|         assertTrue(filterList.findAll{ it instanceof Number} == [2, 1, 3, 4, 5, 6, 76]) |         assertTrue(filterList.findAll{ it instanceof Number} == [2, 1, 3, 4, 5, 6, 76]) | ||||||
|          | 
 | ||||||
|         assertTrue(filterList.grep( Number )== [2, 1, 3, 4, 5, 6, 76]) |         assertTrue(filterList.grep( Number )== [2, 1, 3, 4, 5, 6, 76]) | ||||||
|          | 
 | ||||||
|         assertTrue(filterList.grep{ it> 6 }== [76]) |         assertTrue(filterList.grep{ it> 6 }== [76]) | ||||||
| 
 | 
 | ||||||
|         def conditionList = [2, 1, 3, 4, 5, 6, 76] |         def conditionList = [2, 1, 3, 4, 5, 6, 76] | ||||||
|          | 
 | ||||||
|         assertFalse(conditionList.every{ it < 6}) |         assertFalse(conditionList.every{ it < 6}) | ||||||
| 
 | 
 | ||||||
|         assertTrue(conditionList.any{ it%2 == 0}) |         assertTrue(conditionList.any{ it%2 == 0}) | ||||||
| @ -165,7 +165,7 @@ class ListTest{ | |||||||
| 
 | 
 | ||||||
|         def strList = ["na", "ppp", "as"] |         def strList = ["na", "ppp", "as"] | ||||||
|         assertTrue(strList.max() == "ppp") |         assertTrue(strList.max() == "ppp") | ||||||
|          | 
 | ||||||
|         Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1} |         Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1} | ||||||
|         def numberList = [3, 2, 0, 7] |         def numberList = [3, 2, 0, 7] | ||||||
|         assertTrue(numberList.min(minc) == 0) |         assertTrue(numberList.min(minc) == 0) | ||||||
|  | |||||||
| @ -0,0 +1,58 @@ | |||||||
|  | package com.baeldung.lists | ||||||
|  | 
 | ||||||
|  | import com.baeldung.Person | ||||||
|  | import org.junit.Test | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.* | ||||||
|  | 
 | ||||||
|  | class ListUnitTest { | ||||||
|  | 
 | ||||||
|  |     private final personList = [ | ||||||
|  |       new Person("Regina", "Fitzpatrick", 25), | ||||||
|  |       new Person("Abagail", "Ballard", 26), | ||||||
|  |       new Person("Lucian", "Walter", 30), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void whenListContainsElement_thenCheckReturnsTrue() { | ||||||
|  |         def list = ['a', 'b', 'c'] | ||||||
|  | 
 | ||||||
|  |         assertTrue(list.indexOf('a') > -1) | ||||||
|  |         assertTrue(list.contains('a')) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void whenListContainsElement_thenCheckWithMembershipOperatorReturnsTrue() { | ||||||
|  |         def list = ['a', 'b', 'c'] | ||||||
|  | 
 | ||||||
|  |         assertTrue('a' in list) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenListOfPerson_whenUsingStreamMatching_thenShouldEvaluateList() { | ||||||
|  |         assertTrue(personList.stream().anyMatch {it.age > 20}) | ||||||
|  |         assertFalse(personList.stream().allMatch {it.age < 30}) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenListOfPerson_whenUsingCollectionMatching_thenShouldEvaluateList() { | ||||||
|  |         assertTrue(personList.any {it.age > 20}) | ||||||
|  |         assertFalse(personList.every {it.age < 30}) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements() { | ||||||
|  |         assertTrue(personList.stream().filter {it.age > 20}.findAny().isPresent()) | ||||||
|  |         assertFalse(personList.stream().filter {it.age > 30}.findAny().isPresent()) | ||||||
|  |         assertTrue(personList.stream().filter {it.age > 20}.findAll().size() == 3) | ||||||
|  |         assertTrue(personList.stream().filter {it.age > 30}.findAll().isEmpty()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenListOfPerson_whenUsingCollectionFind_thenShouldReturnMatchingElements() { | ||||||
|  |         assertNotNull(personList.find {it.age > 20}) | ||||||
|  |         assertNull(personList.find {it.age > 30}) | ||||||
|  |         assertTrue(personList.findAll {it.age > 20}.size() == 3) | ||||||
|  |         assertTrue(personList.findAll {it.age > 30}.isEmpty()) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,10 +1,18 @@ | |||||||
| package com.baeldung.map | package com.baeldung.map | ||||||
| 
 | 
 | ||||||
| import static org.junit.Assert.* | import com.baeldung.Person | ||||||
| import org.junit.Test | import org.junit.Test | ||||||
| 
 | 
 | ||||||
|  | import static org.junit.Assert.* | ||||||
|  | 
 | ||||||
| class MapUnitTest { | class MapUnitTest { | ||||||
| 
 | 
 | ||||||
|  |     private final personMap = [ | ||||||
|  |       Regina : new Person("Regina", "Fitzpatrick", 25), | ||||||
|  |       Abagail: new Person("Abagail", "Ballard", 26), | ||||||
|  |       Lucian : new Person("Lucian", "Walter", 30) | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|     @Test |     @Test | ||||||
|     void whenUsingEach_thenMapIsIterated() { |     void whenUsingEach_thenMapIsIterated() { | ||||||
|         def map = [ |         def map = [ | ||||||
| @ -63,7 +71,7 @@ class MapUnitTest { | |||||||
|             'FF6347' : 'Tomato', |             'FF6347' : 'Tomato', | ||||||
|             'FF4500' : 'Orange Red' |             'FF4500' : 'Orange Red' | ||||||
|         ] |         ] | ||||||
|          | 
 | ||||||
|         map.eachWithIndex { key, val, index -> |         map.eachWithIndex { key, val, index -> | ||||||
|             def indent = ((index == 0 || index % 2 == 0) ? "   " : "") |             def indent = ((index == 0 || index % 2 == 0) ? "   " : "") | ||||||
|             println "$indent Hex Code: $key = Color Name: $val" |             println "$indent Hex Code: $key = Color Name: $val" | ||||||
| @ -82,4 +90,65 @@ class MapUnitTest { | |||||||
|             println "Hex Code: $entry.key = Color Name: $entry.value" |             println "Hex Code: $entry.key = Color Name: $entry.value" | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void whenMapContainsKeyElement_thenCheckReturnsTrue() { | ||||||
|  |         def map = [a: 'd', b: 'e', c: 'f'] | ||||||
|  | 
 | ||||||
|  |         assertTrue(map.containsKey('a')) | ||||||
|  |         assertFalse(map.containsKey('e')) | ||||||
|  |         assertTrue(map.containsValue('e')) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void whenMapContainsKeyElement_thenCheckByMembershipReturnsTrue() { | ||||||
|  |         def map = [a: 'd', b: 'e', c: 'f'] | ||||||
|  | 
 | ||||||
|  |         assertTrue('a' in map) | ||||||
|  |         assertFalse('f' in map) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void whenMapContainsFalseBooleanValues_thenCheckReturnsFalse() { | ||||||
|  |         def map = [a: true, b: false, c: null] | ||||||
|  | 
 | ||||||
|  |         assertTrue(map.containsKey('b')) | ||||||
|  |         assertTrue('a' in map) | ||||||
|  |         assertFalse('b' in map) | ||||||
|  |         assertFalse('c' in map) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap() { | ||||||
|  |         assertTrue(personMap.keySet().stream().anyMatch {it == "Regina"}) | ||||||
|  |         assertFalse(personMap.keySet().stream().allMatch {it == "Albert"}) | ||||||
|  |         assertFalse(personMap.values().stream().allMatch {it.age < 30}) | ||||||
|  |         assertTrue(personMap.entrySet().stream().anyMatch {it.key == "Abagail" && it.value.lastname == "Ballard"}) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap() { | ||||||
|  |         assertTrue(personMap.keySet().any {it == "Regina"}) | ||||||
|  |         assertFalse(personMap.keySet().every {it == "Albert"}) | ||||||
|  |         assertFalse(personMap.values().every {it.age < 30}) | ||||||
|  |         assertTrue(personMap.any {firstname, person -> firstname == "Abagail" && person.lastname == "Ballard"}) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenMapOfPerson_whenUsingCollectionFind_thenShouldReturnElements() { | ||||||
|  |         assertNotNull(personMap.find {it.key == "Abagail" && it.value.lastname == "Ballard"}) | ||||||
|  |         assertTrue(personMap.findAll {it.value.age > 20}.size() == 3) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void givenMapOfPerson_whenUsingStreamFind_thenShouldReturnElements() { | ||||||
|  |         assertTrue( | ||||||
|  |           personMap.entrySet().stream() | ||||||
|  |             .filter {it.key == "Abagail" && it.value.lastname == "Ballard"} | ||||||
|  |             .findAny().isPresent()) | ||||||
|  |         assertTrue( | ||||||
|  |           personMap.entrySet().stream() | ||||||
|  |             .filter {it.value.age > 20} | ||||||
|  |             .findAll().size() == 3) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,16 @@ | |||||||
|  | package com.baeldung.set | ||||||
|  | 
 | ||||||
|  | import org.junit.Test | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.assertTrue | ||||||
|  | 
 | ||||||
|  | class SetUnitTest { | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     void whenSetContainsElement_thenCheckReturnsTrue() { | ||||||
|  |         def set = ['a', 'b', 'c'] as Set | ||||||
|  | 
 | ||||||
|  |         assertTrue(set.contains('a')) | ||||||
|  |         assertTrue('a' in set) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | package com.baeldung.jlink; | ||||||
|  | 
 | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | 
 | ||||||
|  | public class HelloWorld { | ||||||
|  | 
 | ||||||
|  |     private static final Logger LOG = Logger.getLogger(HelloWorld.class.getName()); | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         LOG.info("Hello World!"); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								core-java-11/src/modules/jlinkModule/module-info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								core-java-11/src/modules/jlinkModule/module-info.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | module jlinkModule { | ||||||
|  |     requires java.logging; | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								core-java-12/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								core-java-12/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||||
|  | 		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  | 		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  | 	<modelVersion>4.0.0</modelVersion> | ||||||
|  | 	<groupId>com.baeldung</groupId> | ||||||
|  | 	<artifactId>core-java-12</artifactId> | ||||||
|  | 	<version>0.1.0-SNAPSHOT</version> | ||||||
|  | 	<name>core-java-12</name> | ||||||
|  | 	<packaging>jar</packaging> | ||||||
|  | 	<url>http://maven.apache.org</url> | ||||||
|  | 
 | ||||||
|  | 	<parent> | ||||||
|  | 		<groupId>com.baeldung</groupId> | ||||||
|  | 		<artifactId>parent-modules</artifactId> | ||||||
|  | 		<version>1.0.0-SNAPSHOT</version> | ||||||
|  | 	</parent> | ||||||
|  | 
 | ||||||
|  | 	<dependencies> | ||||||
|  | 		<dependency> | ||||||
|  | 			<groupId>org.assertj</groupId> | ||||||
|  | 			<artifactId>assertj-core</artifactId> | ||||||
|  | 			<version>${assertj.version}</version> | ||||||
|  | 			<scope>test</scope> | ||||||
|  | 		</dependency> | ||||||
|  | 	</dependencies> | ||||||
|  | 
 | ||||||
|  | 	<build> | ||||||
|  | 		<plugins> | ||||||
|  | 			<plugin> | ||||||
|  | 				<groupId>org.apache.maven.plugins</groupId> | ||||||
|  | 				<artifactId>maven-compiler-plugin</artifactId> | ||||||
|  | 				<version>${maven-compiler-plugin.version}</version> | ||||||
|  | 				<configuration> | ||||||
|  | 					<source>${maven.compiler.source.version}</source> | ||||||
|  | 					<target>${maven.compiler.target.version}</target> | ||||||
|  | 				</configuration> | ||||||
|  | 			</plugin> | ||||||
|  | 		</plugins> | ||||||
|  | 	</build> | ||||||
|  | 
 | ||||||
|  | 	<properties> | ||||||
|  | 		<maven.compiler.source.version>12</maven.compiler.source.version> | ||||||
|  | 		<maven.compiler.target.version>12</maven.compiler.target.version> | ||||||
|  | 		<assertj.version>3.6.1</assertj.version> | ||||||
|  | 	</properties> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -0,0 +1,77 @@ | |||||||
|  | package com.baeldung.collectors; | ||||||
|  | 
 | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Objects; | ||||||
|  | 
 | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | import static java.util.stream.Collectors.maxBy; | ||||||
|  | import static java.util.stream.Collectors.minBy; | ||||||
|  | import static java.util.stream.Collectors.teeing; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Unit tests for collectors additions in Java 12. | ||||||
|  |  */ | ||||||
|  | public class CollectorsUnitTest { | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void whenTeeing_ItShouldCombineTheResultsAsExpected() { | ||||||
|  | 		List<Integer> numbers = Arrays.asList(42, 4, 2, 24); | ||||||
|  | 		Range range = numbers.stream() | ||||||
|  | 				.collect(teeing( | ||||||
|  | 						minBy(Integer::compareTo), | ||||||
|  | 						maxBy(Integer::compareTo), | ||||||
|  | 						(min, max) -> new Range(min.orElse(null), max.orElse(null)) | ||||||
|  | 				)); | ||||||
|  | 
 | ||||||
|  | 		assertThat(range).isEqualTo(new Range(2, 42)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Represents a closed range of numbers between {@link #min} and | ||||||
|  | 	 * {@link #max}, both inclusive. | ||||||
|  | 	 */ | ||||||
|  | 	private static class Range { | ||||||
|  | 
 | ||||||
|  | 		private final Integer min; | ||||||
|  | 
 | ||||||
|  | 		private final Integer max; | ||||||
|  | 
 | ||||||
|  | 		Range(Integer min, Integer max) { | ||||||
|  | 			this.min = min; | ||||||
|  | 			this.max = max; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		Integer getMin() { | ||||||
|  | 			return min; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		Integer getMax() { | ||||||
|  | 			return max; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Override | ||||||
|  | 		public boolean equals(Object o) { | ||||||
|  | 			if (this == o) return true; | ||||||
|  | 			if (o == null || getClass() != o.getClass()) return false; | ||||||
|  | 			Range range = (Range) o; | ||||||
|  | 			return Objects.equals(getMin(), range.getMin()) && | ||||||
|  | 					Objects.equals(getMax(), range.getMax()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Override | ||||||
|  | 		public int hashCode() { | ||||||
|  | 			return Objects.hash(getMin(), getMax()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Override | ||||||
|  | 		public String toString() { | ||||||
|  | 			return "Range{" + | ||||||
|  | 					"min=" + min + | ||||||
|  | 					", max=" + max + | ||||||
|  | 					'}'; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -124,11 +124,44 @@ public class Java8SortUnitTest { | |||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { |     public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { | ||||||
|          |  | ||||||
|         final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); |         final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); | ||||||
|         final Comparator<Human> nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName()); |         final Comparator<Human> nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName()); | ||||||
|          |          | ||||||
|         final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList()); |         final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList()); | ||||||
|         Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); |         Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public final void givenStreamComparatorOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { | ||||||
|  |         final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); | ||||||
|  | 
 | ||||||
|  |         final List<Human> sortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName)).collect(Collectors.toList()); | ||||||
|  |         Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public final void givenStreamNaturalOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() { | ||||||
|  |         final List<String> letters = Lists.newArrayList("B", "A", "C"); | ||||||
|  | 
 | ||||||
|  |         final List<String> reverseSortedLetters = letters.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()); | ||||||
|  |         Assert.assertThat(reverseSortedLetters.get(0), equalTo("C")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public final void givenStreamCustomOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() { | ||||||
|  |         final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); | ||||||
|  |         final Comparator<Human> reverseNameComparator = (h1, h2) -> h2.getName().compareTo(h1.getName()); | ||||||
|  | 
 | ||||||
|  |         final List<Human> reverseSortedHumans = humans.stream().sorted(reverseNameComparator).collect(Collectors.toList()); | ||||||
|  |         Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public final void givenStreamComparatorOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() { | ||||||
|  |         final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); | ||||||
|  | 
 | ||||||
|  |         final List<Human> reverseSortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName, Comparator.reverseOrder())).collect(Collectors.toList()); | ||||||
|  |         Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,29 @@ | |||||||
|  | package com.baeldung.socket.read; | ||||||
|  | 
 | ||||||
|  | import java.net.*; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | import java.io.*;  | ||||||
|  | 
 | ||||||
|  | public class Client { | ||||||
|  |      | ||||||
|  |     public void runClient(String ip, int port) { | ||||||
|  |         try { | ||||||
|  |             Socket socket = new Socket(ip, port); | ||||||
|  |             System.out.println("Connected to server ..."); | ||||||
|  |             DataInputStream in = new DataInputStream(System.in); | ||||||
|  |             DataOutputStream out = new DataOutputStream(socket.getOutputStream()); | ||||||
|  |              | ||||||
|  |             char type = 's'; // s for string | ||||||
|  |             int length = 29; | ||||||
|  |             String data = "This is a string of length 29"; | ||||||
|  |             byte[] dataInBytes = data.getBytes(StandardCharsets.UTF_8);          | ||||||
|  |             //Sending data in TLV format         | ||||||
|  |             out.writeChar(type); | ||||||
|  |             out.writeInt(length); | ||||||
|  |             out.write(dataInBytes); | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,49 @@ | |||||||
|  | package com.baeldung.socket.read; | ||||||
|  | 
 | ||||||
|  | import java.net.*; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | import java.io.*;  | ||||||
|  | 
 | ||||||
|  | public class Server { | ||||||
|  |      | ||||||
|  |     public void runServer(int port) { | ||||||
|  |         //Start the server and wait for connection | ||||||
|  |         try { | ||||||
|  |             ServerSocket server = new ServerSocket(port); | ||||||
|  |             System.out.println("Server Started. Waiting for connection ..."); | ||||||
|  |             Socket socket = server.accept(); | ||||||
|  |             System.out.println("Got connection from client."); | ||||||
|  |             //Get input stream from socket variable and convert the same to DataInputStream | ||||||
|  |             DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); | ||||||
|  |             //Read type and length of data | ||||||
|  |             char dataType = in.readChar(); | ||||||
|  |             int length = in.readInt(); | ||||||
|  |             System.out.println("Type : "+dataType); | ||||||
|  |             System.out.println("Lenght :"+length); | ||||||
|  |             if(dataType == 's') { | ||||||
|  |                 //Read String data in bytes | ||||||
|  |                 byte[] messageByte = new byte[length]; | ||||||
|  |                 boolean end = false; | ||||||
|  |                 StringBuilder dataString = new StringBuilder(length); | ||||||
|  |                 int totalBytesRead = 0; | ||||||
|  |                 //We need to run while loop, to read all data in that stream | ||||||
|  |                 while(!end) { | ||||||
|  |                     int currentBytesRead = in.read(messageByte); | ||||||
|  |                     totalBytesRead = currentBytesRead + totalBytesRead; | ||||||
|  |                     if(totalBytesRead <= length) { | ||||||
|  |                         dataString.append(new String(messageByte,0,currentBytesRead,StandardCharsets.UTF_8)); | ||||||
|  |                     } else { | ||||||
|  |                         dataString.append(new String(messageByte,0,length - totalBytesRead + currentBytesRead,StandardCharsets.UTF_8)); | ||||||
|  |                     } | ||||||
|  |                     if(dataString.length()>=length) { | ||||||
|  |                         end = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 System.out.println("Read "+length+" bytes of message from client. Message = "+dataString); | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | package com.baeldung.socket.read; | ||||||
|  | 
 | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | 
 | ||||||
|  | public class SocketReadAllDataLiveTest { | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void givenServerAndClient_whenClientSendsAndServerReceivesData_thenCorrect() { | ||||||
|  |         //Run server in new thread | ||||||
|  |         Runnable runnable1 = () -> { runServer(); }; | ||||||
|  |         Thread thread1 = new Thread(runnable1); | ||||||
|  |         thread1.start(); | ||||||
|  |         //Wait for 10 seconds  | ||||||
|  |         try { | ||||||
|  |             TimeUnit.SECONDS.sleep(10); | ||||||
|  |         } catch (InterruptedException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |         //Run client in a new thread | ||||||
|  |         Runnable runnable2 = () -> { runClient(); }; | ||||||
|  |         Thread thread2 = new Thread(runnable2); | ||||||
|  |         thread2.start(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public static void runServer() { | ||||||
|  |         //Run Server | ||||||
|  |         Server server = new Server(); | ||||||
|  |         server.runServer(5555); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public static void runClient() { | ||||||
|  |         //Run Client | ||||||
|  |         Client client = new Client(); | ||||||
|  |         client.runClient("127.0.0.1", 5555); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | package com.baeldung.scope | ||||||
|  | 
 | ||||||
|  | data class Student(var studentId: String = "", var name: String = "", var surname: String = "") { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data class Teacher(var teacherId: Int = 0, var name: String = "", var surname: String = "") { | ||||||
|  |     fun setId(anId: Int): Teacher = apply { teacherId = anId } | ||||||
|  |     fun setName(aName: String): Teacher = apply { name = aName } | ||||||
|  |     fun setSurname(aSurname: String): Teacher = apply { surname = aSurname } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data class Headers(val headerInfo: String) | ||||||
|  | 
 | ||||||
|  | data class Response(val headers: Headers) | ||||||
|  | 
 | ||||||
|  | data class RestClient(val url: String) { | ||||||
|  |     fun getResponse() = Response(Headers("some header info")) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data class BankAccount(val id: Int) { | ||||||
|  |     fun checkAuthorization(username: String) = Unit | ||||||
|  |     fun addPayee(payee: String) = Unit | ||||||
|  |     fun makePayment(paymentDetails: String) = Unit | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -4,7 +4,7 @@ import org.junit.Test | |||||||
| import kotlin.test.assertTrue | import kotlin.test.assertTrue | ||||||
| import kotlin.test.assertFalse | import kotlin.test.assertFalse | ||||||
| 
 | 
 | ||||||
| class ValidationUnitTest { | class ValidationTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     fun whenAmountIsOneAndNameIsAlice_thenTrue() { |     fun whenAmountIsOneAndNameIsAlice_thenTrue() { | ||||||
|  | |||||||
| @ -1,42 +0,0 @@ | |||||||
| package com.baeldung.annotations |  | ||||||
| 
 |  | ||||||
| import org.junit.jupiter.api.Assertions.assertTrue |  | ||||||
| import org.junit.jupiter.api.Assertions.assertFalse |  | ||||||
| import org.junit.jupiter.api.Test |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class ValidationUnitTest { |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     fun whenAmountIsOneAndNameIsAlice_thenTrue() { |  | ||||||
|         assertTrue(Validator().isValid(Item(1f, "Alice"))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     fun whenAmountIsOneAndNameIsBob_thenTrue() { |  | ||||||
|         assertTrue(Validator().isValid(Item(1f, "Bob"))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     fun whenAmountIsMinusOneAndNameIsAlice_thenFalse() { |  | ||||||
|         assertFalse(Validator().isValid(Item(-1f, "Alice"))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     fun whenAmountIsMinusOneAndNameIsBob_thenFalse() { |  | ||||||
|         assertFalse(Validator().isValid(Item(-1f, "Bob"))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     fun whenAmountIsOneAndNameIsTom_thenFalse() { |  | ||||||
|         assertFalse(Validator().isValid(Item(1f, "Tom"))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     fun whenAmountIsMinusOneAndNameIsTom_thenFalse() { |  | ||||||
|         assertFalse(Validator().isValid(Item(-1f, "Tom"))) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -0,0 +1,143 @@ | |||||||
|  | package com.baeldung.scope | ||||||
|  | 
 | ||||||
|  | import org.junit.Test | ||||||
|  | import kotlin.test.assertTrue | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ScopeFunctionsUnitTest { | ||||||
|  | 
 | ||||||
|  |     class Logger { | ||||||
|  | 
 | ||||||
|  |         var called : Boolean = false | ||||||
|  | 
 | ||||||
|  |         fun info(message: String) { | ||||||
|  |             called = true | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         fun wasCalled() = called | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldTransformWhenLetFunctionUsed() { | ||||||
|  |         val stringBuider = StringBuilder() | ||||||
|  |         val numberOfCharacters = stringBuider.let { | ||||||
|  |             it.append("This is a transformation function.") | ||||||
|  |             it.append("It takes a StringBuilder instance and returns the number of characters in the generated String") | ||||||
|  |             it.length | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             numberOfCharacters == 128 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldHandleNullabilityWhenLetFunctionUsed() { | ||||||
|  | 
 | ||||||
|  |         val message: String? = "hello there!" | ||||||
|  |         val charactersInMessage = message?.let { | ||||||
|  |             "At this point is safe to reference the variable. Let's print the message: $it" | ||||||
|  |         } ?: "default value" | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!") | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         val aNullMessage = null | ||||||
|  |         val thisIsNull = aNullMessage?.let { | ||||||
|  |             "At this point it would be safe to reference the variable. But it will not really happen because it is null. Let's reference: $it" | ||||||
|  |         } ?: "default value" | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             thisIsNull.equals("default value") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldInitializeObjectWhenUsingApply() { | ||||||
|  |         val aStudent = Student().apply { | ||||||
|  |             studentId = "1234567" | ||||||
|  |             name = "Mary" | ||||||
|  |             surname = "Smith" | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             aStudent.name.equals("Mary") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldAllowBuilderStyleObjectDesignWhenApplyUsedInClassMethods() { | ||||||
|  |         val teacher = Teacher() | ||||||
|  |             .setId(1000) | ||||||
|  |             .setName("Martha") | ||||||
|  |             .setSurname("Spector") | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             teacher.surname.equals("Spector") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldAllowSideEffectWhenUsingAlso() { | ||||||
|  |         val restClient = RestClient("http://www.someurl.com") | ||||||
|  | 
 | ||||||
|  |         val logger = Logger() | ||||||
|  | 
 | ||||||
|  |         val headers = restClient | ||||||
|  |             .getResponse() | ||||||
|  |             .also { logger.info(it.toString()) } | ||||||
|  |             .headers | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             logger.wasCalled() && headers.headerInfo.equals("some header info") | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldInitializeFieldWhenAlsoUsed() { | ||||||
|  |         val aStudent = Student().also { it.name = "John"} | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             aStudent.name.equals("John") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldLogicallyGroupObjectCallsWhenUsingWith() { | ||||||
|  |         val bankAccount = BankAccount(1000) | ||||||
|  |         with (bankAccount) { | ||||||
|  |             checkAuthorization("someone") | ||||||
|  |             addPayee("some payee") | ||||||
|  |             makePayment("payment information") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldConvertObjectWhenRunUsed() { | ||||||
|  |         val stringBuider = StringBuilder() | ||||||
|  |         val numberOfCharacters = stringBuider.run { | ||||||
|  |             append("This is a transformation function.") | ||||||
|  |             append("It takes a StringBuilder instance and returns the number of characters in the generated String") | ||||||
|  |             length | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             numberOfCharacters == 128 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun shouldHandleNullabilityWhenRunIsUsed() { | ||||||
|  |         val message: String? = "hello there!" | ||||||
|  |         val charactersInMessage = message?.run { | ||||||
|  |             "At this point is safe to reference the variable. Let's print the message: $this" | ||||||
|  |         } ?: "default value" | ||||||
|  | 
 | ||||||
|  |         assertTrue { | ||||||
|  |             charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -11,3 +11,5 @@ | |||||||
| - [Convert JSON to a Map Using Gson](https://www.baeldung.com/gson-json-to-map) | - [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) | - [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) | - [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) | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								jackson-2/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								jackson-2/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | *.class | ||||||
|  | 
 | ||||||
|  | #folders# | ||||||
|  | /target | ||||||
|  | /neoDb* | ||||||
|  | /data | ||||||
|  | /src/main/webapp/WEB-INF/classes | ||||||
|  | */META-INF/* | ||||||
|  | 
 | ||||||
|  | # Packaged files # | ||||||
|  | *.jar | ||||||
|  | *.war | ||||||
|  | *.ear | ||||||
							
								
								
									
										9
									
								
								jackson-2/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								jackson-2/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | ========= | ||||||
|  | 
 | ||||||
|  | ## Jackson Cookbooks and Examples | ||||||
|  | 
 | ||||||
|  | ###The Course | ||||||
|  | The "REST With Spring" Classes: http://bit.ly/restwithspring | ||||||
|  | 
 | ||||||
|  | ### Relevant Articles:  | ||||||
|  | - [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field) | ||||||
							
								
								
									
										52
									
								
								jackson-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								jackson-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <artifactId>jackson-2</artifactId> | ||||||
|  |     <version>0.1-SNAPSHOT</version> | ||||||
|  |     <name>jackson-2</name> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-java</artifactId> | ||||||
|  |         <version>0.0.1-SNAPSHOT</version> | ||||||
|  |         <relativePath>../parent-java</relativePath> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  | 
 | ||||||
|  |         <!-- marshalling --> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.fasterxml.jackson.core</groupId> | ||||||
|  |             <artifactId>jackson-databind</artifactId> | ||||||
|  |             <version>${jackson.version}</version> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         <!-- test scoped --> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.assertj</groupId> | ||||||
|  |             <artifactId>assertj-core</artifactId> | ||||||
|  |             <version>${assertj.version}</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  |     <build> | ||||||
|  |         <finalName>jackson-2</finalName> | ||||||
|  |         <resources> | ||||||
|  |             <resource> | ||||||
|  |                 <directory>src/main/resources</directory> | ||||||
|  |                 <filtering>true</filtering> | ||||||
|  |             </resource> | ||||||
|  |         </resources> | ||||||
|  |     </build> | ||||||
|  | 
 | ||||||
|  |     <properties> | ||||||
|  | 
 | ||||||
|  |         <!-- testing --> | ||||||
|  |         <assertj.version>3.11.0</assertj.version> | ||||||
|  |     </properties> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
							
								
								
									
										13
									
								
								jackson-2/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								jackson-2/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <configuration> | ||||||
|  |     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n | ||||||
|  |             </pattern> | ||||||
|  |         </encoder> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <root level="INFO"> | ||||||
|  |         <appender-ref ref="STDOUT" /> | ||||||
|  |     </root> | ||||||
|  | </configuration> | ||||||
							
								
								
									
										29
									
								
								java-dates-2/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								java-dates-2/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | *.class | ||||||
|  | 
 | ||||||
|  | 0.* | ||||||
|  | 
 | ||||||
|  | #folders# | ||||||
|  | /target | ||||||
|  | /neoDb* | ||||||
|  | /data | ||||||
|  | /src/main/webapp/WEB-INF/classes | ||||||
|  | */META-INF/* | ||||||
|  | .resourceCache | ||||||
|  | 
 | ||||||
|  | # Packaged files # | ||||||
|  | *.jar | ||||||
|  | *.war | ||||||
|  | *.ear | ||||||
|  | 
 | ||||||
|  | # Files generated by integration tests | ||||||
|  | *.txt | ||||||
|  | backup-pom.xml | ||||||
|  | /bin/ | ||||||
|  | /temp | ||||||
|  | 
 | ||||||
|  | #IntelliJ specific | ||||||
|  | .idea/ | ||||||
|  | *.iml | ||||||
|  | 
 | ||||||
|  | #jenv | ||||||
|  | .java-version | ||||||
							
								
								
									
										55
									
								
								java-dates-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								java-dates-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <groupId>com.baeldung</groupId> | ||||||
|  |     <artifactId>java-dates-2</artifactId> | ||||||
|  |     <version>0.1.0-SNAPSHOT</version> | ||||||
|  |     <packaging>jar</packaging> | ||||||
|  |     <name>java-dates-2</name> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-java</artifactId> | ||||||
|  |         <version>0.0.1-SNAPSHOT</version> | ||||||
|  |         <relativePath>../parent-java</relativePath> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  |         <!-- test scoped --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.assertj</groupId> | ||||||
|  |             <artifactId>assertj-core</artifactId> | ||||||
|  |             <version>${assertj.version}</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  |     <build> | ||||||
|  |         <finalName>java-dates-2</finalName> | ||||||
|  |         <resources> | ||||||
|  |             <resource> | ||||||
|  |                 <directory>src/main/resources</directory> | ||||||
|  |                 <filtering>true</filtering> | ||||||
|  |             </resource> | ||||||
|  |         </resources> | ||||||
|  | 
 | ||||||
|  |         <plugins> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|  |                 <artifactId>maven-compiler-plugin</artifactId> | ||||||
|  |                 <version>${maven-compiler-plugin.version}</version> | ||||||
|  |                 <configuration> | ||||||
|  |                     <source>${maven.compiler.source}</source> | ||||||
|  |                     <target>${maven.compiler.target}</target> | ||||||
|  |                 </configuration> | ||||||
|  |             </plugin> | ||||||
|  |         </plugins> | ||||||
|  |     </build> | ||||||
|  | 
 | ||||||
|  |     <properties> | ||||||
|  |         <!-- testing --> | ||||||
|  |         <assertj.version>3.6.1</assertj.version> | ||||||
|  |         <maven.compiler.source>1.9</maven.compiler.source> | ||||||
|  |         <maven.compiler.target>1.9</maven.compiler.target> | ||||||
|  |     </properties> | ||||||
|  | </project> | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | package com.baeldung.xmlgregoriancalendar; | ||||||
|  | 
 | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | import javax.xml.datatype.DatatypeConfigurationException; | ||||||
|  | import javax.xml.datatype.DatatypeConstants; | ||||||
|  | import javax.xml.datatype.DatatypeFactory; | ||||||
|  | import javax.xml.datatype.XMLGregorianCalendar; | ||||||
|  | import java.time.LocalDate; | ||||||
|  | 
 | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | 
 | ||||||
|  | public class XmlGregorianCalendarConverterUnitTest { | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void fromLocalDateToXMLGregorianCalendar() throws DatatypeConfigurationException { | ||||||
|  |         LocalDate localDate = LocalDate.of(2017, 4, 25); | ||||||
|  |         XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(localDate.toString()); | ||||||
|  | 
 | ||||||
|  |         assertThat(xmlGregorianCalendar.getYear()).isEqualTo(localDate.getYear()); | ||||||
|  |         assertThat(xmlGregorianCalendar.getMonth()).isEqualTo(localDate.getMonthValue()); | ||||||
|  |         assertThat(xmlGregorianCalendar.getDay()).isEqualTo(localDate.getDayOfMonth()); | ||||||
|  |         assertThat(xmlGregorianCalendar.getTimezone()).isEqualTo(DatatypeConstants.FIELD_UNDEFINED); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void fromXMLGregorianCalendarToLocalDate() throws DatatypeConfigurationException { | ||||||
|  |         XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar("2017-04-25"); | ||||||
|  |         LocalDate localDate = LocalDate.of(xmlGregorianCalendar.getYear(), xmlGregorianCalendar.getMonth(), xmlGregorianCalendar.getDay()); | ||||||
|  | 
 | ||||||
|  |         assertThat(localDate.getYear()).isEqualTo(xmlGregorianCalendar.getYear()); | ||||||
|  |         assertThat(localDate.getMonthValue()).isEqualTo(xmlGregorianCalendar.getMonth()); | ||||||
|  |         assertThat(localDate.getDayOfMonth()).isEqualTo(xmlGregorianCalendar.getDay()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -19,6 +19,14 @@ | |||||||
|             <name>exposed</name> |             <name>exposed</name> | ||||||
|             <url>https://dl.bintray.com/kotlin/exposed</url> |             <url>https://dl.bintray.com/kotlin/exposed</url> | ||||||
|         </repository> |         </repository> | ||||||
|  |         <repository> | ||||||
|  |             <snapshots> | ||||||
|  |                 <enabled>false</enabled> | ||||||
|  |             </snapshots> | ||||||
|  |             <id>kotlinx</id> | ||||||
|  |             <name>bintray</name> | ||||||
|  |             <url>https://dl.bintray.com/kotlin/kotlinx</url> | ||||||
|  |         </repository> | ||||||
|     </repositories> |     </repositories> | ||||||
| 
 | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
| @ -112,9 +120,30 @@ | |||||||
|             <version>3.3.0</version> |             <version>3.3.0</version> | ||||||
|             <type>pom</type> |             <type>pom</type> | ||||||
|         </dependency> |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <!-- https://mvnrepository.com/artifact/junit/junit --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>junit</groupId> | ||||||
|  |             <artifactId>junit</artifactId> | ||||||
|  |             <version>${junit.version}</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.google.guava</groupId> | ||||||
|  |             <artifactId>guava</artifactId> | ||||||
|  |             <version>27.1-jre</version> | ||||||
|  |         </dependency> | ||||||
|  |         <!-- https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-collections-immutable --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.jetbrains.kotlinx</groupId> | ||||||
|  |             <artifactId>kotlinx-collections-immutable</artifactId> | ||||||
|  |             <version>0.1</version> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
|  |         <junit.version>4.12</junit.version> | ||||||
|         <mockito-kotlin.version>1.5.0</mockito-kotlin.version> |         <mockito-kotlin.version>1.5.0</mockito-kotlin.version> | ||||||
|         <kodein.version>4.1.0</kodein.version> |         <kodein.version>4.1.0</kodein.version> | ||||||
|         <klaxon.version>3.0.4</klaxon.version> |         <klaxon.version>3.0.4</klaxon.version> | ||||||
|  | |||||||
| @ -0,0 +1,27 @@ | |||||||
|  | package com.baeldung.kotlin.immutable | ||||||
|  | 
 | ||||||
|  | import junit.framework.Assert.assertEquals | ||||||
|  | import kotlinx.collections.immutable.ImmutableList | ||||||
|  | import kotlinx.collections.immutable.immutableListOf | ||||||
|  | import org.junit.Rule | ||||||
|  | import org.junit.Test | ||||||
|  | import org.junit.rules.ExpectedException | ||||||
|  | 
 | ||||||
|  | class KotlinxImmutablesUnitTest{ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   @Rule | ||||||
|  |   @JvmField | ||||||
|  |   var ee : ExpectedException = ExpectedException.none() | ||||||
|  | 
 | ||||||
|  |   @Test | ||||||
|  |   fun givenKICLList_whenAddTried_checkExceptionThrown(){ | ||||||
|  | 
 | ||||||
|  |       val list: ImmutableList<String> = immutableListOf("I", "am", "immutable") | ||||||
|  | 
 | ||||||
|  |       list.add("My new item") | ||||||
|  | 
 | ||||||
|  |       assertEquals(listOf("I", "am", "immutable"), list) | ||||||
|  | 
 | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,73 @@ | |||||||
|  | package com.baeldung.kotlin.immutable | ||||||
|  | 
 | ||||||
|  | import com.google.common.collect.ImmutableList | ||||||
|  | import com.google.common.collect.ImmutableSet | ||||||
|  | import junit.framework.Assert.assertEquals | ||||||
|  | import org.junit.Rule | ||||||
|  | import org.junit.Test | ||||||
|  | import org.junit.rules.ExpectedException | ||||||
|  | 
 | ||||||
|  | class ReadOnlyUnitTest{ | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun givenReadOnlyList_whenCastToMutableList_checkNewElementsAdded(){ | ||||||
|  | 
 | ||||||
|  |         val list: List<String> = listOf("This", "Is", "Totally", "Immutable") | ||||||
|  | 
 | ||||||
|  |         (list as MutableList<String>)[2] = "Not" | ||||||
|  | 
 | ||||||
|  |         assertEquals(listOf("This", "Is", "Not", "Immutable"), list) | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Rule | ||||||
|  |     @JvmField | ||||||
|  |     var ee : ExpectedException = ExpectedException.none() | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun givenImmutableList_whenAddTried_checkExceptionThrown(){ | ||||||
|  | 
 | ||||||
|  |         val list: List<String> = ImmutableList.of("I", "am", "actually", "immutable") | ||||||
|  | 
 | ||||||
|  |         ee.expect(UnsupportedOperationException::class.java) | ||||||
|  | 
 | ||||||
|  |         (list as MutableList<String>).add("Oops") | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun givenMutableList_whenCopiedAndAddTried_checkExceptionThrown(){ | ||||||
|  | 
 | ||||||
|  |         val mutableList : List<String> = listOf("I", "Am", "Definitely", "Immutable") | ||||||
|  | 
 | ||||||
|  |         (mutableList as MutableList<String>)[2] = "100% Not" | ||||||
|  | 
 | ||||||
|  |         assertEquals(listOf("I", "Am", "100% Not", "Immutable"), mutableList) | ||||||
|  | 
 | ||||||
|  |         val list: List<String> = ImmutableList.copyOf(mutableList) | ||||||
|  | 
 | ||||||
|  |         ee.expect(UnsupportedOperationException::class.java) | ||||||
|  | 
 | ||||||
|  |         (list as MutableList<String>)[2] = "Really?" | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun givenImmutableSetBuilder_whenAddTried_checkExceptionThrown(){ | ||||||
|  | 
 | ||||||
|  |         val mutableList : List<String> = listOf("Hello", "Baeldung") | ||||||
|  |         val set: ImmutableSet<String> = ImmutableSet.builder<String>() | ||||||
|  |                 .add("I","am","immutable") | ||||||
|  |                 .addAll(mutableList) | ||||||
|  |                 .build() | ||||||
|  | 
 | ||||||
|  |         assertEquals(setOf("Hello", "Baeldung", "I", "am", "immutable"), set) | ||||||
|  | 
 | ||||||
|  |         ee.expect(UnsupportedOperationException::class.java) | ||||||
|  | 
 | ||||||
|  |         (set as MutableSet<String>).add("Oops") | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -83,13 +83,18 @@ | |||||||
|             <artifactId>jmh-generator-annprocess</artifactId> |             <artifactId>jmh-generator-annprocess</artifactId> | ||||||
|             <version>${openjdk-jmh.version}</version> |             <version>${openjdk-jmh.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>javax.xml.bind</groupId> | ||||||
|  |             <artifactId>jaxb-api</artifactId> | ||||||
|  |             <version>2.3.0</version> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
| 
 | 
 | ||||||
|     <build> |     <build> | ||||||
|         <finalName>hibernate5</finalName> |         <finalName>hibernate5</finalName> | ||||||
|         <resources> |         <resources> | ||||||
|             <resource> |             <resource> | ||||||
|                 <directory>src/main/resources</directory> |                 <directory>src/test/resources</directory> | ||||||
|                 <filtering>true</filtering> |                 <filtering>true</filtering> | ||||||
|             </resource> |             </resource> | ||||||
|         </resources> |         </resources> | ||||||
|  | |||||||
| @ -113,6 +113,7 @@ public class HibernateUtil { | |||||||
|         metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); |         metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); | ||||||
|         metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); |         metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); | ||||||
|         metadataSources.addAnnotatedClass(OfficeEmployee.class); |         metadataSources.addAnnotatedClass(OfficeEmployee.class); | ||||||
|  |         metadataSources.addAnnotatedClass(Post.class); | ||||||
| 
 | 
 | ||||||
|         Metadata metadata = metadataSources.getMetadataBuilder() |         Metadata metadata = metadataSources.getMetadataBuilder() | ||||||
|                 .applyBasicType(LocalDateStringType.INSTANCE) |                 .applyBasicType(LocalDateStringType.INSTANCE) | ||||||
|  | |||||||
| @ -0,0 +1,59 @@ | |||||||
|  | package com.baeldung.hibernate.pojo; | ||||||
|  | 
 | ||||||
|  | import javax.persistence.Entity; | ||||||
|  | import javax.persistence.GeneratedValue; | ||||||
|  | import javax.persistence.Id; | ||||||
|  | import javax.persistence.Table; | ||||||
|  | 
 | ||||||
|  | @Entity | ||||||
|  | @Table(name = "posts") | ||||||
|  | public class Post { | ||||||
|  | 
 | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue | ||||||
|  |     private int id; | ||||||
|  | 
 | ||||||
|  |     private String title; | ||||||
|  | 
 | ||||||
|  |     private String body; | ||||||
|  | 
 | ||||||
|  |     public Post() { } | ||||||
|  | 
 | ||||||
|  |     public Post(String title, String body) { | ||||||
|  |         this.title = title; | ||||||
|  |         this.body = body; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(int id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getTitle() { | ||||||
|  |         return title; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setTitle(String title) { | ||||||
|  |         this.title = title; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getBody() { | ||||||
|  |         return body; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setBody(String body) { | ||||||
|  |         this.body = body; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "Post{" + | ||||||
|  |                 "id=" + id + | ||||||
|  |                 ", title='" + title + '\'' + | ||||||
|  |                 ", body='" + body + '\'' + | ||||||
|  |                 '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | package com.baeldung.hibernate.transaction; | ||||||
|  | 
 | ||||||
|  | import org.hibernate.Session; | ||||||
|  | import org.hibernate.Transaction; | ||||||
|  | import org.hibernate.query.Query; | ||||||
|  | 
 | ||||||
|  | public class PostService { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private Session session; | ||||||
|  | 
 | ||||||
|  |     public PostService(Session session) { | ||||||
|  |         this.session = session; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public void updatePost(String title, String body, int id) { | ||||||
|  |         Transaction txn = session.beginTransaction(); | ||||||
|  |         Query updateQuery = session.createQuery("UPDATE Post p SET p.title = ?1, p.body = ?2 WHERE p.id = ?3"); | ||||||
|  |         updateQuery.setParameter(1, title); | ||||||
|  |         updateQuery.setParameter(2, body); | ||||||
|  |         updateQuery.setParameter(3, id); | ||||||
|  |         updateQuery.executeUpdate(); | ||||||
|  |         txn.commit(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -74,4 +74,6 @@ public class CustomClassIntegrationTest { | |||||||
|         assertEquals("John Smith", result.getEmployeeName()); |         assertEquals("John Smith", result.getEmployeeName()); | ||||||
|         assertEquals("Sales", result.getDepartmentName());    |         assertEquals("Sales", result.getDepartmentName());    | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,57 @@ | |||||||
|  | package com.baeldung.hibernate.transaction; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.hibernate.HibernateUtil; | ||||||
|  | import com.baeldung.hibernate.pojo.Post; | ||||||
|  | import com.baeldung.hibernate.transaction.PostService; | ||||||
|  | import org.hibernate.Session; | ||||||
|  | import org.hibernate.SessionFactory; | ||||||
|  | import org.junit.BeforeClass; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  | 
 | ||||||
|  | import java.io.FileInputStream; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.util.Properties; | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | 
 | ||||||
|  | public class TransactionIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     private static PostService postService; | ||||||
|  |     private static Session session; | ||||||
|  |     private static Logger logger = LoggerFactory.getLogger(TransactionIntegrationTest.class); | ||||||
|  | 
 | ||||||
|  |     @BeforeClass | ||||||
|  |     public static void init() throws IOException { | ||||||
|  |         Properties properties = new Properties(); | ||||||
|  |         properties.setProperty("hibernate.connection.driver_class", "org.h2.Driver"); | ||||||
|  |         properties.setProperty("hibernate.connection.url", "jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1"); | ||||||
|  |         properties.setProperty("hibernate.connection.username", "sa"); | ||||||
|  |         properties.setProperty("hibernate.show_sql", "true"); | ||||||
|  |         properties.setProperty("jdbc.password", ""); | ||||||
|  |         properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); | ||||||
|  |         properties.setProperty("hibernate.hbm2ddl.auto", "create-drop"); | ||||||
|  |         SessionFactory sessionFactory = HibernateUtil.getSessionFactoryByProperties(properties); | ||||||
|  |         session = sessionFactory.openSession(); | ||||||
|  |         postService = new PostService(session); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenTitleAndBody_whenRepositoryUpdatePost_thenUpdatePost() { | ||||||
|  | 
 | ||||||
|  |         Post post = new Post("This is a title", "This is a sample post"); | ||||||
|  |         session.persist(post); | ||||||
|  | 
 | ||||||
|  |         String title = "[UPDATE] Java HowTos"; | ||||||
|  |         String body = "This is an updated posts on Java how-tos"; | ||||||
|  |         postService.updatePost(title, body, post.getId()); | ||||||
|  | 
 | ||||||
|  |         session.refresh(post); | ||||||
|  | 
 | ||||||
|  |         assertEquals(post.getTitle(), title); | ||||||
|  |         assertEquals(post.getBody(), body); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								persistence-modules/spring-data-jpa-2/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								persistence-modules/spring-data-jpa-2/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | ========= | ||||||
|  | 
 | ||||||
|  | ## Spring Data JPA Example Project | ||||||
|  | 
 | ||||||
|  | ### Relevant Articles:  | ||||||
							
								
								
									
										30
									
								
								persistence-modules/spring-data-jpa-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								persistence-modules/spring-data-jpa-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||||
|  |          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  | 	<groupId>com.baeldung</groupId> | ||||||
|  |     <artifactId>spring-data-jpa-2</artifactId> | ||||||
|  | 	<name>spring-data-jpa</name> | ||||||
|  | 	 | ||||||
|  |     <parent> | ||||||
|  |         <artifactId>parent-boot-2</artifactId> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <version>0.0.1-SNAPSHOT</version> | ||||||
|  |         <relativePath>../../parent-boot-2</relativePath> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.boot</groupId> | ||||||
|  |             <artifactId>spring-boot-starter-data-jpa</artifactId> | ||||||
|  |         </dependency> | ||||||
|  |    | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>com.h2database</groupId> | ||||||
|  |             <artifactId>h2</artifactId> | ||||||
|  |         </dependency> | ||||||
|  |        | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -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); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package com.baeldung.entity; | ||||||
|  | 
 | ||||||
|  | import javax.persistence.Entity; | ||||||
|  | import javax.persistence.Id; | ||||||
|  | 
 | ||||||
|  | @Entity | ||||||
|  | public class Fruit { | ||||||
|  | 
 | ||||||
|  |     @Id | ||||||
|  |     private long id; | ||||||
|  |     private String name; | ||||||
|  |     private String color; | ||||||
|  | 
 | ||||||
|  |     public long getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setId(long id) { | ||||||
|  |         this.id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getColor() { | ||||||
|  |         return color; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setColor(String color) { | ||||||
|  |         this.color = color; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | package com.baeldung.repository; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.data.jpa.repository.Modifying; | ||||||
|  | import org.springframework.data.jpa.repository.Query; | ||||||
|  | import org.springframework.data.repository.query.Param; | ||||||
|  | import org.springframework.stereotype.Repository; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.entity.Fruit; | ||||||
|  | 
 | ||||||
|  | @Repository | ||||||
|  | public interface FruitRepository extends JpaRepository<Fruit, Long> { | ||||||
|  | 
 | ||||||
|  |     Long deleteByName(String name); | ||||||
|  | 
 | ||||||
|  |     List<Fruit> deleteByColor(String color); | ||||||
|  | 
 | ||||||
|  |     Long removeByName(String name); | ||||||
|  | 
 | ||||||
|  |     List<Fruit> removeByColor(String color); | ||||||
|  | 
 | ||||||
|  |     @Modifying | ||||||
|  |     @Query("delete from Fruit f where f.name=:name or f.color=:color") | ||||||
|  |     List<Fruit> deleteFruits(@Param("name") String name, @Param("color") String color); | ||||||
|  | } | ||||||
| @ -0,0 +1 @@ | |||||||
|  | spring.jpa.show-sql=true | ||||||
| @ -0,0 +1,77 @@ | |||||||
|  | package com.baeldung.repository; | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | import static org.junit.Assert.assertTrue; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.junit.jupiter.api.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.test.context.jdbc.Sql; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.entity.Fruit; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest | ||||||
|  | class FruitRepositoryIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private FruitRepository fruitRepository; | ||||||
|  | 
 | ||||||
|  |     @Transactional | ||||||
|  |     @Test | ||||||
|  |     @Sql(scripts = { "/test-fruit-data.sql" }) | ||||||
|  |     public void givenFruits_WhenDeletedByColor_DeletedFruitShouldReturn() { | ||||||
|  | 
 | ||||||
|  |         List<Fruit> fruits = fruitRepository.deleteByColor("green"); | ||||||
|  | 
 | ||||||
|  |         assertEquals("number of fruits are not matching", 2, fruits.size()); | ||||||
|  |         fruits.forEach(fruit -> assertEquals("Its not a green fruit", "green", fruit.getColor())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Transactional | ||||||
|  |     @Test | ||||||
|  |     @Sql(scripts = { "/test-fruit-data.sql" }) | ||||||
|  |     public void givenFruits_WhenDeletedByName_DeletedFruitCountShouldReturn() { | ||||||
|  | 
 | ||||||
|  |         Long deletedFruitCount = fruitRepository.deleteByName("apple"); | ||||||
|  | 
 | ||||||
|  |         assertEquals("deleted fruit count is not matching", 1, deletedFruitCount.intValue()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Transactional | ||||||
|  |     @Test | ||||||
|  |     @Sql(scripts = { "/test-fruit-data.sql" }) | ||||||
|  |     public void givenFruits_WhenRemovedByColor_DeletedFruitShouldReturn() { | ||||||
|  | 
 | ||||||
|  |         List<Fruit> fruits = fruitRepository.removeByColor("green"); | ||||||
|  | 
 | ||||||
|  |         assertEquals("number of fruits are not matching", 2, fruits.size()); | ||||||
|  |         fruits.forEach(fruit -> assertEquals("Its not a green fruit", "green", fruit.getColor())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Transactional | ||||||
|  |     @Test | ||||||
|  |     @Sql(scripts = { "/test-fruit-data.sql" }) | ||||||
|  |     public void givenFruits_WhenRemovedByName_DeletedFruitCountShouldReturn() { | ||||||
|  | 
 | ||||||
|  |         Long deletedFruitCount = fruitRepository.removeByName("apple"); | ||||||
|  | 
 | ||||||
|  |         assertEquals("deleted fruit count is not matching", 1, deletedFruitCount.intValue()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Transactional | ||||||
|  |     @Test | ||||||
|  |     @Sql(scripts = { "/test-fruit-data.sql" }) | ||||||
|  |     public void givenFruits_WhenDeletedByColorOrName_DeletedFruitShouldReturn() { | ||||||
|  | 
 | ||||||
|  |         List<Fruit> fruits = fruitRepository.deleteFruits("apple", "green"); | ||||||
|  | 
 | ||||||
|  |         assertEquals("number of fruits are not matching", 3, fruits.size()); | ||||||
|  |         fruits.forEach(fruit -> assertTrue("Its not a green fruit or apple", ("green".equals(fruit.getColor())) || "apple".equals(fruit.getColor()))); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | insert into fruit(id,name,color) values (1,'apple','red'); | ||||||
|  | insert into fruit(id,name,color) values (2,'custard apple','green'); | ||||||
|  | insert into fruit(id,name,color) values (3,'mango','yellow'); | ||||||
|  | insert into fruit(id,name,color) values (4,'guava','green'); | ||||||
							
								
								
									
										5
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								pom.xml
									
									
									
									
									
								
							| @ -377,6 +377,7 @@ | |||||||
|                 <module>core-groovy</module> |                 <module>core-groovy</module> | ||||||
|                 <!-- <module>core-java-10</module> --> <!-- We haven't upgraded to java 10. Fixing in BAEL-10841 --> |                 <!-- <module>core-java-10</module> --> <!-- We haven't upgraded to java 10. Fixing in BAEL-10841 --> | ||||||
|                 <!-- <module>core-java-11</module> --> <!-- We haven't upgraded to java 11. Fixing in BAEL-10841 -->  |                 <!-- <module>core-java-11</module> --> <!-- We haven't upgraded to java 11. Fixing in BAEL-10841 -->  | ||||||
|  |                 <!-- <module>core-java-12</module> --> <!-- We haven't upgraded to java 12. Fixing in BAEL-10841 --> | ||||||
|                 <module>core-java-8</module> |                 <module>core-java-8</module> | ||||||
|                 <!--<module>core-java-9</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> |                 <!--<module>core-java-9</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> | ||||||
|                 <!--<module>core-java-os</module> --> <!-- We haven't upgraded to java 9.--> |                 <!--<module>core-java-os</module> --> <!-- We haven't upgraded to java 9.--> | ||||||
| @ -436,9 +437,11 @@ | |||||||
|                 <module>immutables</module> |                 <module>immutables</module> | ||||||
| 
 | 
 | ||||||
|                 <module>jackson</module> |                 <module>jackson</module> | ||||||
|  |                 <module>jackson-2</module> | ||||||
|                 <module>java-collections-conversions</module> |                 <module>java-collections-conversions</module> | ||||||
|                 <module>java-collections-maps</module> |                 <module>java-collections-maps</module> | ||||||
|                 <!-- <module>java-dates</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> |                 <!-- <module>java-dates</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> | ||||||
|  |                 <!-- <module>java-dates-2</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> | ||||||
|                 <!-- <module>java-ee-8-security-api</module> --> <!-- long running --> |                 <!-- <module>java-ee-8-security-api</module> --> <!-- long running --> | ||||||
|                 <module>java-lite</module> |                 <module>java-lite</module> | ||||||
|                 <module>java-numbers</module> |                 <module>java-numbers</module> | ||||||
| @ -579,6 +582,7 @@ | |||||||
|                 <module>spring-5-reactive-client</module> |                 <module>spring-5-reactive-client</module> | ||||||
|                 <module>spring-5-reactive-oauth</module> |                 <module>spring-5-reactive-oauth</module> | ||||||
|                 <module>spring-5-reactive-security</module> |                 <module>spring-5-reactive-security</module> | ||||||
|  |                 <module>spring-5-reactive-netty</module> | ||||||
|                 <module>spring-5-security</module> |                 <module>spring-5-security</module> | ||||||
|                 <module>spring-5-security-oauth</module> |                 <module>spring-5-security-oauth</module> | ||||||
|                  |                  | ||||||
| @ -1078,6 +1082,7 @@ | |||||||
|                 <module>immutables</module> |                 <module>immutables</module> | ||||||
| 
 | 
 | ||||||
|                 <module>jackson</module> |                 <module>jackson</module> | ||||||
|  |                 <module>jackson-2</module> | ||||||
|                 <module>java-collections-conversions</module> |                 <module>java-collections-conversions</module> | ||||||
|                 <module>java-collections-maps</module> |                 <module>java-collections-maps</module> | ||||||
|                 <!-- <module>java-dates</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> |                 <!-- <module>java-dates</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 --> | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								spring-5-reactive-netty/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								spring-5-reactive-netty/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | # Folders # | ||||||
|  | **/.idea | ||||||
|  | **/target | ||||||
|  | 
 | ||||||
|  | # Files # | ||||||
|  | *.log | ||||||
|  | 
 | ||||||
|  | # Packaged files # | ||||||
|  | *.jar | ||||||
|  | *.war | ||||||
|  | *.ear | ||||||
							
								
								
									
										3
									
								
								spring-5-reactive-netty/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								spring-5-reactive-netty/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | ## Spring 5 Reactive Project With Netty Server | ||||||
|  | 
 | ||||||
|  | Includes configuration options for Netty server. | ||||||
							
								
								
									
										51
									
								
								spring-5-reactive-netty/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								spring-5-reactive-netty/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <groupId>com.baeldung</groupId> | ||||||
|  |     <artifactId>spring-5-reactive-netty</artifactId> | ||||||
|  |     <version>0.0.1-SNAPSHOT</version> | ||||||
|  |     <name>spring-5-reactive-netty</name> | ||||||
|  |     <packaging>jar</packaging> | ||||||
|  |     <description>Spring 5 sample project about reactive web with Netty server</description> | ||||||
|  | 
 | ||||||
|  |     <parent> | ||||||
|  |         <groupId>com.baeldung</groupId> | ||||||
|  |         <artifactId>parent-boot-2</artifactId> | ||||||
|  |         <version>0.0.1-SNAPSHOT</version> | ||||||
|  |         <relativePath>../parent-boot-2</relativePath> | ||||||
|  |     </parent> | ||||||
|  | 
 | ||||||
|  |     <dependencies> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.boot</groupId> | ||||||
|  |             <artifactId>spring-boot-starter-webflux</artifactId> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.projectlombok</groupId> | ||||||
|  |             <artifactId>lombok</artifactId> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.boot</groupId> | ||||||
|  |             <artifactId>spring-boot-devtools</artifactId> | ||||||
|  |             <scope>runtime</scope> | ||||||
|  |         </dependency> | ||||||
|  | 
 | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.springframework.boot</groupId> | ||||||
|  |             <artifactId>spring-boot-starter-test</artifactId> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  | 
 | ||||||
|  |     <build> | ||||||
|  |         <plugins> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.springframework.boot</groupId> | ||||||
|  |                 <artifactId>spring-boot-maven-plugin</artifactId> | ||||||
|  |             </plugin> | ||||||
|  |         </plugins> | ||||||
|  |     </build> | ||||||
|  | </project> | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import io.netty.channel.EventLoopGroup; | ||||||
|  | import io.netty.channel.nio.NioEventLoopGroup; | ||||||
|  | import io.netty.channel.socket.nio.NioServerSocketChannel; | ||||||
|  | import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; | ||||||
|  | import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.context.annotation.Configuration; | ||||||
|  | import org.springframework.context.annotation.Profile; | ||||||
|  | import reactor.netty.http.server.HttpServer; | ||||||
|  | 
 | ||||||
|  | @Configuration | ||||||
|  | @Profile("skipAutoConfig") | ||||||
|  | public class CustomNettyWebServerFactory { | ||||||
|  | 
 | ||||||
|  |     @Bean | ||||||
|  |     public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() { | ||||||
|  |         NettyReactiveWebServerFactory webServerFactory = new NettyReactiveWebServerFactory(); | ||||||
|  |         webServerFactory.addServerCustomizers(new EventLoopNettyCustomizer()); | ||||||
|  |         return webServerFactory; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static class EventLoopNettyCustomizer implements NettyServerCustomizer { | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public HttpServer apply(HttpServer httpServer) { | ||||||
|  |             EventLoopGroup parentGroup = new NioEventLoopGroup(); | ||||||
|  |             EventLoopGroup childGroup = new NioEventLoopGroup(); | ||||||
|  |             return httpServer | ||||||
|  |                     .tcpConfiguration(tcpServer -> tcpServer.bootstrap( | ||||||
|  |                             serverBootstrap -> serverBootstrap.group(parentGroup, childGroup).channel(NioServerSocketChannel.class) | ||||||
|  |                     )); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import reactor.core.publisher.Mono; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/greet") | ||||||
|  | public class GreetingController { | ||||||
|  | 
 | ||||||
|  |     private final GreetingService greetingService; | ||||||
|  | 
 | ||||||
|  |     public GreetingController(GreetingService greetingService) { | ||||||
|  |         this.greetingService = greetingService; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/{name}") | ||||||
|  |     private Mono<String> greet(@PathVariable String name) { | ||||||
|  |         return greetingService.greet(name); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import reactor.core.publisher.Mono; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class GreetingService { | ||||||
|  | 
 | ||||||
|  |     public Mono<String> greet(String name) { | ||||||
|  |         return Mono.just("Greeting " + name); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; | ||||||
|  | import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; | ||||||
|  | import org.springframework.boot.web.server.WebServerFactoryCustomizer; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | import reactor.netty.http.server.HttpServer; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class NettyWebServerFactoryPortCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void customize(NettyReactiveWebServerFactory serverFactory) { | ||||||
|  |         serverFactory.addServerCustomizers(new PortCustomizer(8443)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static class PortCustomizer implements NettyServerCustomizer { | ||||||
|  | 
 | ||||||
|  |         private final int port; | ||||||
|  | 
 | ||||||
|  |         private PortCustomizer(int port) { | ||||||
|  |             this.port = port; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Override | ||||||
|  |         public HttpServer apply(HttpServer httpServer) { | ||||||
|  |             return httpServer.port(port); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; | ||||||
|  | import org.springframework.boot.web.embedded.netty.SslServerCustomizer; | ||||||
|  | import org.springframework.boot.web.server.Http2; | ||||||
|  | import org.springframework.boot.web.server.Ssl; | ||||||
|  | import org.springframework.boot.web.server.WebServerFactoryCustomizer; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class NettyWebServerFactorySslCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void customize(NettyReactiveWebServerFactory serverFactory) { | ||||||
|  |         Ssl ssl = new Ssl(); | ||||||
|  |         ssl.setEnabled(true); | ||||||
|  |         ssl.setKeyStore("classpath:sample.jks"); | ||||||
|  |         ssl.setKeyAlias("alias"); | ||||||
|  |         ssl.setKeyPassword("password"); | ||||||
|  |         ssl.setKeyStorePassword("secret"); | ||||||
|  |         Http2 http2 = new Http2(); | ||||||
|  |         http2.setEnabled(false); | ||||||
|  |         serverFactory.addServerCustomizers(new SslServerCustomizer(ssl, http2, null)); | ||||||
|  |         serverFactory.setPort(8443); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.boot.SpringApplication; | ||||||
|  | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
|  | 
 | ||||||
|  | @SpringBootApplication | ||||||
|  | public class ServerConfigApplication { | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         SpringApplication.run(ServerConfigApplication.class, args); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								spring-5-reactive-netty/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								spring-5-reactive-netty/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <configuration> | ||||||
|  |     <appender name="Console" | ||||||
|  |         class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|  |         <layout class="ch.qos.logback.classic.PatternLayout"> | ||||||
|  |             <Pattern> | ||||||
|  |                 %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable | ||||||
|  |             </Pattern> | ||||||
|  |         </layout> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <appender name="AccessLog" class="ch.qos.logback.core.FileAppender"> | ||||||
|  |         <file>netty-access.log</file> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>%msg%n</pattern> | ||||||
|  |         </encoder> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <appender name="Async" class="ch.qos.logback.classic.AsyncAppender"> | ||||||
|  |         <appender-ref ref="AccessLog"/> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false"> | ||||||
|  |         <appender-ref ref="Console"/> | ||||||
|  |         <appender-ref ref="Async"/> | ||||||
|  |     </logger> | ||||||
|  | 
 | ||||||
|  |     <root level="info"> | ||||||
|  |         <appender-ref ref="Console"/> | ||||||
|  |     </root> | ||||||
|  | </configuration> | ||||||
							
								
								
									
										
											BIN
										
									
								
								spring-5-reactive-netty/src/main/resources/sample.jks
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								spring-5-reactive-netty/src/main/resources/sample.jks
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  | 
 | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; | ||||||
|  | import org.springframework.boot.test.mock.mockito.MockBean; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.springframework.test.web.reactive.server.WebTestClient; | ||||||
|  | import reactor.core.publisher.Mono; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @WebFluxTest | ||||||
|  | public class GreetingControllerIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private WebTestClient webClient; | ||||||
|  | 
 | ||||||
|  |     @MockBean | ||||||
|  |     private GreetingService greetingService; | ||||||
|  | 
 | ||||||
|  |     private final String name = "Baeldung"; | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         when(greetingService.greet(name)).thenReturn(Mono.just("Greeting Baeldung")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void shouldGreet() { | ||||||
|  |         webClient.get().uri("/greet/{name}", name) | ||||||
|  |                  .exchange() | ||||||
|  |                  .expectStatus() | ||||||
|  |                  .isOk() | ||||||
|  |                  .expectBody(String.class) | ||||||
|  |                  .isEqualTo("Greeting Baeldung"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,56 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import io.netty.handler.ssl.SslContext; | ||||||
|  | import io.netty.handler.ssl.SslContextBuilder; | ||||||
|  | import io.netty.handler.ssl.util.InsecureTrustManagerFactory; | ||||||
|  | import javax.net.ssl.SSLException; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; | ||||||
|  | import org.springframework.http.client.reactive.ReactorClientHttpConnector; | ||||||
|  | import org.springframework.test.context.ActiveProfiles; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.springframework.test.web.reactive.server.WebTestClient; | ||||||
|  | import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; | ||||||
|  | import reactor.netty.http.client.HttpClient; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) | ||||||
|  | public class GreetingLiveTest { | ||||||
|  | 
 | ||||||
|  |     private static final String BASE_URL = "https://localhost:8443"; | ||||||
|  | 
 | ||||||
|  |     private WebTestClient webTestClient; | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setup() throws SSLException { | ||||||
|  |         webTestClient = WebTestClient.bindToServer(getConnector()) | ||||||
|  |                                      .baseUrl(BASE_URL) | ||||||
|  |                                      .build(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void shouldGreet() { | ||||||
|  |         final String name = "Baeldung"; | ||||||
|  | 
 | ||||||
|  |         ResponseSpec response = webTestClient.get() | ||||||
|  |                                              .uri("/greet/{name}", name) | ||||||
|  |                                              .exchange(); | ||||||
|  | 
 | ||||||
|  |         response.expectStatus() | ||||||
|  |                 .isOk() | ||||||
|  |                 .expectBody(String.class) | ||||||
|  |                 .isEqualTo("Greeting Baeldung"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private ReactorClientHttpConnector getConnector() throws SSLException { | ||||||
|  |         SslContext sslContext = SslContextBuilder | ||||||
|  |                 .forClient() | ||||||
|  |                 .trustManager(InsecureTrustManagerFactory.INSTANCE) | ||||||
|  |                 .build(); | ||||||
|  |         HttpClient httpClient = HttpClient.create().secure(t -> t.sslContext(sslContext)); | ||||||
|  |         return new ReactorClientHttpConnector(httpClient); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | package com.baeldung.serverconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.test.context.ActiveProfiles; | ||||||
|  | 
 | ||||||
|  | @ActiveProfiles("skipAutoConfig") | ||||||
|  | public class GreetingSkipAutoConfigLiveTest extends GreetingLiveTest { | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								spring-5-reactive-netty/src/test/resources/logback-test.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								spring-5-reactive-netty/src/test/resources/logback-test.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <configuration> | ||||||
|  |     <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|  |         <layout class="ch.qos.logback.classic.PatternLayout"> | ||||||
|  |             <Pattern> | ||||||
|  |                 %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable | ||||||
|  |             </Pattern> | ||||||
|  |         </layout> | ||||||
|  |     </appender> | ||||||
|  |     <root level="info"> | ||||||
|  |         <appender-ref ref="Console"/> | ||||||
|  |     </root> | ||||||
|  | </configuration> | ||||||
| @ -0,0 +1,53 @@ | |||||||
|  | package com.baeldung.web.controller.students; | ||||||
|  | 
 | ||||||
|  | public class Student { | ||||||
|  |      | ||||||
|  |     private long id; | ||||||
|  |     private String firstName; | ||||||
|  |     private String lastName; | ||||||
|  |      | ||||||
|  |     public Student() {} | ||||||
|  |      | ||||||
|  |     public Student(String firstName, String lastName) { | ||||||
|  |         super(); | ||||||
|  |         this.firstName = firstName; | ||||||
|  |         this.lastName = lastName; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public Student(long id, String firstName, String lastName) { | ||||||
|  |         super(); | ||||||
|  |         this.id = id; | ||||||
|  |         this.firstName = firstName; | ||||||
|  |         this.lastName = lastName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     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; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,73 @@ | |||||||
|  | package com.baeldung.web.controller.students; | ||||||
|  | 
 | ||||||
|  | import java.net.URI; | ||||||
|  | import java.net.URISyntaxException; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.web.bind.annotation.DeleteMapping; | ||||||
|  | import org.springframework.web.bind.annotation.GetMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
|  | import org.springframework.web.bind.annotation.PostMapping; | ||||||
|  | import org.springframework.web.bind.annotation.PutMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RequestBody; | ||||||
|  | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
|  | import org.springframework.web.bind.annotation.RestController; | ||||||
|  | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||||||
|  | import com.baeldung.web.controller.students.StudentService; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/students") | ||||||
|  | public class StudentController { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private StudentService service; | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/") | ||||||
|  |     public List<Student> read() { | ||||||
|  |         return service.readAll(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping("/{id}") | ||||||
|  |     public ResponseEntity<Student> read(@PathVariable("id") Long id) { | ||||||
|  |         Student foundStudent = service.read(id); | ||||||
|  |         if (foundStudent == null) { | ||||||
|  |             return ResponseEntity.notFound().build(); | ||||||
|  |         } else { | ||||||
|  |             return ResponseEntity.ok(foundStudent); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @PostMapping("/") | ||||||
|  |     public ResponseEntity<Student> create(@RequestBody Student student) throws URISyntaxException { | ||||||
|  |         Student createdStudent = service.create(student); | ||||||
|  | 
 | ||||||
|  |         URI uri = ServletUriComponentsBuilder.fromCurrentRequest() | ||||||
|  |             .path("/{id}") | ||||||
|  |             .buildAndExpand(createdStudent.getId()) | ||||||
|  |             .toUri(); | ||||||
|  | 
 | ||||||
|  |         return ResponseEntity.created(uri) | ||||||
|  |             .body(createdStudent); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @PutMapping("/{id}") | ||||||
|  |     public ResponseEntity<Student> update(@RequestBody Student student, @PathVariable Long id) { | ||||||
|  |         Student updatedStudent = service.update(id, student); | ||||||
|  |         if (updatedStudent == null) { | ||||||
|  |             return ResponseEntity.notFound().build(); | ||||||
|  |         } else { | ||||||
|  |             return ResponseEntity.ok(updatedStudent); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @DeleteMapping("/{id}") | ||||||
|  |     public ResponseEntity<Object> deleteStudent(@PathVariable Long id) { | ||||||
|  |         service.delete(id); | ||||||
|  | 
 | ||||||
|  |         return ResponseEntity.noContent().build(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | package com.baeldung.web.controller.students; | ||||||
|  | 
 | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.concurrent.atomic.AtomicLong; | ||||||
|  | import java.util.function.Function; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | 
 | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class StudentService { | ||||||
|  |      | ||||||
|  |     // DB repository mock | ||||||
|  |     private Map<Long, Student> repository = Arrays.asList( | ||||||
|  |         new Student[]{ | ||||||
|  |                 new Student(1, "Alan","Turing"), | ||||||
|  |                 new Student(2, "Sebastian","Bach"), | ||||||
|  |                 new Student(3, "Pablo","Picasso"), | ||||||
|  |         }).stream() | ||||||
|  |         .collect(Collectors.toConcurrentMap(s -> s.getId(), Function.identity())); | ||||||
|  |      | ||||||
|  |     // DB id sequence mock | ||||||
|  |     private AtomicLong sequence = new AtomicLong(3); | ||||||
|  |      | ||||||
|  |     public List<Student> readAll() { | ||||||
|  |         return repository.values().stream().collect(Collectors.toList()); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public Student read(Long id) { | ||||||
|  |         return repository.get(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Student create(Student student) { | ||||||
|  |         long key = sequence.incrementAndGet(); | ||||||
|  |         student.setId(key); | ||||||
|  |         repository.put(key, student); | ||||||
|  |         return student; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public Student update(Long id, Student student) { | ||||||
|  |         student.setId(id); | ||||||
|  |         Student oldStudent = repository.replace(id, student); | ||||||
|  |         return oldStudent == null ? null : student; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public void delete(Long id) { | ||||||
|  |         repository.remove(id); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,76 @@ | |||||||
|  | package com.baeldung.web; | ||||||
|  | 
 | ||||||
|  | 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.web.server.MediaTypeNotSupportedStatusException; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.web.controller.students.Student; | ||||||
|  | import com.fasterxml.jackson.databind.ObjectMapper; | ||||||
|  | 
 | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest | ||||||
|  | @AutoConfigureMockMvc | ||||||
|  | public class StudentControllerIntegrationTest { | ||||||
|  | 
 | ||||||
|  |     private static final String STUDENTS_PATH = "/students/"; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MockMvc mockMvc; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenReadAll_thenStatusIsOk() throws Exception { | ||||||
|  |         this.mockMvc.perform(get(STUDENTS_PATH)) | ||||||
|  |             .andExpect(status().isOk()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenReadOne_thenStatusIsOk() throws Exception { | ||||||
|  |         this.mockMvc.perform(get(STUDENTS_PATH + 1)) | ||||||
|  |             .andExpect(status().isOk()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenCreate_thenStatusIsCreated() throws Exception { | ||||||
|  |         Student student = new Student(10, "Albert", "Einstein"); | ||||||
|  |         this.mockMvc.perform(post(STUDENTS_PATH).content(asJsonString(student)) | ||||||
|  |             .contentType(MediaType.APPLICATION_JSON_VALUE)) | ||||||
|  |             .andExpect(status().isCreated()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void whenUpdate_thenStatusIsOk() throws Exception { | ||||||
|  |         Student student = new Student(1, "Nikola", "Tesla"); | ||||||
|  |         this.mockMvc.perform(put(STUDENTS_PATH + 1) | ||||||
|  |             .content(asJsonString(student)) | ||||||
|  |             .contentType(MediaType.APPLICATION_JSON_VALUE)) | ||||||
|  |             .andExpect(status().isOk()); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Test | ||||||
|  |     public void whenDelete_thenStatusIsNoContent() throws Exception { | ||||||
|  |         this.mockMvc.perform(delete(STUDENTS_PATH + 3)) | ||||||
|  |             .andExpect(status().isNoContent()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private String asJsonString(final Object obj) { | ||||||
|  |         try { | ||||||
|  |             return new ObjectMapper().writeValueAsString(obj); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             throw new RuntimeException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user