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 instanceof 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]) | ||||
| 
 | ||||
|         def conditionList = [2, 1, 3, 4, 5, 6, 76] | ||||
|          | ||||
| 
 | ||||
|         assertFalse(conditionList.every{ it < 6}) | ||||
| 
 | ||||
|         assertTrue(conditionList.any{ it%2 == 0}) | ||||
| @ -165,7 +165,7 @@ class ListTest{ | ||||
| 
 | ||||
|         def strList = ["na", "ppp", "as"] | ||||
|         assertTrue(strList.max() == "ppp") | ||||
|          | ||||
| 
 | ||||
|         Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1} | ||||
|         def numberList = [3, 2, 0, 7] | ||||
|         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 | ||||
| 
 | ||||
| import static org.junit.Assert.* | ||||
| import com.baeldung.Person | ||||
| import org.junit.Test | ||||
| 
 | ||||
| import static org.junit.Assert.* | ||||
| 
 | ||||
| class MapUnitTest { | ||||
| 
 | ||||
|     private final personMap = [ | ||||
|       Regina : new Person("Regina", "Fitzpatrick", 25), | ||||
|       Abagail: new Person("Abagail", "Ballard", 26), | ||||
|       Lucian : new Person("Lucian", "Walter", 30) | ||||
|     ] | ||||
| 
 | ||||
|     @Test | ||||
|     void whenUsingEach_thenMapIsIterated() { | ||||
|         def map = [ | ||||
| @ -63,7 +71,7 @@ class MapUnitTest { | ||||
|             'FF6347' : 'Tomato', | ||||
|             'FF4500' : 'Orange Red' | ||||
|         ] | ||||
|          | ||||
| 
 | ||||
|         map.eachWithIndex { key, val, index -> | ||||
|             def indent = ((index == 0 || index % 2 == 0) ? "   " : "") | ||||
|             println "$indent Hex Code: $key = Color Name: $val" | ||||
| @ -82,4 +90,65 @@ class MapUnitTest { | ||||
|             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 | ||||
|     public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { | ||||
|          | ||||
|         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 List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList()); | ||||
|         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.assertFalse | ||||
| 
 | ||||
| class ValidationUnitTest { | ||||
| class ValidationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     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) | ||||
| - [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives) | ||||
| - [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject) | ||||
| - [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										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> | ||||
|             <url>https://dl.bintray.com/kotlin/exposed</url> | ||||
|         </repository> | ||||
|         <repository> | ||||
|             <snapshots> | ||||
|                 <enabled>false</enabled> | ||||
|             </snapshots> | ||||
|             <id>kotlinx</id> | ||||
|             <name>bintray</name> | ||||
|             <url>https://dl.bintray.com/kotlin/kotlinx</url> | ||||
|         </repository> | ||||
|     </repositories> | ||||
| 
 | ||||
|     <dependencies> | ||||
| @ -112,9 +120,30 @@ | ||||
|             <version>3.3.0</version> | ||||
|             <type>pom</type> | ||||
|         </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> | ||||
| 
 | ||||
|     <properties> | ||||
|         <junit.version>4.12</junit.version> | ||||
|         <mockito-kotlin.version>1.5.0</mockito-kotlin.version> | ||||
|         <kodein.version>4.1.0</kodein.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> | ||||
|             <version>${openjdk-jmh.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>javax.xml.bind</groupId> | ||||
|             <artifactId>jaxb-api</artifactId> | ||||
|             <version>2.3.0</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <finalName>hibernate5</finalName> | ||||
|         <resources> | ||||
|             <resource> | ||||
|                 <directory>src/main/resources</directory> | ||||
|                 <directory>src/test/resources</directory> | ||||
|                 <filtering>true</filtering> | ||||
|             </resource> | ||||
|         </resources> | ||||
|  | ||||
| @ -113,6 +113,7 @@ public class HibernateUtil { | ||||
|         metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); | ||||
|         metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); | ||||
|         metadataSources.addAnnotatedClass(OfficeEmployee.class); | ||||
|         metadataSources.addAnnotatedClass(Post.class); | ||||
| 
 | ||||
|         Metadata metadata = metadataSources.getMetadataBuilder() | ||||
|                 .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("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-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-12</module> --> <!-- We haven't upgraded to java 12. Fixing in BAEL-10841 --> | ||||
|                 <module>core-java-8</module> | ||||
|                 <!--<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.--> | ||||
| @ -436,9 +437,11 @@ | ||||
|                 <module>immutables</module> | ||||
| 
 | ||||
|                 <module>jackson</module> | ||||
|                 <module>jackson-2</module> | ||||
|                 <module>java-collections-conversions</module> | ||||
|                 <module>java-collections-maps</module> | ||||
|                 <!-- <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-lite</module> | ||||
|                 <module>java-numbers</module> | ||||
| @ -579,6 +582,7 @@ | ||||
|                 <module>spring-5-reactive-client</module> | ||||
|                 <module>spring-5-reactive-oauth</module> | ||||
|                 <module>spring-5-reactive-security</module> | ||||
|                 <module>spring-5-reactive-netty</module> | ||||
|                 <module>spring-5-security</module> | ||||
|                 <module>spring-5-security-oauth</module> | ||||
|                  | ||||
| @ -1078,6 +1082,7 @@ | ||||
|                 <module>immutables</module> | ||||
| 
 | ||||
|                 <module>jackson</module> | ||||
|                 <module>jackson-2</module> | ||||
|                 <module>java-collections-conversions</module> | ||||
|                 <module>java-collections-maps</module> | ||||
|                 <!-- <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