From 8efe817cd38e160faafa9fb113b73fcee773ba90 Mon Sep 17 00:00:00 2001 From: Roger Yates <587230+rojyates@users.noreply.github.com> Date: Tue, 10 Mar 2020 09:19:13 +1000 Subject: [PATCH 1/5] BAEL-3603 Add test examples for Java IO versus NIO article --- core-java-modules/core-java-io-2/pom.xml | 8 ++ .../BlockingClientUnitTest.java | 51 ++++++++++ .../NonBlockingClientUnitTest.java | 94 +++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java create mode 100644 core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml index 0c271737d9..960cc51bbd 100644 --- a/core-java-modules/core-java-io-2/pom.xml +++ b/core-java-modules/core-java-io-2/pom.xml @@ -45,6 +45,14 @@ ${assertj.version} test + + + com.github.tomakehurst + wiremock + 2.26.3 + test + + diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java new file mode 100644 index 0000000000..eca2a2638f --- /dev/null +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.blockingnonblocking; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import java.io.*; +import java.net.Socket; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.junit.Assert.assertTrue; + +public class BlockingClientUnitTest { + private static final String REQUESTED_RESOURCE = "/test.json"; + + @Rule public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort()); + + @Before + public void setup() { + stubFor(get(urlEqualTo(REQUESTED_RESOURCE)).willReturn(aResponse() + .withStatus(200) + .withBody("{ \"response\" : \"It worked!\" }\r\n\r\n"))); + } + + @Test + public void givenJavaIOSocket_whenReadingAndWritingWithStreams_thenReadSuccessfully() throws IOException { + // given an IO socket and somewhere to store our result + Socket socket = new Socket("localhost", wireMockRule.port()); + StringBuilder ourStore = new StringBuilder(); + + // when we write and read (using try-with-resources so our resources are auto-closed) + try (InputStream serverInput = socket.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(serverInput)); + OutputStream clientOutput = socket.getOutputStream(); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(clientOutput))) { + writer.print("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"); + writer.flush(); // important - without this the request is never sent, and the test will hang on readLine() + + for (String line; (line = reader.readLine()) != null; ) { + ourStore.append(line); + } + } + + // then we read and saved our data + assertTrue(ourStore + .toString() + .contains("It worked!")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java new file mode 100644 index 0000000000..47115887ab --- /dev/null +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.blockingnonblocking; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.channels.SocketChannel; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.StandardCharsets; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.junit.Assert.assertTrue; + +public class NonBlockingClientUnitTest { + private String REQUESTED_RESOURCE = "/test.json"; + + @Rule public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort()); + + @Before + public void setup() { + stubFor(get(urlEqualTo(REQUESTED_RESOURCE)).willReturn(aResponse() + .withStatus(200) + .withBody("{ \"response\" : \"It worked!\" }"))); + } + + @Test + public void givenJavaNIOSocketChannel_whenReadingAndWriting_thenUseBuffers() throws IOException { + // given a NIO SocketChannel and a charset + InetSocketAddress address = new InetSocketAddress("localhost", wireMockRule.port()); + SocketChannel socketChannel = SocketChannel.open(address); + Charset charset = StandardCharsets.UTF_8; + + // when we write and read using buffers + socketChannel.write(charset.encode(CharBuffer.wrap("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"))); + + ByteBuffer buffer = ByteBuffer.allocate(8); // or allocateDirect if we need direct memory access + CharBuffer charBuffer = CharBuffer.allocate(8192); + CharsetDecoder decoder = charset.newDecoder(); + StringBuilder ourStore = new StringBuilder(); + while (socketChannel.read(buffer) != -1 || buffer.position() > 0) { + buffer.flip(); + storeBufferContents(buffer, charBuffer, decoder, ourStore); + buffer.compact(); + } + socketChannel.close(); + + // then we read and saved our data + assertTrue(ourStore + .toString() + .contains("It worked!")); + } + + @Test + public void givenJavaNIO_whenReadingAndWriting_thenSmallBuffers() throws IOException { + // given a NIO SocketChannel and a charset + InetSocketAddress address = new InetSocketAddress("localhost", wireMockRule.port()); + SocketChannel socket = SocketChannel.open(address); + Charset charset = StandardCharsets.UTF_8; + + // when we write and read using buffers that are too small for our message + socket.write(charset.encode(CharBuffer.wrap("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"))); + + ByteBuffer buffer = ByteBuffer.allocate(8); // or allocateDirect if we need direct memory access + CharBuffer charBuffer = CharBuffer.allocate(8); + CharsetDecoder decoder = charset.newDecoder(); + StringBuilder ourStore = new StringBuilder(); + while (socket.read(buffer) != -1 || buffer.position() > 0) { + buffer.flip(); + storeBufferContents(buffer, charBuffer, decoder, ourStore); + buffer.compact(); + } + socket.close(); + + // then we read and saved our data + assertTrue(ourStore + .toString() + .contains("It worked!")); + } + + void storeBufferContents(ByteBuffer buffer, CharBuffer charBuffer, CharsetDecoder decoder, StringBuilder ourStore) { + decoder.decode(buffer, charBuffer, true); + charBuffer.flip(); + ourStore.append(charBuffer); + charBuffer.clear(); + } + +} \ No newline at end of file From fad2d2a67ccc4d709f817ae902fa5078cca00d68 Mon Sep 17 00:00:00 2001 From: Roger Yates <587230+rojyates@users.noreply.github.com> Date: Thu, 12 Mar 2020 06:12:42 +1000 Subject: [PATCH 2/5] BAEL-3603 Add line separator to preserve lines read --- .../com/baeldung/blockingnonblocking/BlockingClientUnitTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java index eca2a2638f..3fc968ded0 100644 --- a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java @@ -40,6 +40,7 @@ public class BlockingClientUnitTest { for (String line; (line = reader.readLine()) != null; ) { ourStore.append(line); + ourStore.append(System.lineSeparator()); } } From 5c83dddb9182c0d74ba3685d6f5c7f09f7417681 Mon Sep 17 00:00:00 2001 From: Roger Yates <587230+rojyates@users.noreply.github.com> Date: Mon, 16 Mar 2020 06:23:33 +1000 Subject: [PATCH 3/5] BAEL-3603 Update method names and variable name for PR --- .../blockingnonblocking/BlockingClientUnitTest.java | 2 +- .../NonBlockingClientUnitTest.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java index 3fc968ded0..cd3d688763 100644 --- a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/BlockingClientUnitTest.java @@ -25,7 +25,7 @@ public class BlockingClientUnitTest { } @Test - public void givenJavaIOSocket_whenReadingAndWritingWithStreams_thenReadSuccessfully() throws IOException { + public void givenJavaIOSocket_whenReadingAndWritingWithStreams_thenSuccess() throws IOException { // given an IO socket and somewhere to store our result Socket socket = new Socket("localhost", wireMockRule.port()); StringBuilder ourStore = new StringBuilder(); diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java index 47115887ab..90edee0306 100644 --- a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java @@ -31,7 +31,7 @@ public class NonBlockingClientUnitTest { } @Test - public void givenJavaNIOSocketChannel_whenReadingAndWriting_thenUseBuffers() throws IOException { + public void givenJavaNIOSocketChannel_whenReadingAndWritingWithBuffers_thenSuccess() throws IOException { // given a NIO SocketChannel and a charset InetSocketAddress address = new InetSocketAddress("localhost", wireMockRule.port()); SocketChannel socketChannel = SocketChannel.open(address); @@ -58,25 +58,25 @@ public class NonBlockingClientUnitTest { } @Test - public void givenJavaNIO_whenReadingAndWriting_thenSmallBuffers() throws IOException { + public void givenJavaNIOSocketChannel_whenReadingAndWritingWithSmallBuffers_thenSuccess() throws IOException { // given a NIO SocketChannel and a charset InetSocketAddress address = new InetSocketAddress("localhost", wireMockRule.port()); - SocketChannel socket = SocketChannel.open(address); + SocketChannel socketChannel = SocketChannel.open(address); Charset charset = StandardCharsets.UTF_8; // when we write and read using buffers that are too small for our message - socket.write(charset.encode(CharBuffer.wrap("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"))); + socketChannel.write(charset.encode(CharBuffer.wrap("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"))); ByteBuffer buffer = ByteBuffer.allocate(8); // or allocateDirect if we need direct memory access CharBuffer charBuffer = CharBuffer.allocate(8); CharsetDecoder decoder = charset.newDecoder(); StringBuilder ourStore = new StringBuilder(); - while (socket.read(buffer) != -1 || buffer.position() > 0) { + while (socketChannel.read(buffer) != -1 || buffer.position() > 0) { buffer.flip(); storeBufferContents(buffer, charBuffer, decoder, ourStore); buffer.compact(); } - socket.close(); + socketChannel.close(); // then we read and saved our data assertTrue(ourStore From 38843e814bfcee140d766957f63514e984210230 Mon Sep 17 00:00:00 2001 From: Roger Yates <587230+rojyates@users.noreply.github.com> Date: Tue, 17 Mar 2020 06:32:39 +1000 Subject: [PATCH 4/5] BAEL-3603 Update variable names --- .../NonBlockingClientUnitTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java index 90edee0306..838d456f03 100644 --- a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java @@ -40,14 +40,14 @@ public class NonBlockingClientUnitTest { // when we write and read using buffers socketChannel.write(charset.encode(CharBuffer.wrap("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"))); - ByteBuffer buffer = ByteBuffer.allocate(8); // or allocateDirect if we need direct memory access + ByteBuffer byteBuffer = ByteBuffer.allocate(8192); // or allocateDirect if we need direct memory access CharBuffer charBuffer = CharBuffer.allocate(8192); - CharsetDecoder decoder = charset.newDecoder(); + CharsetDecoder charsetDecoder = charset.newDecoder(); StringBuilder ourStore = new StringBuilder(); - while (socketChannel.read(buffer) != -1 || buffer.position() > 0) { - buffer.flip(); - storeBufferContents(buffer, charBuffer, decoder, ourStore); - buffer.compact(); + while (socketChannel.read(byteBuffer) != -1 || byteBuffer.position() > 0) { + byteBuffer.flip(); + storeBufferContents(byteBuffer, charBuffer, charsetDecoder, ourStore); + byteBuffer.compact(); } socketChannel.close(); @@ -67,14 +67,14 @@ public class NonBlockingClientUnitTest { // when we write and read using buffers that are too small for our message socketChannel.write(charset.encode(CharBuffer.wrap("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r\n\r\n"))); - ByteBuffer buffer = ByteBuffer.allocate(8); // or allocateDirect if we need direct memory access + ByteBuffer byteBuffer = ByteBuffer.allocate(8); // or allocateDirect if we need direct memory access CharBuffer charBuffer = CharBuffer.allocate(8); - CharsetDecoder decoder = charset.newDecoder(); + CharsetDecoder charsetDecoder = charset.newDecoder(); StringBuilder ourStore = new StringBuilder(); - while (socketChannel.read(buffer) != -1 || buffer.position() > 0) { - buffer.flip(); - storeBufferContents(buffer, charBuffer, decoder, ourStore); - buffer.compact(); + while (socketChannel.read(byteBuffer) != -1 || byteBuffer.position() > 0) { + byteBuffer.flip(); + storeBufferContents(byteBuffer, charBuffer, charsetDecoder, ourStore); + byteBuffer.compact(); } socketChannel.close(); From 0f5889567e3dc1cb1d7fff20e855a30f81842a14 Mon Sep 17 00:00:00 2001 From: Roger Yates <587230+rojyates@users.noreply.github.com> Date: Tue, 17 Mar 2020 06:35:29 +1000 Subject: [PATCH 5/5] BAEL-3603 Update variable names --- .../blockingnonblocking/NonBlockingClientUnitTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java index 838d456f03..3e606476e6 100644 --- a/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java +++ b/core-java-modules/core-java-io-2/src/test/java/com/baeldung/blockingnonblocking/NonBlockingClientUnitTest.java @@ -84,8 +84,8 @@ public class NonBlockingClientUnitTest { .contains("It worked!")); } - void storeBufferContents(ByteBuffer buffer, CharBuffer charBuffer, CharsetDecoder decoder, StringBuilder ourStore) { - decoder.decode(buffer, charBuffer, true); + void storeBufferContents(ByteBuffer byteBuffer, CharBuffer charBuffer, CharsetDecoder charsetDecoder, StringBuilder ourStore) { + charsetDecoder.decode(byteBuffer, charBuffer, true); charBuffer.flip(); ourStore.append(charBuffer); charBuffer.clear();