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:
parent
f09327b2d9
commit
dcd9411cf3
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
2
pom.xml
2
pom.xml
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user