BAEL-5076 Unix domain socket in Java 16 (#11493)

* BAEL-5076 Unix domain socket in Java 16

* BAEL-5076 Unix domain socket in Java 16

* BAEL-5076 Unix domain socket in Java 16

* BAEL-5076 Unix domain socket in Java 16

Co-authored-by: krzysztof <kmajewski@berg.technology>
This commit is contained in:
Krzysztof Majewski 2021-11-26 18:06:20 +01:00 committed by GitHub
parent f09327b2d9
commit dcd9411cf3
7 changed files with 250 additions and 1 deletions

View File

@ -64,6 +64,16 @@
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>

View File

@ -0,0 +1,49 @@
package com.baeldung.socket;
import java.io.IOException;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
class UnixDomainSocketClient {
public static void main(String[] args) throws Exception {
new UnixDomainSocketClient().runClient();
}
void runClient() throws IOException {
Path socketPath = Path.of(System.getProperty("user.home"))
.resolve("baeldung.socket");
UnixDomainSocketAddress socketAddress = getAddress(socketPath);
SocketChannel channel = openSocketChannel(socketAddress);
String message = "Hello from Baeldung Unix domain socket article";
writeMessage(channel, message);
}
UnixDomainSocketAddress getAddress(Path socketPath) {
return UnixDomainSocketAddress.of(socketPath);
}
SocketChannel openSocketChannel(UnixDomainSocketAddress socketAddress) throws IOException {
SocketChannel channel = SocketChannel
.open(StandardProtocolFamily.UNIX);
channel.connect(socketAddress);
return channel;
}
void writeMessage(SocketChannel socketChannel, String message) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.clear();
buffer.put(message.getBytes());
buffer.flip();
while (buffer.hasRemaining()) {
socketChannel.write(buffer);
}
}
}

View File

@ -0,0 +1,57 @@
package com.baeldung.socket;
import java.io.IOException;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
class UnixDomainSocketServer {
public static void main(String[] args) throws IOException, InterruptedException {
new UnixDomainSocketServer().runServer();
}
void runServer() throws IOException, InterruptedException {
Path socketPath = Path.of(System.getProperty("user.home"))
.resolve("baeldung.socket");
Files.deleteIfExists(socketPath);
UnixDomainSocketAddress socketAddress = getAddress(socketPath);
ServerSocketChannel serverChannel = createServerSocketChannel(socketAddress);
SocketChannel channel = serverChannel.accept();
while (true) {
readSocketMessage(channel)
.ifPresent(message -> System.out.printf("[Client message] %s%n", message));
Thread.sleep(100);
}
}
UnixDomainSocketAddress getAddress(Path socketPath) {
return UnixDomainSocketAddress.of(socketPath);
}
ServerSocketChannel createServerSocketChannel(UnixDomainSocketAddress socketAddress) throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
serverChannel.bind(socketAddress);
return serverChannel;
}
Optional<String> readSocketMessage(SocketChannel channel) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
if (bytesRead < 0) return Optional.empty();
byte[] bytes = new byte[bytesRead];
buffer.flip();
buffer.get(bytes);
String message = new String(bytes);
return Optional.of(message);
}
}

View File

@ -0,0 +1,82 @@
package com.baeldung.socket;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.io.IOException;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.util.UUID;
import static java.nio.file.Files.deleteIfExists;
import static org.assertj.core.util.Files.newTemporaryFile;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class UnixDomainSocketClientUnitTest {
@Test
public void givenSocketPath_shouldCreateUnixDomainSocketAddress() {
// given
File tempFile = newTemporaryFile();
Path socketPath = tempFile.toPath();
// when
UnixDomainSocketAddress address = new UnixDomainSocketClient().getAddress(socketPath);
// then
assertEquals(address.getPath(), socketPath);
// cleanup
tempFile.delete();
}
@Test
public void givenUnixDomainSocketAddress_shouldOpenSocketChannel() throws IOException {
// given
File tempFile = newTemporaryFile();
Path socketPath = tempFile.toPath();
deleteIfExists(socketPath);
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketPath);
// bind address as a unix domain socket
ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
serverChannel.bind(address);
// when
SocketChannel socketChannel = new UnixDomainSocketClient().openSocketChannel(address);
// then
assertTrue(socketChannel.isOpen());
assertEquals(socketChannel.getRemoteAddress(), address);
// cleanup
tempFile.delete();
}
@Test
public void givenSocketChannelAndMessage_shouldWriteMessage() throws IOException {
// given
SocketChannel socketChannel = Mockito.mock(SocketChannel.class);
String message = UUID.randomUUID().toString();
Mockito.when(socketChannel.write(Mockito.any(ByteBuffer.class)))
.thenAnswer(
(Answer<Integer>) invocationOnMock -> {
((ByteBuffer) invocationOnMock.getArguments()[0]).position(message.getBytes().length);
return -1;
}
);
// when
new UnixDomainSocketClient().writeMessage(socketChannel, message);
// then
Mockito.verify(socketChannel, Mockito.times(1)).write(Mockito.any(ByteBuffer.class));
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.socket;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.net.UnixDomainSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.file.Path;
import static java.nio.file.Files.deleteIfExists;
import static org.assertj.core.util.Files.newTemporaryFile;
import static org.junit.Assert.assertEquals;
public class UnixDomainSocketServerUnitTest {
@Test
public void givenSocketPath_shouldCreateUnixDomainSocketAddress() {
// given
File tempFile = newTemporaryFile();
Path socketPath = tempFile.toPath();
// when
UnixDomainSocketAddress address = new UnixDomainSocketServer().getAddress(socketPath);
// then
assertEquals(address.getPath(), socketPath);
// cleanup
tempFile.delete();
}
@Test
public void givenUnixDomainSocketAddress_shouldCreateServerSocketChannel() throws IOException {
// given
File tempFile = newTemporaryFile();
Path socketPath = tempFile.toPath();
deleteIfExists(socketPath);
UnixDomainSocketAddress address = UnixDomainSocketAddress.of(socketPath);
// when
ServerSocketChannel serverSocketChannel = new UnixDomainSocketServer().createServerSocketChannel(address);
// then
assertEquals(serverSocketChannel.getLocalAddress(), address);
// cleanup
tempFile.delete();
}
}

View File

@ -90,7 +90,6 @@
<module>core-java-lang-syntax-2</module>
<module>core-java-networking</module>
<module>core-java-networking-2</module>
<module>core-java-networking-3</module>
<module>core-java-nio</module>
<module>core-java-nio-2</module>
<module>core-java-optional</module>

View File

@ -1322,6 +1322,7 @@
<module>core-java-modules/core-java-string-operations-3</module>
<module>core-java-modules/core-java-string-operations-4</module>
<module>core-java-modules/core-java-time-measurements</module>
<module>core-java-modules/core-java-networking-3</module>
<module>core-java-modules/multimodulemavenproject</module>
<module>persistence-modules/sirix</module>
<module>quarkus-vs-springboot</module>
@ -1375,6 +1376,7 @@
<module>core-java-modules/core-java-os</module>
<module>core-java-modules/core-java-string-operations-3</module>
<module>core-java-modules/core-java-time-measurements</module>
<module>core-java-modules/core-java-networking-3</module>
<module>core-java-modules/multimodulemavenproject</module>
<module>core-java-modules/core-java-strings</module>
<module>persistence-modules/sirix</module>