From 425586cc08bedd08c387ae43b310e22eb0fc4772 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sun, 2 Apr 2017 23:43:58 +0300 Subject: [PATCH 01/19] BAEL-748 quick guide to @Value --- .../java/com/baeldung/value/SomeBean.java | 17 +++++ .../java/com/baeldung/value/ValuesApp.java | 68 +++++++++++++++++++ .../src/main/resources/values.properties | 3 + 3 files changed, 88 insertions(+) create mode 100644 spring-core/src/main/java/com/baeldung/value/SomeBean.java create mode 100644 spring-core/src/main/java/com/baeldung/value/ValuesApp.java create mode 100644 spring-core/src/main/resources/values.properties diff --git a/spring-core/src/main/java/com/baeldung/value/SomeBean.java b/spring-core/src/main/java/com/baeldung/value/SomeBean.java new file mode 100644 index 000000000000..39d5245049e9 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/value/SomeBean.java @@ -0,0 +1,17 @@ +package com.baeldung.value; + +public class SomeBean { + private int someValue; + + public SomeBean(int someValue) { + this.someValue = someValue; + } + + public int getSomeValue() { + return someValue; + } + + public void setSomeValue(int someValue) { + this.someValue = someValue; + } +} diff --git a/spring-core/src/main/java/com/baeldung/value/ValuesApp.java b/spring-core/src/main/java/com/baeldung/value/ValuesApp.java new file mode 100644 index 000000000000..4a90a7d85a72 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/value/ValuesApp.java @@ -0,0 +1,68 @@ +package com.baeldung.value; + +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource(name = "myProperties", value = "values.properties") +public class ValuesApp { + + @Value("string value") + private String value1; + + @Value("${value.from.file}") + private String value2; + + @Value("${systemValue}") + private String value3; + + @Value("${unknown_param:some default}") + private String value4; + + @Value("${priority}") + private String value5; + + @Value("#{systemProperties['priority']}") + private String value6; + + @Value("#{systemEnvironment['priority'] ?: 'default env'}") + private String value7; + + @Value("#{someBean.someValue}") + private Integer value8; + + @Value("#{'${listOfValues}'.split(',')}") + private List valuesList; + + public static void main(String[] args) { + System.setProperty("systemValue", "Some system parameter value"); + System.setProperty("priority", "System property"); + ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ValuesApp.class); + } + + @Bean + public SomeBean someBean() { + return new SomeBean(42); + } + + @PostConstruct + public void afterInitialize() { + System.out.println(value1); + System.out.println(value2); + System.out.println(value3); + System.out.println(value4); + System.out.println(value5); + System.out.println(value6); + System.out.println(value7); + System.out.println(value8); + System.out.println(valuesList); + } +} diff --git a/spring-core/src/main/resources/values.properties b/spring-core/src/main/resources/values.properties new file mode 100644 index 000000000000..8c406cda9077 --- /dev/null +++ b/spring-core/src/main/resources/values.properties @@ -0,0 +1,3 @@ +value.from.file=Value got from file +priority=Properties file +listOfValues=A, B, C \ No newline at end of file From f56a201948f996f41906880ec520cf3f2d689ac7 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Fri, 14 Apr 2017 00:36:57 +0300 Subject: [PATCH 02/19] BAEL-748 changes from review --- .../java/com/baeldung/value/ValuesApp.java | 36 +++++++++---------- .../src/main/resources/values.properties | 4 +-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/spring-core/src/main/java/com/baeldung/value/ValuesApp.java b/spring-core/src/main/java/com/baeldung/value/ValuesApp.java index 4a90a7d85a72..25f4b9fb9c63 100644 --- a/spring-core/src/main/java/com/baeldung/value/ValuesApp.java +++ b/spring-core/src/main/java/com/baeldung/value/ValuesApp.java @@ -16,28 +16,28 @@ public class ValuesApp { @Value("string value") - private String value1; + private String stringValue; @Value("${value.from.file}") - private String value2; + private String valueFromFile; @Value("${systemValue}") - private String value3; + private String systemValue; @Value("${unknown_param:some default}") - private String value4; + private String someDefault; @Value("${priority}") - private String value5; + private String prioritySystemProperty; @Value("#{systemProperties['priority']}") - private String value6; + private String spelValue; - @Value("#{systemEnvironment['priority'] ?: 'default env'}") - private String value7; + @Value("#{systemProperties['unknown'] ?: 'some default'}") + private String spelSomeDefault; @Value("#{someBean.someValue}") - private Integer value8; + private Integer someBeanValue; @Value("#{'${listOfValues}'.split(',')}") private List valuesList; @@ -50,19 +50,19 @@ public static void main(String[] args) { @Bean public SomeBean someBean() { - return new SomeBean(42); + return new SomeBean(10); } @PostConstruct public void afterInitialize() { - System.out.println(value1); - System.out.println(value2); - System.out.println(value3); - System.out.println(value4); - System.out.println(value5); - System.out.println(value6); - System.out.println(value7); - System.out.println(value8); + System.out.println(stringValue); + System.out.println(valueFromFile); + System.out.println(systemValue); + System.out.println(someDefault); + System.out.println(prioritySystemProperty); + System.out.println(spelValue); + System.out.println(spelSomeDefault); + System.out.println(someBeanValue); System.out.println(valuesList); } } diff --git a/spring-core/src/main/resources/values.properties b/spring-core/src/main/resources/values.properties index 8c406cda9077..d7d61b8ee8e1 100644 --- a/spring-core/src/main/resources/values.properties +++ b/spring-core/src/main/resources/values.properties @@ -1,3 +1,3 @@ -value.from.file=Value got from file +value.from.file=Value got from the file priority=Properties file -listOfValues=A, B, C \ No newline at end of file +listOfValues=A,B,C \ No newline at end of file From edbd02ab1f3c7ae6e4a51c0ed8baab39bcda3dd9 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sun, 16 Apr 2017 23:00:25 +0300 Subject: [PATCH 03/19] BAEL-748 inject comma-separated values into array --- spring-core/src/main/java/com/baeldung/value/ValuesApp.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spring-core/src/main/java/com/baeldung/value/ValuesApp.java b/spring-core/src/main/java/com/baeldung/value/ValuesApp.java index 25f4b9fb9c63..f525dfde8949 100644 --- a/spring-core/src/main/java/com/baeldung/value/ValuesApp.java +++ b/spring-core/src/main/java/com/baeldung/value/ValuesApp.java @@ -1,5 +1,6 @@ package com.baeldung.value; +import java.util.Arrays; import java.util.List; import javax.annotation.PostConstruct; @@ -30,6 +31,9 @@ public class ValuesApp { @Value("${priority}") private String prioritySystemProperty; + @Value("${listOfValues}") + private String[] valuesArray; + @Value("#{systemProperties['priority']}") private String spelValue; @@ -60,6 +64,7 @@ public void afterInitialize() { System.out.println(systemValue); System.out.println(someDefault); System.out.println(prioritySystemProperty); + System.out.println(Arrays.toString(valuesArray)); System.out.println(spelValue); System.out.println(spelSomeDefault); System.out.println(someBeanValue); From 8c1198c9b49d0435c5006a0b8198463906f4d82e Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Thu, 25 May 2017 23:16:20 +0300 Subject: [PATCH 04/19] BAEL-768 Introduction to Netty --- libraries/pom.xml | 6 +++ .../com/baeldung/netty/ClientHandler.java | 22 +++++++++ .../java/com/baeldung/netty/NettyClient.java | 37 ++++++++++++++ .../java/com/baeldung/netty/NettyServer.java | 49 +++++++++++++++++++ .../com/baeldung/netty/ProcessingHandler.java | 19 +++++++ .../java/com/baeldung/netty/RequestData.java | 30 ++++++++++++ .../baeldung/netty/RequestDataEncoder.java | 19 +++++++ .../com/baeldung/netty/RequestDecoder.java | 22 +++++++++ .../java/com/baeldung/netty/ResponseData.java | 20 ++++++++ .../baeldung/netty/ResponseDataDecoder.java | 17 +++++++ .../baeldung/netty/ResponseDataEncoder.java | 13 +++++ .../netty/SimpleProcessingHandler.java | 39 +++++++++++++++ 12 files changed, 293 insertions(+) create mode 100644 libraries/src/main/java/com/baeldung/netty/ClientHandler.java create mode 100644 libraries/src/main/java/com/baeldung/netty/NettyClient.java create mode 100644 libraries/src/main/java/com/baeldung/netty/NettyServer.java create mode 100644 libraries/src/main/java/com/baeldung/netty/ProcessingHandler.java create mode 100644 libraries/src/main/java/com/baeldung/netty/RequestData.java create mode 100644 libraries/src/main/java/com/baeldung/netty/RequestDataEncoder.java create mode 100644 libraries/src/main/java/com/baeldung/netty/RequestDecoder.java create mode 100644 libraries/src/main/java/com/baeldung/netty/ResponseData.java create mode 100644 libraries/src/main/java/com/baeldung/netty/ResponseDataDecoder.java create mode 100644 libraries/src/main/java/com/baeldung/netty/ResponseDataEncoder.java create mode 100644 libraries/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java diff --git a/libraries/pom.xml b/libraries/pom.xml index 6d41902db753..bf8941233b0a 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -269,6 +269,11 @@ h2 1.4.195 + + io.netty + netty-all + ${netty.version} + 0.7.0 @@ -292,6 +297,7 @@ 1.24.0 1.1.3-rc.5 1.4.0 + 4.1.10.Final diff --git a/libraries/src/main/java/com/baeldung/netty/ClientHandler.java b/libraries/src/main/java/com/baeldung/netty/ClientHandler.java new file mode 100644 index 000000000000..d120d12ec57e --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/ClientHandler.java @@ -0,0 +1,22 @@ +package com.baeldung.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class ClientHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + RequestData msg = new RequestData(); + msg.setIntValue(123); + msg.setStringValue("all work and no play makes jack a dull boy"); + ChannelFuture future = ctx.writeAndFlush(msg); + //future.addListener(f -> ctx.fireChannelActive()); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + System.out.println((ResponseData)msg); + ctx.close(); + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/NettyClient.java b/libraries/src/main/java/com/baeldung/netty/NettyClient.java new file mode 100644 index 000000000000..97dfc70b9f3b --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/NettyClient.java @@ -0,0 +1,37 @@ +package com.baeldung.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; + +public class NettyClient { + public static void main(String[] args) throws Exception { + String host = "localhost"; + int port = 8080; + EventLoopGroup workerGroup = new NioEventLoopGroup(); + + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new RequestDataEncoder(), new ResponseDataDecoder(), new ClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port).sync(); + + f.channel().closeFuture().sync(); + } finally { + workerGroup.shutdownGracefully(); + } + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/NettyServer.java b/libraries/src/main/java/com/baeldung/netty/NettyServer.java new file mode 100644 index 000000000000..b9d35859d074 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/NettyServer.java @@ -0,0 +1,49 @@ +package com.baeldung.netty; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; + +public class NettyServer { + + private int port; + + public NettyServer(int port) { + this.port = port; + } + + public static void main(String[] args) throws Exception { + int port; + if (args.length > 0) { + port = Integer.parseInt(args[0]); + } else { + port = 8080; + } + new NettyServer(port).run(); + } + + public void run() throws Exception { + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new RequestDecoder(), new ResponseDataEncoder(), new ProcessingHandler()); + } + }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true); + + ChannelFuture f = b.bind(port).sync(); + f.channel().closeFuture().sync(); + } finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/ProcessingHandler.java b/libraries/src/main/java/com/baeldung/netty/ProcessingHandler.java new file mode 100644 index 000000000000..6de4d3fca8db --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/ProcessingHandler.java @@ -0,0 +1,19 @@ +package com.baeldung.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class ProcessingHandler extends ChannelInboundHandlerAdapter { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + RequestData requestData = (RequestData) msg; + ResponseData responseData = new ResponseData(); + responseData.setIntValue(requestData.getIntValue() * 2); + ChannelFuture future = ctx.writeAndFlush(responseData); + future.addListener(ChannelFutureListener.CLOSE); + System.out.println(requestData); + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/RequestData.java b/libraries/src/main/java/com/baeldung/netty/RequestData.java new file mode 100644 index 000000000000..e7404c166339 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/RequestData.java @@ -0,0 +1,30 @@ +package com.baeldung.netty; + +public class RequestData { + private int intValue; + private String stringValue; + + public int getIntValue() { + return intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + @Override + public String toString() { + return "RequestData{" + + "intValue=" + intValue + + ", stringValue='" + stringValue + '\'' + + '}'; + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/RequestDataEncoder.java b/libraries/src/main/java/com/baeldung/netty/RequestDataEncoder.java new file mode 100644 index 000000000000..205a48699ecc --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/RequestDataEncoder.java @@ -0,0 +1,19 @@ +package com.baeldung.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +import java.nio.charset.Charset; + +public class RequestDataEncoder extends MessageToByteEncoder { + + private final Charset charset = Charset.forName("UTF-8"); + + @Override + protected void encode(ChannelHandlerContext ctx, RequestData msg, ByteBuf out) throws Exception { + out.writeInt(msg.getIntValue()); + out.writeInt(msg.getStringValue().length()); + out.writeCharSequence(msg.getStringValue(), charset); + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/RequestDecoder.java b/libraries/src/main/java/com/baeldung/netty/RequestDecoder.java new file mode 100644 index 000000000000..38b78fc87721 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/RequestDecoder.java @@ -0,0 +1,22 @@ +package com.baeldung.netty; + +import java.nio.charset.Charset; +import java.util.List; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ReplayingDecoder; + +public class RequestDecoder extends ReplayingDecoder { + + private final Charset charset = Charset.forName("UTF-8"); + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + RequestData data = new RequestData(); + data.setIntValue(in.readInt()); + int strLen = in.readInt(); + data.setStringValue(in.readCharSequence(strLen, charset).toString()); + out.add(data); + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/ResponseData.java b/libraries/src/main/java/com/baeldung/netty/ResponseData.java new file mode 100644 index 000000000000..ce388a9a3df4 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/ResponseData.java @@ -0,0 +1,20 @@ +package com.baeldung.netty; + +public class ResponseData { + private int intValue; + + public int getIntValue() { + return intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + } + + @Override + public String toString() { + return "ResponseData{" + + "intValue=" + intValue + + '}'; + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/ResponseDataDecoder.java b/libraries/src/main/java/com/baeldung/netty/ResponseDataDecoder.java new file mode 100644 index 000000000000..ee33679dfe0a --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/ResponseDataDecoder.java @@ -0,0 +1,17 @@ +package com.baeldung.netty; + +import java.util.List; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ReplayingDecoder; + +public class ResponseDataDecoder extends ReplayingDecoder { + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + ResponseData data = new ResponseData(); + data.setIntValue(in.readInt()); + out.add(data); + } +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/netty/ResponseDataEncoder.java b/libraries/src/main/java/com/baeldung/netty/ResponseDataEncoder.java new file mode 100644 index 000000000000..c73be11a4439 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/ResponseDataEncoder.java @@ -0,0 +1,13 @@ +package com.baeldung.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class ResponseDataEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, ResponseData msg, ByteBuf out) throws Exception { + out.writeInt(msg.getIntValue()); + } +} diff --git a/libraries/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java b/libraries/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java new file mode 100644 index 000000000000..d12089f0bb10 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java @@ -0,0 +1,39 @@ +package com.baeldung.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class SimpleProcessingHandler extends ChannelInboundHandlerAdapter { + private ByteBuf tmp; + + @Override + public void handlerAdded(ChannelHandlerContext ctx) { + System.out.println("Handler added"); + tmp = ctx.alloc().buffer(4); + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) { + System.out.println("Handler removed"); + tmp.release(); + tmp = null; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + ByteBuf m = (ByteBuf) msg; + tmp.writeBytes(m); + m.release(); + if (tmp.readableBytes() >= 4) { + RequestData requestData = new RequestData(); + requestData.setIntValue(tmp.readInt()); + ResponseData responseData = new ResponseData(); + responseData.setIntValue(requestData.getIntValue() * 2); + ChannelFuture future = ctx.writeAndFlush(responseData); + future.addListener(ChannelFutureListener.CLOSE); + } + } +} From 14ba94457aa2feb47f1a225e60004fefb2939549 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Fri, 2 Jun 2017 22:44:18 +0300 Subject: [PATCH 05/19] BAEL-768 remove commented code --- .../src/main/java/com/baeldung/netty/ClientHandler.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/src/main/java/com/baeldung/netty/ClientHandler.java b/libraries/src/main/java/com/baeldung/netty/ClientHandler.java index d120d12ec57e..5981affd223c 100644 --- a/libraries/src/main/java/com/baeldung/netty/ClientHandler.java +++ b/libraries/src/main/java/com/baeldung/netty/ClientHandler.java @@ -1,6 +1,5 @@ package com.baeldung.netty; -import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; @@ -10,13 +9,12 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { RequestData msg = new RequestData(); msg.setIntValue(123); msg.setStringValue("all work and no play makes jack a dull boy"); - ChannelFuture future = ctx.writeAndFlush(msg); - //future.addListener(f -> ctx.fireChannelActive()); + ctx.writeAndFlush(msg); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - System.out.println((ResponseData)msg); + System.out.println(msg); ctx.close(); } } From ad9c69a9b0ce3845b84d3fe69a794a9b64661620 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sun, 25 Jun 2017 22:04:13 +0300 Subject: [PATCH 06/19] BAEL-861 Introduction to Awaitility --- libraries/pom.xml | 15 +++- .../com/baeldung/awaitility/AsyncService.java | 50 +++++++++++ .../baeldung/awaitility/AsyncServiceTest.java | 84 +++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 libraries/src/main/java/com/baeldung/awaitility/AsyncService.java create mode 100644 libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java diff --git a/libraries/pom.xml b/libraries/pom.xml index ed4759c336d7..f6254fab20c3 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -381,8 +381,18 @@ java-lsh ${java-lsh.version} - - + + org.awaitility + awaitility + ${awaitility.version} + test + + + org.awaitility + awaitility-proxy + ${awaitility.version} + test + 0.7.0 @@ -410,6 +420,7 @@ 1.1.0 4.1.10.Final 0.10 + 3.0.0 diff --git a/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java b/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java new file mode 100644 index 000000000000..3bc82afaac52 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java @@ -0,0 +1,50 @@ +package com.baeldung.awaitility; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLong; + +public class AsyncService { + private final int DELAY = 1000; + private final int INIT_DELAY = 2000; + + private AtomicLong value = new AtomicLong(0); + private Executor executor = Executors.newFixedThreadPool(4); + private volatile boolean initialized = false; + + public void initialize() { + executor.execute(() -> { + sleep(INIT_DELAY); + initialized = true; + }); + } + + public boolean isInitialized() { + return initialized; + } + + public void addValue(long val) { + if (!isInitialized()) { + throw new IllegalStateException("Service is not initialized"); + } + executor.execute(() -> { + sleep(DELAY); + value.addAndGet(val); + }); + } + + public long getValue() { + if (!isInitialized()) { + throw new IllegalStateException("Service is not initialized"); + } + return value.longValue(); + } + + private void sleep(int delay) { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java new file mode 100644 index 000000000000..5b578bb4f8a2 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java @@ -0,0 +1,84 @@ +package com.baeldung.awaitility; + +import static org.awaitility.Awaitility.await; +import static org.awaitility.Awaitility.fieldIn; +import static org.awaitility.Awaitility.given; +import static org.awaitility.proxy.AwaitilityClassProxy.to; +import static org.hamcrest.Matchers.equalTo; + +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import org.awaitility.Awaitility; +import org.awaitility.Duration; +import org.junit.Before; +import org.junit.Test; + +public class AsyncServiceTest { + private AsyncService asyncService; + + @Before + public void setUp() { + asyncService = new AsyncService(); + } + + @Test + public void givenAsyncService_whenInitialize_thenInitOccurs1() { + asyncService.initialize(); + Callable isInitialized = () -> asyncService.isInitialized(); + await().until(isInitialized); + } + + @Test + public void givenAsyncService_whenInitialize_thenInitOccurs2() { + asyncService.initialize(); + Callable isInitialized = () -> asyncService.isInitialized(); + await().atLeast(Duration.ONE_HUNDRED_MILLISECONDS) + .atMost(Duration.FIVE_SECONDS) + .with().pollInterval(Duration.ONE_HUNDRED_MILLISECONDS) + .until(isInitialized); + } + + @Test + public void givenAsyncService_whenInitialize_thenInitOccurs_withDefualts() { + Awaitility.setDefaultPollInterval(10, TimeUnit.MILLISECONDS); + Awaitility.setDefaultPollDelay(Duration.ZERO); + Awaitility.setDefaultTimeout(Duration.ONE_MINUTE); + + asyncService.initialize(); + await().until(() -> asyncService.isInitialized()); + } + + @Test + public void givenAsyncService_whenInitialize_thenInitOccurs_withProxy() { + asyncService.initialize(); + await().untilCall(to(asyncService).isInitialized(), equalTo(true)); + } + + @Test + public void givenAsyncService_whenInitialize_thenInitOccurs3() { + asyncService.initialize(); + await().until(fieldIn(asyncService) + .ofType(boolean.class) + .andWithName("initialized"), equalTo(true)); + } + + @Test + public void givenValue_whenAddValue_thenValueAdded() { + asyncService.initialize(); + await().until(() -> asyncService.isInitialized()); + long value = 5; + asyncService.addValue(value); + await().until(asyncService::getValue, equalTo(value)); + } + + @Test + public void givenAsyncService_whenGetValue_thenExceptionIgnored() { + asyncService.initialize(); + given().ignoreException(IllegalStateException.class) + .await() + .atMost(Duration.FIVE_SECONDS) + .atLeast(Duration.FIVE_HUNDRED_MILLISECONDS) + .until(asyncService::getValue, equalTo(0L)); + } +} From d0dd51bd892c084b667d2781a8b9f607e8f96d58 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Thu, 6 Jul 2017 23:54:12 +0300 Subject: [PATCH 07/19] BAEL-861 rename Test to UnitTest --- .../{AsyncServiceTest.java => AsyncServiceUnitTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename libraries/src/test/java/com/baeldung/awaitility/{AsyncServiceTest.java => AsyncServiceUnitTest.java} (98%) diff --git a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java rename to libraries/src/test/java/com/baeldung/awaitility/AsyncServiceUnitTest.java index 5b578bb4f8a2..4f07d556b959 100644 --- a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceTest.java +++ b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceUnitTest.java @@ -14,7 +14,7 @@ import org.junit.Before; import org.junit.Test; -public class AsyncServiceTest { +public class AsyncServiceUnitTest { private AsyncService asyncService; @Before From 05525879109c49dcf908082bbe4e7639fd0bfe0a Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Fri, 8 Sep 2017 08:26:28 +0300 Subject: [PATCH 08/19] BAEL-1041 Introduction in Caffeine --- libraries/pom.xml | 6 + .../com/baeldung/caffeine/DataObject.java | 28 ++++ .../baeldung/caffeine/CaffeineUnitTest.java | 157 ++++++++++++++++++ 3 files changed, 191 insertions(+) create mode 100644 libraries/src/main/java/com/baeldung/caffeine/DataObject.java create mode 100644 libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java diff --git a/libraries/pom.xml b/libraries/pom.xml index 9bbc0c41d2ba..751987ba44a4 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -514,6 +514,11 @@ hirondelle-date4j ${hirondelle-date4j.version} + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + @@ -582,5 +587,6 @@ 15.2 2.9.9 1.5.1 + 2.5.5 diff --git a/libraries/src/main/java/com/baeldung/caffeine/DataObject.java b/libraries/src/main/java/com/baeldung/caffeine/DataObject.java new file mode 100644 index 000000000000..2a8b60b045f4 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/caffeine/DataObject.java @@ -0,0 +1,28 @@ +package com.baeldung.caffeine; + +final class DataObject { + private final String data; + + private static int objectCounter = 0; + + private DataObject(String data) { + this.data = data; + } + + public String getData() { + return data; + } + + @Override + public String toString() { + return "DataObject{" + + "data='" + data + '\'' + + '}'; + } + + public static DataObject get(String data) { + objectCounter++; + System.out.println(String.format("Initializing DataObject#%d with data '%s'", objectCounter, data)); + return new DataObject(data); + } +} diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java new file mode 100644 index 000000000000..0587fabfdb28 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -0,0 +1,157 @@ +package com.baeldung.caffeine; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nonnull; + +import org.junit.Test; + +import com.github.benmanes.caffeine.cache.AsyncLoadingCache; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.Expiry; +import com.github.benmanes.caffeine.cache.LoadingCache; + +public class CaffeineUnitTest { + + @Test + public void given_Cache_whenPopulate_thenValueStored() { + Cache cache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.MINUTES) + .maximumSize(100) + .build(); + String key = "A"; + DataObject dataObject = cache.getIfPresent(key); + assertNull(dataObject); + dataObject = cache.get(key, k -> DataObject.get("Data for A")); + assertNotNull(dataObject); + assertEquals(dataObject.getData(), "Data for A"); + cache.put(key, dataObject); + dataObject = cache.getIfPresent(key); + assertNotNull(dataObject); + cache.invalidate(key); + + dataObject = cache.getIfPresent(key); + assertNull(dataObject); + } + + @Test + public void given_LoadingCache_whenGet_thenValuePopulated() { + LoadingCache cache = Caffeine.newBuilder() + .maximumSize(100) + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + String key = "A"; + + DataObject dataObject = cache.get(key); + assertNotNull(dataObject); + assertEquals("Data for " + key, dataObject.getData()); + + Map dataObjectMap = cache.getAll(Arrays.asList("A", "B", "C")); + assertEquals(3, dataObjectMap.size()); + } + + @Test + public void given_AsyncLoadingCache_whenGet_thenValuePopulated() { + + AsyncLoadingCache cache = Caffeine.newBuilder() + .maximumSize(100) + .expireAfterWrite(1, TimeUnit.MINUTES) + .buildAsync(k -> DataObject.get("Data for " + k)); + String key = "A"; + + cache.get(key) + .thenAccept(dataObject -> { + assertNotNull(dataObject); + assertEquals("Data for " + key, dataObject.getData()); + }); + + cache.getAll(Arrays.asList("A", "B", "C")) + .thenAccept(dataObjectMap -> assertEquals(3, dataObjectMap.size())); + } + + @Test + public void given_LoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { + LoadingCache cache = Caffeine.newBuilder() + .maximumSize(1) + .refreshAfterWrite(10, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + assertEquals(0, cache.estimatedSize()); + cache.get("A"); + assertEquals(1, cache.estimatedSize()); + cache.get("B"); + cache.cleanUp(); + assertEquals(1, cache.estimatedSize()); + } + + @Test + public void given_LoadingCacheWithWeighter_whenPut_thenSizeIsConstant() { + LoadingCache cache = Caffeine.newBuilder() + .maximumWeight(10) + .weigher((k,v) -> 5) + .build(k -> DataObject.get("Data for " + k)); + assertEquals(0, cache.estimatedSize()); + cache.get("A"); + assertEquals(1, cache.estimatedSize()); + cache.get("B"); + assertEquals(2, cache.estimatedSize()); + cache.get("C"); + cache.cleanUp(); + assertEquals(2, cache.estimatedSize()); + } + + @Test + public void given_TimeEvictionCache_whenTimeLeft_thenValueEvicted() { + LoadingCache cache = Caffeine.newBuilder() + .expireAfterAccess(5, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder() + .expireAfterWrite(10, TimeUnit.SECONDS) + .weakKeys() + .weakValues() + .softValues() + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder() + .expireAfter(new Expiry() { + @Override + public long expireAfterCreate(@Nonnull String key, @Nonnull DataObject value, long currentTime) { + return value.getData().length()*1000; + } + + @Override + public long expireAfterUpdate(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { + return currentDuration; + } + + @Override + public long expireAfterRead(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { + return currentDuration; + } + }) + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder() + .refreshAfterWrite(1, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + } + + @Test + public void givenCache_whenStatsEnabled_thenStatsRecorded() { + LoadingCache cache = Caffeine.newBuilder() + .maximumSize(100) + .recordStats() + .build(k -> DataObject.get("Data for " + k)); + cache.get("A"); + cache.get("A"); + assertEquals(1, cache.stats().hitCount()); + assertEquals(1, cache.stats().missCount()); + } +} From 0dc0c585777aee448c98f358d96456f168f05d54 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Fri, 8 Sep 2017 08:47:33 +0300 Subject: [PATCH 09/19] BAEL-1041 fix test --- .../src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java index 0587fabfdb28..cb9aa0888be0 100644 --- a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -116,7 +116,6 @@ public void given_TimeEvictionCache_whenTimeLeft_thenValueEvicted() { .expireAfterWrite(10, TimeUnit.SECONDS) .weakKeys() .weakValues() - .softValues() .build(k -> DataObject.get("Data for " + k)); cache = Caffeine.newBuilder() From 6cc922e702cb51eaf3650ba60c56b4dffdbb56f8 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Tue, 19 Sep 2017 23:32:35 +0300 Subject: [PATCH 10/19] BAEL-1041 fix formatting --- .../baeldung/caffeine/CaffeineUnitTest.java | 116 +++++++++--------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java index cb9aa0888be0..dc2f4cee0403 100644 --- a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -1,8 +1,6 @@ package com.baeldung.caffeine; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.*; import java.util.Arrays; import java.util.Map; @@ -12,31 +10,30 @@ import org.junit.Test; -import com.github.benmanes.caffeine.cache.AsyncLoadingCache; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.Expiry; -import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.*; public class CaffeineUnitTest { @Test public void given_Cache_whenPopulate_thenValueStored() { Cache cache = Caffeine.newBuilder() - .expireAfterWrite(1, TimeUnit.MINUTES) - .maximumSize(100) - .build(); + .expireAfterWrite(1, TimeUnit.MINUTES) + .maximumSize(100) + .build(); + String key = "A"; DataObject dataObject = cache.getIfPresent(key); assertNull(dataObject); + dataObject = cache.get(key, k -> DataObject.get("Data for A")); assertNotNull(dataObject); assertEquals(dataObject.getData(), "Data for A"); + cache.put(key, dataObject); dataObject = cache.getIfPresent(key); assertNotNull(dataObject); - cache.invalidate(key); + cache.invalidate(key); dataObject = cache.getIfPresent(key); assertNull(dataObject); } @@ -44,9 +41,9 @@ public void given_Cache_whenPopulate_thenValueStored() { @Test public void given_LoadingCache_whenGet_thenValuePopulated() { LoadingCache cache = Caffeine.newBuilder() - .maximumSize(100) - .expireAfterWrite(1, TimeUnit.MINUTES) - .build(k -> DataObject.get("Data for " + k)); + .maximumSize(100) + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); String key = "A"; DataObject dataObject = cache.get(key); @@ -61,30 +58,32 @@ public void given_LoadingCache_whenGet_thenValuePopulated() { public void given_AsyncLoadingCache_whenGet_thenValuePopulated() { AsyncLoadingCache cache = Caffeine.newBuilder() - .maximumSize(100) - .expireAfterWrite(1, TimeUnit.MINUTES) - .buildAsync(k -> DataObject.get("Data for " + k)); + .maximumSize(100) + .expireAfterWrite(1, TimeUnit.MINUTES) + .buildAsync(k -> DataObject.get("Data for " + k)); String key = "A"; - cache.get(key) - .thenAccept(dataObject -> { + cache.get(key).thenAccept(dataObject -> { assertNotNull(dataObject); assertEquals("Data for " + key, dataObject.getData()); }); cache.getAll(Arrays.asList("A", "B", "C")) - .thenAccept(dataObjectMap -> assertEquals(3, dataObjectMap.size())); + .thenAccept(dataObjectMap -> assertEquals(3, dataObjectMap.size())); } @Test public void given_LoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { LoadingCache cache = Caffeine.newBuilder() - .maximumSize(1) - .refreshAfterWrite(10, TimeUnit.MINUTES) - .build(k -> DataObject.get("Data for " + k)); + .maximumSize(1) + .refreshAfterWrite(10, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + assertEquals(0, cache.estimatedSize()); + cache.get("A"); assertEquals(1, cache.estimatedSize()); + cache.get("B"); cache.cleanUp(); assertEquals(1, cache.estimatedSize()); @@ -93,14 +92,18 @@ public void given_LoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { @Test public void given_LoadingCacheWithWeighter_whenPut_thenSizeIsConstant() { LoadingCache cache = Caffeine.newBuilder() - .maximumWeight(10) - .weigher((k,v) -> 5) - .build(k -> DataObject.get("Data for " + k)); + .maximumWeight(10) + .weigher((k,v) -> 5) + .build(k -> DataObject.get("Data for " + k)); + assertEquals(0, cache.estimatedSize()); + cache.get("A"); assertEquals(1, cache.estimatedSize()); + cache.get("B"); assertEquals(2, cache.estimatedSize()); + cache.get("C"); cache.cleanUp(); assertEquals(2, cache.estimatedSize()); @@ -109,45 +112,44 @@ public void given_LoadingCacheWithWeighter_whenPut_thenSizeIsConstant() { @Test public void given_TimeEvictionCache_whenTimeLeft_thenValueEvicted() { LoadingCache cache = Caffeine.newBuilder() - .expireAfterAccess(5, TimeUnit.MINUTES) - .build(k -> DataObject.get("Data for " + k)); + .expireAfterAccess(5, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); cache = Caffeine.newBuilder() - .expireAfterWrite(10, TimeUnit.SECONDS) - .weakKeys() - .weakValues() - .build(k -> DataObject.get("Data for " + k)); + .expireAfterWrite(10, TimeUnit.SECONDS) + .weakKeys() + .weakValues() + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder().expireAfter(new Expiry() { + @Override + public long expireAfterCreate(@Nonnull String key, @Nonnull DataObject value, long currentTime) { + return value.getData().length() * 1000; + } + + @Override + public long expireAfterUpdate(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { + return currentDuration; + } + + @Override + public long expireAfterRead(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { + return currentDuration; + } + }).build(k -> DataObject.get("Data for " + k)); cache = Caffeine.newBuilder() - .expireAfter(new Expiry() { - @Override - public long expireAfterCreate(@Nonnull String key, @Nonnull DataObject value, long currentTime) { - return value.getData().length()*1000; - } - - @Override - public long expireAfterUpdate(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { - return currentDuration; - } - - @Override - public long expireAfterRead(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { - return currentDuration; - } - }) - .build(k -> DataObject.get("Data for " + k)); - - cache = Caffeine.newBuilder() - .refreshAfterWrite(1, TimeUnit.MINUTES) - .build(k -> DataObject.get("Data for " + k)); + .refreshAfterWrite(1, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); } @Test public void givenCache_whenStatsEnabled_thenStatsRecorded() { LoadingCache cache = Caffeine.newBuilder() - .maximumSize(100) - .recordStats() - .build(k -> DataObject.get("Data for " + k)); + .maximumSize(100) + .recordStats() + .build(k -> DataObject.get("Data for " + k)); + cache.get("A"); cache.get("A"); assertEquals(1, cache.stats().hitCount()); From bb27fd5c7cd11c27d685f4d2f19ebc4fab34d4b1 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Wed, 20 Sep 2017 00:48:24 +0300 Subject: [PATCH 11/19] BAEL-1041 fix expected/actual order --- .../src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java index dc2f4cee0403..1ee14c057d60 100644 --- a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -27,7 +27,7 @@ public void given_Cache_whenPopulate_thenValueStored() { dataObject = cache.get(key, k -> DataObject.get("Data for A")); assertNotNull(dataObject); - assertEquals(dataObject.getData(), "Data for A"); + assertEquals("Data for A", dataObject.getData()); cache.put(key, dataObject); dataObject = cache.getIfPresent(key); From a91fd34cfe3073e57fc730635f50a4f16a8b060d Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Wed, 20 Sep 2017 01:17:43 +0300 Subject: [PATCH 12/19] BAEL-1041 remove trailing underscore --- .../java/com/baeldung/caffeine/CaffeineUnitTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java index 1ee14c057d60..599ff563f4a8 100644 --- a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -15,7 +15,7 @@ public class CaffeineUnitTest { @Test - public void given_Cache_whenPopulate_thenValueStored() { + public void givenCache_whenPopulate_thenValueStored() { Cache cache = Caffeine.newBuilder() .expireAfterWrite(1, TimeUnit.MINUTES) .maximumSize(100) @@ -39,7 +39,7 @@ public void given_Cache_whenPopulate_thenValueStored() { } @Test - public void given_LoadingCache_whenGet_thenValuePopulated() { + public void givenLoadingCache_whenGet_thenValuePopulated() { LoadingCache cache = Caffeine.newBuilder() .maximumSize(100) .expireAfterWrite(1, TimeUnit.MINUTES) @@ -55,7 +55,7 @@ public void given_LoadingCache_whenGet_thenValuePopulated() { } @Test - public void given_AsyncLoadingCache_whenGet_thenValuePopulated() { + public void givenAsyncLoadingCache_whenGet_thenValuePopulated() { AsyncLoadingCache cache = Caffeine.newBuilder() .maximumSize(100) @@ -73,7 +73,7 @@ public void given_AsyncLoadingCache_whenGet_thenValuePopulated() { } @Test - public void given_LoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { + public void givenLoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { LoadingCache cache = Caffeine.newBuilder() .maximumSize(1) .refreshAfterWrite(10, TimeUnit.MINUTES) @@ -90,7 +90,7 @@ public void given_LoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { } @Test - public void given_LoadingCacheWithWeighter_whenPut_thenSizeIsConstant() { + public void givenLoadingCacheWithWeigher_whenPut_thenSizeIsConstant() { LoadingCache cache = Caffeine.newBuilder() .maximumWeight(10) .weigher((k,v) -> 5) @@ -110,7 +110,7 @@ public void given_LoadingCacheWithWeighter_whenPut_thenSizeIsConstant() { } @Test - public void given_TimeEvictionCache_whenTimeLeft_thenValueEvicted() { + public void givenTimeEvictionCache_whenTimeLeft_thenValueEvicted() { LoadingCache cache = Caffeine.newBuilder() .expireAfterAccess(5, TimeUnit.MINUTES) .build(k -> DataObject.get("Data for " + k)); From a27c44249f9a3b0caab3b57db70973b02c8579cd Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sat, 30 Sep 2017 13:05:14 +0300 Subject: [PATCH 13/19] Formatting after merge --- libraries/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index 9ec54947ff17..5b14afa8d580 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -590,11 +590,11 @@ jgrapht-core 1.0.1 - - com.hazelcast - hazelcast - ${hazelcast.version} - + + com.hazelcast + hazelcast + ${hazelcast.version} + com.github.ben-manes.caffeine caffeine From 5d400d6c1e55de4d9ff267ac7379da94f86a25db Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sat, 30 Sep 2017 13:08:57 +0300 Subject: [PATCH 14/19] BAEL-1041 add spaces between data and assertions --- .../com/baeldung/caffeine/CaffeineUnitTest.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java index 599ff563f4a8..82028d13416a 100644 --- a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -23,18 +23,22 @@ public void givenCache_whenPopulate_thenValueStored() { String key = "A"; DataObject dataObject = cache.getIfPresent(key); + assertNull(dataObject); dataObject = cache.get(key, k -> DataObject.get("Data for A")); + assertNotNull(dataObject); assertEquals("Data for A", dataObject.getData()); cache.put(key, dataObject); dataObject = cache.getIfPresent(key); + assertNotNull(dataObject); cache.invalidate(key); dataObject = cache.getIfPresent(key); + assertNull(dataObject); } @@ -47,10 +51,12 @@ public void givenLoadingCache_whenGet_thenValuePopulated() { String key = "A"; DataObject dataObject = cache.get(key); + assertNotNull(dataObject); assertEquals("Data for " + key, dataObject.getData()); Map dataObjectMap = cache.getAll(Arrays.asList("A", "B", "C")); + assertEquals(3, dataObjectMap.size()); } @@ -82,10 +88,12 @@ public void givenLoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { assertEquals(0, cache.estimatedSize()); cache.get("A"); + assertEquals(1, cache.estimatedSize()); cache.get("B"); cache.cleanUp(); + assertEquals(1, cache.estimatedSize()); } @@ -99,13 +107,16 @@ public void givenLoadingCacheWithWeigher_whenPut_thenSizeIsConstant() { assertEquals(0, cache.estimatedSize()); cache.get("A"); + assertEquals(1, cache.estimatedSize()); cache.get("B"); + assertEquals(2, cache.estimatedSize()); cache.get("C"); cache.cleanUp(); + assertEquals(2, cache.estimatedSize()); } @@ -149,10 +160,10 @@ public void givenCache_whenStatsEnabled_thenStatsRecorded() { .maximumSize(100) .recordStats() .build(k -> DataObject.get("Data for " + k)); - cache.get("A"); cache.get("A"); + assertEquals(1, cache.stats().hitCount()); assertEquals(1, cache.stats().missCount()); } -} +} \ No newline at end of file From 91aedcf7c052adeecc3cfa926bb06ed46ea760a5 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sat, 30 Sep 2017 13:43:39 +0300 Subject: [PATCH 15/19] BAEL-1041 soft values example --- .../test/java/com/baeldung/caffeine/CaffeineUnitTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java index 82028d13416a..56dbda5974a7 100644 --- a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -132,6 +132,11 @@ public void givenTimeEvictionCache_whenTimeLeft_thenValueEvicted() { .weakValues() .build(k -> DataObject.get("Data for " + k)); + cache = Caffeine.newBuilder() + .expireAfterWrite(10, TimeUnit.SECONDS) + .softValues() + .build(k -> DataObject.get("Data for " + k)); + cache = Caffeine.newBuilder().expireAfter(new Expiry() { @Override public long expireAfterCreate(@Nonnull String key, @Nonnull DataObject value, long currentTime) { From 2f25c20f41140db239234aaa47275adad2fafe54 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Tue, 10 Oct 2017 22:31:01 +0300 Subject: [PATCH 16/19] BAEL-1041 remove duplicate dependency --- libraries/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index 3f6f85973542..72155c905af9 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -595,11 +595,6 @@ jaxb-api 2.1 - - com.hazelcast - hazelcast - ${hazelcast.version} - com.github.ben-manes.caffeine caffeine From 46cf1c128a441cfdae44f4d063a737732fe8520a Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Tue, 10 Oct 2017 22:34:41 +0300 Subject: [PATCH 17/19] BAEL-1041 formatting fix --- libraries/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index 72155c905af9..76899c7a9fe9 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -670,7 +670,7 @@ 1.14 1.0.3 1.0.0 - 3.8.4 + 3.8.4 2.5.5 From 10cc7659aee6b879615009a0ae37e7ed5920b229 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Tue, 10 Oct 2017 22:37:04 +0300 Subject: [PATCH 18/19] BAEL-1041 formatting fix --- libraries/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index 76899c7a9fe9..b519b9cd53d3 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -590,11 +590,11 @@ docx4j 3.3.5 - - javax.xml.bind - jaxb-api - 2.1 - + + javax.xml.bind + jaxb-api + 2.1 + com.github.ben-manes.caffeine caffeine From e7a58313924dc6e4d61a2b4f25ccfc5c759438e4 Mon Sep 17 00:00:00 2001 From: Anton Sipachev Date: Sat, 14 Oct 2017 19:58:35 +0300 Subject: [PATCH 19/19] BAEL-1041 use logger instead of sout --- .../src/main/java/com/baeldung/caffeine/DataObject.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/src/main/java/com/baeldung/caffeine/DataObject.java b/libraries/src/main/java/com/baeldung/caffeine/DataObject.java index 2a8b60b045f4..a90b3e9f2192 100644 --- a/libraries/src/main/java/com/baeldung/caffeine/DataObject.java +++ b/libraries/src/main/java/com/baeldung/caffeine/DataObject.java @@ -1,9 +1,13 @@ package com.baeldung.caffeine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + final class DataObject { private final String data; private static int objectCounter = 0; + private static final Logger log = LoggerFactory.getLogger(DataObject.class); private DataObject(String data) { this.data = data; @@ -22,7 +26,7 @@ public String toString() { public static DataObject get(String data) { objectCounter++; - System.out.println(String.format("Initializing DataObject#%d with data '%s'", objectCounter, data)); + log.info("Init DataObject#{} with '{}'", objectCounter, data); return new DataObject(data); } }