Use slf4j
This commit is contained in:
parent
58e0d56051
commit
901e18c307
8 changed files with 130 additions and 35 deletions
67
pom.xml
67
pom.xml
|
@ -11,7 +11,9 @@
|
|||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<exec.mainClass>eu.m724.Main</exec.mainClass>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -20,6 +22,71 @@
|
|||
<artifactId>json</artifactId>
|
||||
<version>20250107</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>2.0.16</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.16</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>26.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.4.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<mainClass>${exec.mainClass}</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -4,6 +4,8 @@ import eu.m724.docker.DockerEngine;
|
|||
import eu.m724.docker.exception.FailedRequestException;
|
||||
import eu.m724.docker.proxy.TcpSocketProxy;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.StandardProtocolFamily;
|
||||
|
@ -11,29 +13,30 @@ import java.net.UnixDomainSocketAddress;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class Main {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
var proxy = new TcpSocketProxy(StandardProtocolFamily.UNIX, UnixDomainSocketAddress.of("/var/run/docker.sock"));
|
||||
proxy.start();
|
||||
System.out.println("Started");
|
||||
|
||||
System.out.printf("Tested in %d ms %n", proxy.test() / 1000000);
|
||||
LOGGER.info("Latency to remote: {} ms", proxy.test() / 1000000);
|
||||
|
||||
var engine = new DockerEngine(proxy.getURI());
|
||||
engine.ping().join();
|
||||
|
||||
var info = engine.info().join();
|
||||
System.out.println("Docker runtime:");
|
||||
System.out.println("- " + info.getString("ID"));
|
||||
System.out.println("- " + info.getString("OSType") + " " + info.getString("Architecture"));
|
||||
System.out.println("- OS: " + info.getString("OperatingSystem") + " " + info.getString("OSVersion"));
|
||||
System.out.println("- Hostname: " + info.getString("Name"));
|
||||
LOGGER.info("Docker runtime:");
|
||||
LOGGER.info("- {}", info.getString("ID"));
|
||||
LOGGER.info("- {}, {}", info.getString("OSType"), info.getString("Architecture"));
|
||||
LOGGER.info("- OS: {} version {}", info.getString("OperatingSystem"), info.getString("OSVersion"));
|
||||
LOGGER.info("- Hostname: {}", info.getString("Name"));
|
||||
|
||||
JSONObject containerInfo = null;
|
||||
try {
|
||||
containerInfo = engine.inspectContainer("dcdn_nginx").get();
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof FailedRequestException fre && fre.getResponse().statusCode() == 404) {
|
||||
System.out.println("Container doesn't exist");
|
||||
LOGGER.info("Container doesn't exist");
|
||||
} else {
|
||||
throw new RuntimeException("Exception getting container info", e);
|
||||
}
|
||||
|
@ -41,14 +44,14 @@ public class Main {
|
|||
|
||||
if (containerInfo != null) {
|
||||
var mounts = containerInfo.getJSONArray("Mounts");
|
||||
System.out.printf("Detected %d mounts:%n", mounts.length());
|
||||
LOGGER.debug("Detected {} mounts:", mounts.length());
|
||||
for (int i=0; i<mounts.length(); i++) {
|
||||
var j = mounts.getJSONObject(i);
|
||||
|
||||
System.out.printf("%s %s -> %s %n", j.getString("Name"), j.getString("Source"), j.getString("Destination"));
|
||||
LOGGER.debug("{} {} -> {}", j.getString("Name"), j.getString("Source"), j.getString("Destination"));
|
||||
}
|
||||
} else {
|
||||
System.out.println("Creating it");
|
||||
LOGGER.info("Creating it");
|
||||
|
||||
var data = new JSONObject()
|
||||
.put("Image", "nginx:1.27");
|
||||
|
|
|
@ -3,6 +3,8 @@ package eu.m724.docker;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
@ -12,7 +14,7 @@ public class DockerEngine {
|
|||
|
||||
|
||||
public DockerEngine(URI socketUri) {
|
||||
this.dao = new DockerEngineDAO(socketUri);
|
||||
this.dao = new DockerEngineDAO(socketUri, HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).connectTimeout(Duration.ofSeconds(30)).build());
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> ping() {
|
||||
|
|
|
@ -1,31 +1,34 @@
|
|||
package eu.m724.docker;
|
||||
|
||||
import eu.m724.docker.exception.FailedRequestException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DockerEngineDAO {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DockerEngineDAO.class);
|
||||
|
||||
private final URI socketUri;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
DockerEngineDAO(URI socketUri) {
|
||||
DockerEngineDAO(URI socketUri, HttpClient httpClient) {
|
||||
this.socketUri = socketUri;
|
||||
this.httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).connectTimeout(Duration.ofSeconds(30)).build();
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
httpClient.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a GET request that expects a JSON from the server.<br>
|
||||
* A {@link FailedRequestException} is thrown by the future if a non-200 status code is returned.
|
||||
|
@ -172,19 +175,16 @@ public class DockerEngineDAO {
|
|||
}
|
||||
|
||||
|
||||
private HttpRequest createRequest(String path) {
|
||||
return HttpRequest.newBuilder(socketUri.resolve(path)).build();
|
||||
}
|
||||
private <T> CompletableFuture<T> commonRequest(@NotNull String path, @Nullable Map<String, Object> queryParams, @Nullable JSONObject data, @NotNull HttpResponse.BodyHandler<T> bodyHandler) {
|
||||
Objects.requireNonNull(path, "Request path cannot be null");
|
||||
Objects.requireNonNull(bodyHandler, "Body handler cannot be null");
|
||||
|
||||
private <T> CompletableFuture<T> commonRequest(String path, Map<String, Object> queryParams, JSONObject data, HttpResponse.BodyHandler<T> bodyHandler) {
|
||||
if (queryParams != null && !queryParams.isEmpty()) {
|
||||
path += '?';
|
||||
path += queryParams.entrySet().stream()
|
||||
.map(e -> e.getKey() + '=' + e.getValue())
|
||||
.collect(Collectors.joining("&"));
|
||||
path += encodeQueryParams(queryParams);
|
||||
}
|
||||
|
||||
System.out.println(path);
|
||||
LOGGER.debug("Calling request: {}", path);
|
||||
|
||||
var builder = HttpRequest.newBuilder(socketUri.resolve(path));
|
||||
|
||||
if (data != null) {
|
||||
|
@ -200,4 +200,12 @@ public class DockerEngineDAO {
|
|||
return response.body();
|
||||
});
|
||||
}
|
||||
|
||||
private String encodeQueryParams(@NotNull Map<String, Object> params) {
|
||||
return params.entrySet().stream()
|
||||
.map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8) +
|
||||
"=" +
|
||||
URLEncoder.encode(String.valueOf(e.getValue()), StandardCharsets.UTF_8))
|
||||
.collect(Collectors.joining("&", "?", ""));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public class FailedRequestException extends CompletionException {
|
|||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Code: " + response.statusCode() + " | Body: " + response.body();
|
||||
return "Request failed with status %d: %s".formatted(response.statusCode(), response.body());
|
||||
}
|
||||
|
||||
public HttpResponse<?> getResponse() {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package eu.m724.docker.proxy;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -13,6 +16,8 @@ public class ConnectionThread extends Thread {
|
|||
private final RemoteSocketFactory remoteSocketFactory;
|
||||
private final Socket clientSocket;
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(ConnectionThread.class);
|
||||
|
||||
ConnectionThread(ExecutorService executorService, RemoteSocketFactory remoteSocketFactory, Socket clientSocket) {
|
||||
this.executorService = executorService;
|
||||
this.remoteSocketFactory = remoteSocketFactory;
|
||||
|
@ -25,11 +30,11 @@ public class ConnectionThread extends Thread {
|
|||
clientSocket;
|
||||
var remoteSocket = remoteSocketFactory.newChannel()
|
||||
) {
|
||||
System.out.println("connected");
|
||||
LOGGER.debug("starting inner");
|
||||
inner(remoteSocket);
|
||||
System.out.println("disconnected");
|
||||
LOGGER.debug("inner ended");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Exception handling client: " + e.getMessage());
|
||||
LOGGER.error("Exception handling client", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
package eu.m724.docker.proxy;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class ServerRunnable implements Runnable {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServerRunnable.class);
|
||||
|
||||
private final ExecutorService executorService;
|
||||
private final ServerSocket serverSocket;
|
||||
private final RemoteSocketFactory remoteSocketFactory;
|
||||
|
@ -26,7 +31,7 @@ public class ServerRunnable implements Runnable {
|
|||
} catch (IOException e) {
|
||||
if (serverSocket.isClosed()) break;
|
||||
|
||||
System.err.println("Exception handling client request: " + e.getMessage());
|
||||
LOGGER.error("Exception handling client request", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
package eu.m724.docker.proxy;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class TcpSocketProxy implements AutoCloseable {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TcpSocketProxy.class);
|
||||
|
||||
private final RemoteSocketFactory remoteSocketFactory;
|
||||
|
||||
private ServerSocket serverSocket;
|
||||
|
@ -28,7 +33,7 @@ public class TcpSocketProxy implements AutoCloseable {
|
|||
this.executorService = Executors.newVirtualThreadPerTaskExecutor();
|
||||
executorService.execute(new ServerRunnable(executorService, serverSocket, remoteSocketFactory));
|
||||
|
||||
System.out.println("Proxy bound on " + getURI());
|
||||
LOGGER.info("Proxy bound on {}", getURI());
|
||||
}
|
||||
|
||||
public long test() throws IOException {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue