From 2c0b55e4a3dfddd0739827a5a78b7daa5ac33ce9 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Tue, 17 Jan 2017 15:44:28 +0100 Subject: [PATCH 01/17] BAEL-382 more examples --- .../kotlin/com/baeldung/kotlin/ItemService.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt index 3c0d2eacb1..97360db822 100644 --- a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt +++ b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt @@ -26,25 +26,32 @@ class ItemManager(val categoryId: String, val dbConnection: String) { println(result) } + + fun sum(a: Int, b: Int): Int { + return a + b + } } fun main(args: Array) { val numbers = arrayOf("first", "second", "third", "fourth") - var concat = "" for (n in numbers) { - concat += n + println(n) } - var sum = 0 - for (i in 2..9) { - sum += i + + for (i in 2..9 step 2) { + println(i) } + val res = 1.rangeTo(10).map { it * 2 } + println(res) + val firstName = "Tom" val secondName = "Mary" val concatOfNames = "$firstName + $secondName" println("Names: $concatOfNames") + val sum = "four: ${2 + 2}" val itemManager = ItemManager("cat_id", "db://connection") val result = "function result: ${itemManager.isFromSpecificCategory("1")}" From 7fdf20df6baf4170b4350d9f30c7e83f3638ac6a Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Tue, 17 Jan 2017 16:09:05 +0100 Subject: [PATCH 02/17] BAEL-382 lambdas --- .../kotlin/com/baeldung/kotlin/ItemService.kt | 1 + .../kotlin/com/baeldung/kotlin/LambdaTest.kt | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt index 97360db822..1740fb2863 100644 --- a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt +++ b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt @@ -54,6 +54,7 @@ fun main(args: Array) { val sum = "four: ${2 + 2}" val itemManager = ItemManager("cat_id", "db://connection") + ItemManager(categoryId = "catId", dbConnection = "db://Connection") val result = "function result: ${itemManager.isFromSpecificCategory("1")}" println(result) diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt b/kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt new file mode 100644 index 0000000000..34217336a0 --- /dev/null +++ b/kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt @@ -0,0 +1,19 @@ +package com.baeldung.kotlin + +import org.junit.Test +import kotlin.test.assertEquals + + +class LambdaTest { + @Test + fun givenListOfNumber_whenDoingOperationsUsingLambda_shouldReturnProperResult() { + //given + val listOfNumbers = listOf(1, 2, 3) + + //when + val sum = listOfNumbers.reduce { a, b -> a + b } + + //then + assertEquals(6, sum) + } +} \ No newline at end of file From faa3d322f8868b8af7eb1d0c143acbfc796efa90 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Tue, 17 Jan 2017 16:25:19 +0100 Subject: [PATCH 03/17] BAEL-382 creating mutalbe and immutable list --- kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt index 1740fb2863..96e297115b 100644 --- a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt +++ b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt @@ -30,6 +30,7 @@ class ItemManager(val categoryId: String, val dbConnection: String) { fun sum(a: Int, b: Int): Int { return a + b } + } fun main(args: Array) { @@ -39,7 +40,6 @@ fun main(args: Array) { println(n) } - for (i in 2..9 step 2) { println(i) } @@ -71,4 +71,9 @@ fun main(args: Array) { "Alice" -> println("Hi lady") } + val items = listOf(1, 2, 3, 4) + + + val rwList = mutableListOf(1, 2, 3) + rwList.add(5) } \ No newline at end of file From a269eba42734973639d7bdee522881b83713db8f Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Wed, 18 Jan 2017 19:37:12 +0100 Subject: [PATCH 04/17] BAEL-382 kotlin/java interperability example --- .../java/com/baeldung/java/StringUtils.java | 7 +++++++ .../kotlin/KotlinScalaInteroperabilityTest.kt | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 kotlin/src/main/java/com/baeldung/java/StringUtils.java create mode 100644 kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinScalaInteroperabilityTest.kt diff --git a/kotlin/src/main/java/com/baeldung/java/StringUtils.java b/kotlin/src/main/java/com/baeldung/java/StringUtils.java new file mode 100644 index 0000000000..f405924cdf --- /dev/null +++ b/kotlin/src/main/java/com/baeldung/java/StringUtils.java @@ -0,0 +1,7 @@ +package com.baeldung.java; + +public class StringUtils { + public static String toUpperCase(String name) { + return name.toUpperCase(); + } +} diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinScalaInteroperabilityTest.kt b/kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinScalaInteroperabilityTest.kt new file mode 100644 index 0000000000..f671c3af8b --- /dev/null +++ b/kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinScalaInteroperabilityTest.kt @@ -0,0 +1,20 @@ +package com.baeldung.kotlin + +import com.baeldung.java.StringUtils +import org.junit.Test +import kotlin.test.assertEquals + + +class KotlinScalaInteroperabilityTest { + @Test + fun givenLowercaseString_whenExecuteMethodFromJavaStringUtils_shouldReturnStringUppercase() { + //given + val name = "tom" + + //when + val res = StringUtils.toUpperCase(name) + + //then + assertEquals(res, "TOM") + } +} From 49bcf8c967d9b9e6217bca3c37e4edc131353ce5 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Thu, 19 Jan 2017 21:35:23 +0100 Subject: [PATCH 05/17] BAEL-382 BlocknigQueue producer consumer program --- .../concurrency/BlockingQueueUsage.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java diff --git a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java new file mode 100644 index 0000000000..e5637a724b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java @@ -0,0 +1,81 @@ +package com.baeldung.concurrency; + + +import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class BlockingQueueUsage { + public static void main(String[] args) { + int BOUND = 10; + int N_PRODUCERS = 4; + int N_CONSUMERS = Runtime.getRuntime().availableProcessors(); + + + BlockingQueue queue = new LinkedBlockingQueue<>(BOUND); + + for (int i = 0; i < N_PRODUCERS; i++) { + System.out.println("new Producer"); + new Thread(new NumbersProducer(queue)).start(); + } + + for (int j = 0; j < N_CONSUMERS; j++) { + System.out.println("new Consumer"); + new Thread(new NumbersConsumer(queue)).start(); + } + } + + + //producer + static class NumbersProducer implements Runnable { + private final Random random = new Random(); + private final BlockingQueue numbersQueue; + + + public NumbersProducer(BlockingQueue numbersQueue) { + this.numbersQueue = numbersQueue; + } + + + public void run() { + try { + generateNumbers(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void generateNumbers() throws InterruptedException { + for (int i = 0; i < 100; i++) { + numbersQueue.put(random.nextInt(100)); + } + } + } + + //consumer + static class NumbersConsumer implements Runnable { + private final BlockingQueue queue; + + public NumbersConsumer(BlockingQueue queue) { + this.queue = queue; + } + + public void run() { + try { + while (true) { + Integer number = queue.take(); + int result = fibonacci(number); + System.out.println("fibonacci result: " + result); + + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + public int fibonacci(Integer number) { + if (number <= 1) return number; + else return fibonacci(number - 1) + fibonacci(number - 2); + } + } +} \ No newline at end of file From 5013f7be99fad050c09ff8488cf910d6bb3bee2d Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Wed, 25 Jan 2017 19:07:48 +0100 Subject: [PATCH 06/17] BAEL-614 without a fibonacci --- .../java/com/baeldung/concurrency/BlockingQueueUsage.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java index e5637a724b..a8ffc2be72 100644 --- a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java +++ b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java @@ -64,8 +64,8 @@ public class BlockingQueueUsage { try { while (true) { Integer number = queue.take(); - int result = fibonacci(number); - System.out.println("fibonacci result: " + result); + String result = number.toString(); + System.out.println(Thread.currentThread().getName() + " result: " + result); } } catch (InterruptedException e) { @@ -73,9 +73,5 @@ public class BlockingQueueUsage { } } - public int fibonacci(Integer number) { - if (number <= 1) return number; - else return fibonacci(number - 1) + fibonacci(number - 2); - } } } \ No newline at end of file From ea7e3db1549cb42da8db6c125e3c7c13a5588e38 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Wed, 25 Jan 2017 19:10:49 +0100 Subject: [PATCH 07/17] BAEL-614 remove println --- .../main/java/com/baeldung/concurrency/BlockingQueueUsage.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java index a8ffc2be72..0a38715245 100644 --- a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java +++ b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java @@ -15,12 +15,10 @@ public class BlockingQueueUsage { BlockingQueue queue = new LinkedBlockingQueue<>(BOUND); for (int i = 0; i < N_PRODUCERS; i++) { - System.out.println("new Producer"); new Thread(new NumbersProducer(queue)).start(); } for (int j = 0; j < N_CONSUMERS; j++) { - System.out.println("new Consumer"); new Thread(new NumbersConsumer(queue)).start(); } } From 31c65f649ad38bee6bb0b14c0e14188cdd6283fc Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Wed, 25 Jan 2017 19:30:06 +0100 Subject: [PATCH 08/17] BAEL-614 java/kotlin interop --- .../kotlin/com/baeldung/kotlin/ItemService.kt | 6 +++++- .../baeldung/kotlin/MathematicsOperations.kt | 7 +++++++ .../baeldung/kotlin/JavaCallToKotlinTest.java | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt create mode 100644 kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinTest.java diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt index 96e297115b..88de1aa9be 100644 --- a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt +++ b/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt @@ -24,13 +24,17 @@ class ItemManager(val categoryId: String, val dbConnection: String) { fun makeAnalyisOfCategory(catId: String): Unit { val result = if (catId == "100") "Yes" else "No" println(result) - + `object`() } fun sum(a: Int, b: Int): Int { return a + b } + fun `object`(): String { + return "this is object" + } + } fun main(args: Array) { diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt b/kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt new file mode 100644 index 0000000000..924f9d2323 --- /dev/null +++ b/kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt @@ -0,0 +1,7 @@ +package com.baeldung.kotlin + +class MathematicsOperations { + fun addTwoNumbers(a: Int, b: Int): Int { + return a + b + } +} \ No newline at end of file diff --git a/kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinTest.java b/kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinTest.java new file mode 100644 index 0000000000..cfad7cefd4 --- /dev/null +++ b/kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinTest.java @@ -0,0 +1,17 @@ +package com.baeldung.kotlin; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JavaCallToKotlinTest { + @Test + public void givenKotlinClass_whenCallFromJava_shouldProduceResults() { + //when + int res = new MathematicsOperations().addTwoNumbers(2, 4); + + //then + assertEquals(6, res); + + } +} From 4c0a72d6e777b9f7b30cea0e274f8803c46fb169 Mon Sep 17 00:00:00 2001 From: DOHA Date: Wed, 25 Jan 2017 23:35:30 +0200 Subject: [PATCH 09/17] configure discovery and resource servers --- .../application-config/resource.properties | 2 +- .../src/main/resources/bootstrap.properties | 5 ++++- .../src/main/resources/application.properties | 19 ------------------- .../src/main/resources/bootstrap.properties | 6 ++++++ .../SpringCloudRestConfigApplication.java | 3 ++- .../src/main/resources/application.properties | 8 ++++---- 6 files changed, 17 insertions(+), 26 deletions(-) delete mode 100644 spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties create mode 100644 spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties diff --git a/spring-cloud/spring-cloud-rest/application-config/resource.properties b/spring-cloud/spring-cloud-rest/application-config/resource.properties index 8add49ab7e..759bb87895 100644 --- a/spring-cloud/spring-cloud-rest/application-config/resource.properties +++ b/spring-cloud/spring-cloud-rest/application-config/resource.properties @@ -1,5 +1,5 @@ spring.application.name=resource -server.port=0 +#server.port=0 #### cloud eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka} diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties index f34f1b65ac..a5a8eef7b0 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties @@ -1,3 +1,6 @@ spring.cloud.config.name=resource spring.cloud.config.discovery.service-id=config -spring.cloud.config.discovery.enabled=true \ No newline at end of file +spring.cloud.config.discovery.enabled=true +eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka + +server.port=8086 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties deleted file mode 100644 index f443e86fd8..0000000000 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/application.properties +++ /dev/null @@ -1,19 +0,0 @@ -#### cloud -spring.application.name=spring-cloud-eureka-client -server.port=0 -eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka -eureka.instance.preferIpAddress=true - -#### persistence -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:cloud_rest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=sa -spring.datasource.password= - -#### security -security.basic.enabled=true -security.basic.path=/** -security.user.name=user -security.user.password=userPass -security.user.role=USER -security.sessions=always \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties new file mode 100644 index 0000000000..ef11a62b53 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties @@ -0,0 +1,6 @@ +spring.cloud.config.name=resource +spring.cloud.config.discovery.service-id=config +spring.cloud.config.discovery.enabled=true +eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka + +server.port=8085 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java index 20e1589d5e..90c6fe3ec9 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/java/org/baeldung/SpringCloudRestConfigApplication.java @@ -3,10 +3,11 @@ package org.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableConfigServer -// @EnableEurekaClient +@EnableEurekaClient public class SpringCloudRestConfigApplication { public static void main(String[] args) { diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties index 42fed8d0ba..5b413e1d96 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties @@ -1,8 +1,8 @@ server.port=8081 spring.application.name=config -spring.cloud.config.server.git.uri=https://github.com/eugenp/tutorials/tree/master/spring-cloud/spring-cloud-rest/application-config +spring.cloud.config.server.git.uri=${HOME}/application-config -#eureka.client.region = default -#eureka.client.registryFetchIntervalSeconds = 5 -#eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka} +eureka.client.region = default +eureka.client.registryFetchIntervalSeconds = 5 +eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka} From cf7d8078aa6acc1efe8bd8de210d3f95b6c42ddb Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 26 Jan 2017 13:27:20 +0200 Subject: [PATCH 10/17] change server port --- .../src/test/java/org/baeldung/RestApiLiveTest.java | 2 +- .../src/test/resources/application.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java index 022648ffa1..1899385e2a 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/java/org/baeldung/RestApiLiveTest.java @@ -22,7 +22,7 @@ import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest(classes = { SpringCloudRestClientApplication.class }, webEnvironment = WebEnvironment.DEFINED_PORT) public class RestApiLiveTest { - private static final String API_URI = "http://localhost:8084/reviews"; + private static final String API_URI = "http://localhost:8085/reviews"; @Before public void setUp() { diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties index ece9ca1d94..e69cb2f555 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/test/resources/application.properties @@ -1,6 +1,6 @@ #### cloud spring.application.name=spring-cloud-eureka-client -server.port=8084 +server.port=8085 eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka} eureka.instance.preferIpAddress=true From 09fc6d9ee4d823dc1df1c56f92902e230076783f Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 26 Jan 2017 13:27:28 +0200 Subject: [PATCH 11/17] secure configuration server --- .../src/main/resources/bootstrap.properties | 5 ++++- .../src/main/resources/bootstrap.properties | 3 +++ .../spring-cloud-rest/spring-cloud-rest-config/pom.xml | 4 ++++ .../src/main/resources/application.properties | 3 +++ .../src/main/resources/bootstrap.properties | 4 +++- 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties index a5a8eef7b0..2cb3b71ca7 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-1/src/main/resources/bootstrap.properties @@ -1,6 +1,9 @@ spring.cloud.config.name=resource spring.cloud.config.discovery.service-id=config spring.cloud.config.discovery.enabled=true +spring.cloud.config.username=configUser +spring.cloud.config.password=configPassword + eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka -server.port=8086 \ No newline at end of file +server.port=8084 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties index ef11a62b53..d6e642afcb 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-client-2/src/main/resources/bootstrap.properties @@ -1,6 +1,9 @@ spring.cloud.config.name=resource spring.cloud.config.discovery.service-id=config spring.cloud.config.discovery.enabled=true +spring.cloud.config.username=configUser +spring.cloud.config.password=configPassword + eureka.client.serviceUrl.defaultZone=http://system:systemPass@localhost:8761/eureka server.port=8085 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/pom.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/pom.xml index 20b5eaf908..a6f045899c 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/pom.xml +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/pom.xml @@ -34,6 +34,10 @@ org.springframework.cloud spring-cloud-starter-eureka + + org.springframework.boot + spring-boot-starter-security + org.springframework.boot diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties index 5b413e1d96..4071dc81ea 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config/src/main/resources/application.properties @@ -6,3 +6,6 @@ spring.cloud.config.server.git.uri=${HOME}/application-config eureka.client.region = default eureka.client.registryFetchIntervalSeconds = 5 eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://system:systemPass@localhost:8761/eureka} + +security.user.name=configUser +security.user.password=configPassword \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-server/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-rest/spring-cloud-rest-server/src/main/resources/bootstrap.properties index 296078017e..528cb4cfd3 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-server/src/main/resources/bootstrap.properties +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-server/src/main/resources/bootstrap.properties @@ -1,2 +1,4 @@ spring.cloud.config.name=spring-cloud-rest-server -spring.cloud.config.uri=http://localhost:8081 \ No newline at end of file +spring.cloud.config.uri=http://localhost:8081 +spring.cloud.config.username=configUser +spring.cloud.config.password=configPassword \ No newline at end of file From c9a1fb1b398ad0517d9c3d39a2e3a456f265681a Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Thu, 26 Jan 2017 18:41:29 +0100 Subject: [PATCH 12/17] BAEL-614 move to proper package, move inner classes to separate classes --- .../concurrency/BlockingQueueUsage.java | 75 ------------------- .../blockingqueue/BlockingQueueUsage.java | 24 ++++++ .../blockingqueue/NumbersConsumer.java | 25 +++++++ .../blockingqueue/NumbersProducer.java | 31 ++++++++ 4 files changed, 80 insertions(+), 75 deletions(-) delete mode 100644 core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java create mode 100644 core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java create mode 100644 core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java create mode 100644 core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java diff --git a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java b/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java deleted file mode 100644 index 0a38715245..0000000000 --- a/core-java/src/main/java/com/baeldung/concurrency/BlockingQueueUsage.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.baeldung.concurrency; - - -import java.util.Random; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -public class BlockingQueueUsage { - public static void main(String[] args) { - int BOUND = 10; - int N_PRODUCERS = 4; - int N_CONSUMERS = Runtime.getRuntime().availableProcessors(); - - - BlockingQueue queue = new LinkedBlockingQueue<>(BOUND); - - for (int i = 0; i < N_PRODUCERS; i++) { - new Thread(new NumbersProducer(queue)).start(); - } - - for (int j = 0; j < N_CONSUMERS; j++) { - new Thread(new NumbersConsumer(queue)).start(); - } - } - - - //producer - static class NumbersProducer implements Runnable { - private final Random random = new Random(); - private final BlockingQueue numbersQueue; - - - public NumbersProducer(BlockingQueue numbersQueue) { - this.numbersQueue = numbersQueue; - } - - - public void run() { - try { - generateNumbers(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - private void generateNumbers() throws InterruptedException { - for (int i = 0; i < 100; i++) { - numbersQueue.put(random.nextInt(100)); - } - } - } - - //consumer - static class NumbersConsumer implements Runnable { - private final BlockingQueue queue; - - public NumbersConsumer(BlockingQueue queue) { - this.queue = queue; - } - - public void run() { - try { - while (true) { - Integer number = queue.take(); - String result = number.toString(); - System.out.println(Thread.currentThread().getName() + " result: " + result); - - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - } -} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java new file mode 100644 index 0000000000..63c6cc4460 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java @@ -0,0 +1,24 @@ +package com.baeldung.concurrent.blockingqueue; + + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class BlockingQueueUsage { + public static void main(String[] args) { + int BOUND = 10; + int N_PRODUCERS = 4; + int N_CONSUMERS = Runtime.getRuntime().availableProcessors(); + + + BlockingQueue queue = new LinkedBlockingQueue<>(BOUND); + + for (int i = 0; i < N_PRODUCERS; i++) { + new Thread(new NumbersProducer(queue)).start(); + } + + for (int j = 0; j < N_CONSUMERS; j++) { + new Thread(new NumbersConsumer(queue)).start(); + } + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java new file mode 100644 index 0000000000..110a801acc --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java @@ -0,0 +1,25 @@ +package com.baeldung.concurrent.blockingqueue; + + +import java.util.concurrent.BlockingQueue; + +class NumbersConsumer implements Runnable { + private final BlockingQueue queue; + + public NumbersConsumer(BlockingQueue queue) { + this.queue = queue; + } + + public void run() { + try { + while (true) { + Integer number = queue.take(); + String result = number.toString(); + System.out.println(Thread.currentThread().getName() + " result: " + result); + + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java new file mode 100644 index 0000000000..c9e91cd077 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.blockingqueue; + + +import java.util.Random; +import java.util.concurrent.BlockingQueue; + + +class NumbersProducer implements Runnable { + private final Random random = new Random(); + private final BlockingQueue numbersQueue; + + + public NumbersProducer(BlockingQueue numbersQueue) { + this.numbersQueue = numbersQueue; + } + + + public void run() { + try { + generateNumbers(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void generateNumbers() throws InterruptedException { + for (int i = 0; i < 100; i++) { + numbersQueue.put(random.nextInt(100)); + } + } +} \ No newline at end of file From cc7d5ba3fc7ef184560ce4f507c47016d645ecd4 Mon Sep 17 00:00:00 2001 From: Nitish Bangera Date: Thu, 26 Jan 2017 23:20:41 +0530 Subject: [PATCH 13/17] Final Review changes. (#1055) * String to char and vice versa initial article code * Junit test case for String Conversion. Deleting normal class. * Changes based on review. * BAEL-591 : New Java9 Collectors code snippet * Deleting String conversion test * BAEL-591 : Changing to BDD style testcase names. --- .../java9/language/stream/CollectorImprovementTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementTest.java index 71ee6c6ae4..2496d073ec 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementTest.java +++ b/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectorImprovementTest.java @@ -31,8 +31,8 @@ public class CollectorImprovementTest { } } - @Test - public void testFiltering() { + @Test + public void givenList_whenSatifyPredicate_thenMapValueWithOccurences() { List numbers = List.of(1, 2, 3, 5, 5); Map result = numbers.stream() @@ -49,7 +49,7 @@ public class CollectorImprovementTest { } @Test - public void testFlatMapping() { + public void givenListOfBlogs_whenAuthorName_thenMapAuthorWithComments() { Blog blog1 = new CollectorImprovementTest.Blog("1"); blog1.addComment("Nice"); blog1.addComment("Very Nice"); From 4ff894095c4a7fe14df390a8a75b1ad81c58129b Mon Sep 17 00:00:00 2001 From: Pedja Date: Fri, 27 Jan 2017 11:52:17 +0100 Subject: [PATCH 14/17] BAEL-614 Added "public" to class definitions; Formatted code --- .../concurrent/blockingqueue/BlockingQueueUsage.java | 2 -- .../baeldung/concurrent/blockingqueue/NumbersConsumer.java | 4 +--- .../baeldung/concurrent/blockingqueue/NumbersProducer.java | 6 +----- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java index 63c6cc4460..801dc4e35c 100644 --- a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java @@ -1,6 +1,5 @@ package com.baeldung.concurrent.blockingqueue; - import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -10,7 +9,6 @@ public class BlockingQueueUsage { int N_PRODUCERS = 4; int N_CONSUMERS = Runtime.getRuntime().availableProcessors(); - BlockingQueue queue = new LinkedBlockingQueue<>(BOUND); for (int i = 0; i < N_PRODUCERS; i++) { diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java index 110a801acc..774c263a3b 100644 --- a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java @@ -1,9 +1,8 @@ package com.baeldung.concurrent.blockingqueue; - import java.util.concurrent.BlockingQueue; -class NumbersConsumer implements Runnable { +public class NumbersConsumer implements Runnable { private final BlockingQueue queue; public NumbersConsumer(BlockingQueue queue) { @@ -16,7 +15,6 @@ class NumbersConsumer implements Runnable { Integer number = queue.take(); String result = number.toString(); System.out.println(Thread.currentThread().getName() + " result: " + result); - } } catch (InterruptedException e) { Thread.currentThread().interrupt(); diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java index c9e91cd077..dcc0b48453 100644 --- a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java @@ -1,20 +1,16 @@ package com.baeldung.concurrent.blockingqueue; - import java.util.Random; import java.util.concurrent.BlockingQueue; - -class NumbersProducer implements Runnable { +public class NumbersProducer implements Runnable { private final Random random = new Random(); private final BlockingQueue numbersQueue; - public NumbersProducer(BlockingQueue numbersQueue) { this.numbersQueue = numbersQueue; } - public void run() { try { generateNumbers(); From fb61d1b187bf173065d1690083fb6ef724b63d61 Mon Sep 17 00:00:00 2001 From: Pedja Date: Fri, 27 Jan 2017 12:24:31 +0100 Subject: [PATCH 15/17] BAEL-614 Changed to use ThreadLocalRandom instead of Random --- .../baeldung/concurrent/blockingqueue/NumbersProducer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java index dcc0b48453..eb927c8b37 100644 --- a/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java +++ b/core-java/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java @@ -1,10 +1,10 @@ package com.baeldung.concurrent.blockingqueue; -import java.util.Random; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadLocalRandom; public class NumbersProducer implements Runnable { - private final Random random = new Random(); + private final BlockingQueue numbersQueue; public NumbersProducer(BlockingQueue numbersQueue) { @@ -21,7 +21,7 @@ public class NumbersProducer implements Runnable { private void generateNumbers() throws InterruptedException { for (int i = 0; i < 100; i++) { - numbersQueue.put(random.nextInt(100)); + numbersQueue.put(ThreadLocalRandom.current().nextInt(100)); } } } \ No newline at end of file From 5d2abc903178a2a7bc03b214a6316744a1581d08 Mon Sep 17 00:00:00 2001 From: Tian Baoqiang Date: Fri, 27 Jan 2017 21:10:49 +0800 Subject: [PATCH 16/17] add concurrentmap tests (#1051) --- .../ConcurrentMapAggregateStatusTest.java | 80 +++++++++ .../ConcurrentMapNullKeyValueTest.java | 160 ++++++++++++++++++ .../ConcurrentMapPerformanceTest.java | 98 +++++++++++ .../ConcurretMapMemoryConsistencyTest.java | 78 +++++++++ 4 files changed, 416 insertions(+) create mode 100644 core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java create mode 100644 core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java create mode 100644 core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java create mode 100644 core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java new file mode 100644 index 0000000000..cb43cad24b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java @@ -0,0 +1,80 @@ +package com.baeldung.java.concurrentmap; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class ConcurrentMapAggregateStatusTest { + + private ExecutorService executorService; + private Map concurrentMap; + private List mapSizes; + private int MAX_SIZE = 100000; + + @Before + public void init() { + executorService = Executors.newFixedThreadPool(2); + concurrentMap = new ConcurrentHashMap<>(); + mapSizes = new ArrayList<>(MAX_SIZE); + } + + @Test + public void givenConcurrentMap_whenSizeWithoutConcurrentUpdates_thenCorrect() throws InterruptedException { + Runnable collectMapSizes = () -> { + for (int i = 0; i < MAX_SIZE; i++) { + concurrentMap.put(String.valueOf(i), i); + mapSizes.add(concurrentMap.size()); + } + }; + Runnable retrieveMapData = () -> { + for (int i = 0; i < MAX_SIZE; i++) { + concurrentMap.get(String.valueOf(i)); + } + }; + executorService.execute(retrieveMapData); + executorService.execute(collectMapSizes); + executorService.shutdown(); + executorService.awaitTermination(1, TimeUnit.MINUTES); + + for (int i = 1; i <= MAX_SIZE; i++) { + assertEquals("map size should be consistently reliable", i, mapSizes + .get(i - 1) + .intValue()); + } + assertEquals(MAX_SIZE, concurrentMap.size()); + } + + @Test + public void givenConcurrentMap_whenUpdatingAndGetSize_thenError() throws InterruptedException { + Runnable collectMapSizes = () -> { + for (int i = 0; i < MAX_SIZE; i++) { + mapSizes.add(concurrentMap.size()); + } + }; + Runnable updateMapData = () -> { + for (int i = 0; i < MAX_SIZE; i++) { + concurrentMap.put(String.valueOf(i), i); + } + }; + executorService.execute(updateMapData); + executorService.execute(collectMapSizes); + executorService.shutdown(); + executorService.awaitTermination(1, TimeUnit.MINUTES); + + assertNotEquals("map size collected with concurrent updates not reliable", MAX_SIZE, mapSizes + .get(MAX_SIZE - 1) + .intValue()); + assertEquals(MAX_SIZE, concurrentMap.size()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java new file mode 100644 index 0000000000..62a3d10add --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java @@ -0,0 +1,160 @@ +package com.baeldung.java.concurrentmap; + +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import static org.junit.Assert.assertNull; + +public class ConcurrentMapNullKeyValueTest { + + ConcurrentMap concurrentMap; + + @Before + public void setup() { + concurrentMap = new ConcurrentHashMap<>(); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenGetWithNullKey_thenThrowsNPE() { + concurrentMap.get(null); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenGetOrDefaultWithNullKey_thenThrowsNPE() { + concurrentMap.getOrDefault(null, new Object()); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenPutWithNullKey_thenThrowsNPE() { + concurrentMap.put(null, new Object()); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenPutNullValue_thenThrowsNPE() { + concurrentMap.put("test", null); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMapAndKeyAbsent_whenPutWithNullKey_thenThrowsNPE() { + concurrentMap.putIfAbsent(null, new Object()); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMapAndMapWithNullKey_whenPutNullKeyMap_thenThrowsNPE() { + Map nullKeyMap = new HashMap<>(); + nullKeyMap.put(null, new Object()); + concurrentMap.putAll(nullKeyMap); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMapAndMapWithNullValue_whenPutNullValueMap_thenThrowsNPE() { + Map nullValueMap = new HashMap<>(); + nullValueMap.put("test", null); + concurrentMap.putAll(nullValueMap); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenReplaceNullKeyWithValues_thenThrowsNPE() { + concurrentMap.replace(null, new Object(), new Object()); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenReplaceWithNullNewValue_thenThrowsNPE() { + Object o = new Object(); + concurrentMap.replace("test", o, null); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenReplaceOldNullValue_thenThrowsNPE() { + Object o = new Object(); + concurrentMap.replace("test", null, o); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenReplaceWithNullValue_thenThrowsNPE() { + concurrentMap.replace("test", null); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenReplaceNullKey_thenThrowsNPE() { + concurrentMap.replace(null, "test"); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenReplaceAllMappingNull_thenThrowsNPE() { + concurrentMap.put("test", new Object()); + concurrentMap.replaceAll((s, o) -> null); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenRemoveNullKey_thenThrowsNPE() { + concurrentMap.remove(null); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenRemoveNullKeyWithValue_thenThrowsNPE() { + concurrentMap.remove(null, new Object()); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenMergeNullKeyWithValue_thenThrowsNPE() { + concurrentMap.merge(null, new Object(), (o, o2) -> o2); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenMergeKeyWithNullValue_thenThrowsNPE() { + concurrentMap.put("test", new Object()); + concurrentMap.merge("test", null, (o, o2) -> o2); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMapAndAssumeKeyAbsent_whenComputeWithNullKey_thenThrowsNPE() { + concurrentMap.computeIfAbsent(null, s -> s); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMapAndAssumeKeyPresent_whenComputeWithNullKey_thenThrowsNPE() { + concurrentMap.computeIfPresent(null, (s, o) -> o); + } + + @Test(expected = NullPointerException.class) + public void givenConcurrentHashMap_whenComputeWithNullKey_thenThrowsNPE() { + concurrentMap.compute(null, (s, o) -> o); + } + + @Test + public void givenConcurrentHashMap_whenMergeKeyRemappingNull_thenRemovesMapping() { + Object oldValue = new Object(); + concurrentMap.put("test", oldValue); + concurrentMap.merge("test", new Object(), (o, o2) -> null); + assertNull(concurrentMap.get("test")); + } + + @Test + public void givenConcurrentHashMapAndKeyAbsent_whenComputeWithKeyRemappingNull_thenRemainsAbsent() { + concurrentMap.computeIfPresent("test", (s, o) -> null); + assertNull(concurrentMap.get("test")); + } + + @Test + public void givenKeyPresent_whenComputeIfPresentRemappingNull_thenMappingRemoved() { + Object oldValue = new Object(); + concurrentMap.put("test", oldValue); + concurrentMap.computeIfPresent("test", (s, o) -> null); + assertNull(concurrentMap.get("test")); + } + + @Test + public void givenKeyPresent_whenComputeRemappingNull_thenMappingRemoved() { + Object oldValue = new Object(); + concurrentMap.put("test", oldValue); + concurrentMap.compute("test", (s, o) -> null); + assertNull(concurrentMap.get("test")); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java new file mode 100644 index 0000000000..3275a47b90 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java @@ -0,0 +1,98 @@ +package com.baeldung.java.concurrentmap; + +import org.junit.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.*; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +public class ConcurrentMapPerformanceTest { + + @Test + public void givenMaps_whenGetPut500KTimes_thenConcurrentMapFaster() throws Exception { + Map hashtable = new Hashtable<>(); + Map synchronizedHashMap = Collections.synchronizedMap(new HashMap<>()); + Map concurrentHashMap = new ConcurrentHashMap<>(); + + long hashtableAvgRuntime = timeElapseForGetPut(hashtable); + long syncHashMapAvgRuntime = timeElapseForGetPut(synchronizedHashMap); + long concurrentHashMapAvgRuntime = timeElapseForGetPut(concurrentHashMap); + + assertTrue(hashtableAvgRuntime > concurrentHashMapAvgRuntime); + assertTrue(syncHashMapAvgRuntime > concurrentHashMapAvgRuntime); + + System.out.println(String.format("Hashtable: %s, syncHashMap: %s, ConcurrentHashMap: %s", hashtableAvgRuntime, syncHashMapAvgRuntime, concurrentHashMapAvgRuntime)); + + } + + private long timeElapseForGetPut(Map map) throws InterruptedException { + ExecutorService executorService = Executors.newFixedThreadPool(4); + long startTime = System.nanoTime(); + for (int i = 0; i < 4; i++) { + executorService.execute(() -> { + for (int j = 0; j < 500_000; j++) { + int value = ThreadLocalRandom + .current() + .nextInt(10000); + String key = String.valueOf(value); + map.put(key, value); + map.get(key); + } + }); + } + executorService.shutdown(); + executorService.awaitTermination(1, TimeUnit.MINUTES); + return (System.nanoTime() - startTime) / 500_000; + } + + @Test + public void givenConcurrentMap_whenKeyWithSameHashCode_thenPerformanceDegrades() throws InterruptedException { + class SameHash { + @Override + public int hashCode() { + return 1; + } + } + int executeTimes = 5000; + + Map mapOfSameHash = new ConcurrentHashMap<>(); + ExecutorService executorService = Executors.newFixedThreadPool(2); + long sameHashStartTime = System.currentTimeMillis(); + for (int i = 0; i < 2; i++) { + executorService.execute(() -> { + for (int j = 0; j < executeTimes; j++) { + mapOfSameHash.put(new SameHash(), 1); + } + }); + } + executorService.shutdown(); + executorService.awaitTermination(5, TimeUnit.SECONDS); + + long mapOfSameHashDuration = System.currentTimeMillis() - sameHashStartTime; + Map mapOfDefaultHash = new ConcurrentHashMap<>(); + executorService = Executors.newFixedThreadPool(2); + long defaultHashStartTime = System.currentTimeMillis(); + for (int i = 0; i < 2; i++) { + executorService.execute(() -> { + for (int j = 0; j < executeTimes; j++) { + mapOfDefaultHash.put(new Object(), 1); + } + }); + } + executorService.shutdown(); + executorService.awaitTermination(5, TimeUnit.SECONDS); + + long mapOfDefaultHashDuration = System.currentTimeMillis() - defaultHashStartTime; + assertEquals(executeTimes * 2, mapOfDefaultHash.size()); + assertNotEquals(executeTimes * 2, mapOfSameHash.size()); + System.out.println(String.format("same-hash: %s, default-hash: %s", mapOfSameHashDuration, mapOfDefaultHashDuration)); + assertTrue("same hashCode() should greatly degrade performance", mapOfSameHashDuration > mapOfDefaultHashDuration * 10); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java new file mode 100644 index 0000000000..9a6359f187 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java @@ -0,0 +1,78 @@ +package com.baeldung.java.concurrentmap; + +import org.junit.Test; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.*; + +public class ConcurretMapMemoryConsistencyTest { + + @Test + public void givenConcurrentMap_whenSumParallel_thenCorrect() throws Exception { + Map map = new ConcurrentHashMap<>(); + List sumList = parallelSum100(map, 1000); + assertEquals(1, sumList + .stream() + .distinct() + .count()); + long wrongResultCount = sumList + .stream() + .filter(num -> num != 100) + .count(); + assertEquals(0, wrongResultCount); + } + + @Test + public void givenHashtable_whenSumParallel_thenCorrect() throws Exception { + Map map = new Hashtable<>(); + List sumList = parallelSum100(map, 1000); + assertEquals(1, sumList + .stream() + .distinct() + .count()); + long wrongResultCount = sumList + .stream() + .filter(num -> num != 100) + .count(); + assertEquals(0, wrongResultCount); + } + + @Test + public void givenHashMap_whenSumParallel_thenError() throws Exception { + Map map = new HashMap<>(); + List sumList = parallelSum100(map, 100); + assertNotEquals(1, sumList + .stream() + .distinct() + .count()); + long wrongResultCount = sumList + .stream() + .filter(num -> num != 100) + .count(); + assertTrue(wrongResultCount > 0); + } + + private List parallelSum100(Map map, int executionTimes) throws InterruptedException { + List sumList = new ArrayList<>(1000); + for (int i = 0; i < executionTimes; i++) { + map.put("test", 0); + ExecutorService executorService = Executors.newFixedThreadPool(4); + for (int j = 0; j < 10; j++) { + executorService.execute(() -> { + for (int k = 0; k < 10; k++) + map.computeIfPresent("test", (key, value) -> value + 1); + }); + } + executorService.shutdown(); + executorService.awaitTermination(5, TimeUnit.SECONDS); + sumList.add(map.get("test")); + } + return sumList; + } + +} From 499954786187bcc8e1f109e9e12980b8cef18391 Mon Sep 17 00:00:00 2001 From: Pedja Date: Fri, 27 Jan 2017 15:11:34 +0100 Subject: [PATCH 17/17] BAEL-382 Added java sources into pom.xml --- kotlin/pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kotlin/pom.xml b/kotlin/pom.xml index eba248e1b9..68944f08ac 100644 --- a/kotlin/pom.xml +++ b/kotlin/pom.xml @@ -38,6 +38,12 @@ ${kotlin-maven-plugin.version} + + + src/main/java + src/main/kotlin + + compile compile @@ -45,6 +51,12 @@ + + + src/test/java + src/test/kotlin + + test-compile test-compile