From d02fd1a989efd8daea75c7455031b6d05fb128d0 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Mon, 1 Apr 2019 15:44:42 +0200 Subject: [PATCH] openvidu-server: allow exposing ports in docker containers --- .../service/ComposedRecordingService.java | 4 +- .../io/openvidu/server/rpc/RpcHandler.java | 2 +- .../server/utils/CustomFileManager.java | 22 ++++++- .../openvidu/server/utils/DockerManager.java | 59 +++++++++++++++++-- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java b/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java index 06eab02a..3f28e2d7 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java +++ b/openvidu-server/src/main/java/io/openvidu/server/recording/service/ComposedRecordingService.java @@ -162,7 +162,7 @@ public class ComposedRecordingService extends RecordingService { List binds = new ArrayList<>(); binds.add(bind1); binds.add(bind2); - containerId = dockerManager.runContainer(container, containerName, volumes, binds, envs); + containerId = dockerManager.runContainer(container, containerName, volumes, binds, null, envs); containers.put(containerId, containerName); } catch (Exception e) { this.cleanRecordingMaps(recording); @@ -277,7 +277,7 @@ public class ComposedRecordingService extends RecordingService { // Gracefully stop ffmpeg process try { - dockerManager.runCommandInContainer(containerId, "echo 'q' > stop"); + dockerManager.runCommandInContainer(containerId, "echo 'q' > stop", 0); } catch (InterruptedException e1) { e1.printStackTrace(); } diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java index 2f30223a..d0f72205 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java @@ -637,7 +637,7 @@ public class RpcHandler extends DefaultJsonRpcHandler { @Override public void handleTransportError(Session rpcSession, Throwable exception) throws Exception { log.error("Transport exception for WebSocket session: {} - Exception: {}", rpcSession.getSessionId(), - exception); + exception.getMessage()); if ("IOException".equals(exception.getClass().getSimpleName()) && "Broken pipe".equals(exception.getCause().getMessage())) { log.warn("Parcipant with private id {} unexpectedly closed the websocket", rpcSession.getSessionId()); diff --git a/openvidu-server/src/main/java/io/openvidu/server/utils/CustomFileManager.java b/openvidu-server/src/main/java/io/openvidu/server/utils/CustomFileManager.java index 3fd12a0c..72a0f9e2 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/utils/CustomFileManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/utils/CustomFileManager.java @@ -46,6 +46,26 @@ public class CustomFileManager { } } + public void moveFile(String filePath, String newFilePath, boolean deleteFoldersWhileEmpty) { + try { + FileUtils.moveFile(FileUtils.getFile(filePath), FileUtils.getFile(newFilePath)); + } catch (IOException e) { + log.error("Error moving file '{}' to new path '{}': {}", filePath, newFilePath, e.getMessage()); + } + if (deleteFoldersWhileEmpty) { + boolean keepDeleting = true; + File folder = new File(filePath).getParentFile(); + while (keepDeleting) { + if (folder.exists() && folder.isDirectory() && folder.listFiles().length == 0) { + folder.delete(); + folder = folder.getParentFile(); + } else { + keepDeleting = false; + } + } + } + } + public boolean createFolderIfNotExists(String path) { File folder = new File(path); if (!folder.exists()) { @@ -58,7 +78,7 @@ public class CustomFileManager { public void deleteFolder(String path) throws IOException { FileUtils.deleteDirectory(new File(path)); } - + public void deleteFile(String path) throws IOException { new File(path).delete(); } diff --git a/openvidu-server/src/main/java/io/openvidu/server/utils/DockerManager.java b/openvidu-server/src/main/java/io/openvidu/server/utils/DockerManager.java index 11eee36b..c214aa70 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/utils/DockerManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/utils/DockerManager.java @@ -17,6 +17,8 @@ package io.openvidu.server.utils; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -36,7 +38,11 @@ import com.github.dockerjava.api.exception.InternalServerErrorException; import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.model.Bind; import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.Frame; import com.github.dockerjava.api.model.HostConfig; +import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.core.DefaultDockerClientConfig; import com.github.dockerjava.core.DockerClientBuilder; @@ -116,10 +122,30 @@ public class DockerManager { } public String runContainer(String container, String containerName, List volumes, List binds, - List envs) throws Exception { - HostConfig hostConfig = new HostConfig().withNetworkMode("host").withBinds(binds); - CreateContainerCmd cmd = dockerClient.createContainerCmd(container).withName(containerName).withEnv(envs) - .withHostConfig(hostConfig).withVolumes(volumes); + List exposedPorts, List envs) throws Exception { + + CreateContainerCmd cmd = dockerClient.createContainerCmd(container).withName(containerName).withEnv(envs); + HostConfig hostConfig = new HostConfig().withNetworkMode("host"); + if (volumes != null) { + cmd.withVolumes(volumes); + } + if (binds != null) { + hostConfig.withBinds(binds); + } + if (exposedPorts != null) { + Ports ps = new Ports(); + List expPorts = new ArrayList<>(); + exposedPorts.forEach(p -> { + ExposedPort port = ExposedPort.tcp(p); + expPorts.add(port); + ps.bind(port, Binding.bindPort(p)); + }); + hostConfig.withPortBindings(ps); + cmd.withExposedPorts(expPorts); + } + + cmd.withHostConfig(hostConfig); + CreateContainerResponse response = null; try { response = cmd.exec(); @@ -155,10 +181,21 @@ public class DockerManager { } } - public void runCommandInContainer(String containerId, String command) throws InterruptedException { + public String runCommandInContainer(String containerId, String command, int secondsOfWait) + throws InterruptedException { ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(containerId).withAttachStdout(true) .withAttachStderr(true).withCmd("bash", "-c", command).exec(); - dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(new ExecStartResultCallback()).awaitCompletion(); + CountDownLatch latch = new CountDownLatch(1); + final String[] stringResponse = new String[1]; + dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(new ExecStartResultCallback() { + @Override + public void onNext(Frame item) { + stringResponse[0] = new String(item.getPayload()); + latch.countDown(); + } + }); + latch.await(secondsOfWait, TimeUnit.SECONDS); + return stringResponse[0]; } public void waitForContainerStopped(String containerId, int secondsOfWait) throws Exception { @@ -176,4 +213,14 @@ public class DockerManager { } } + static public String getDokerGatewayIp() { + try { + return CommandExecutor.execCommand("/bin/sh", "-c", + "docker network inspect bridge --format='{{(index .IPAM.Config 0).Gateway}}'"); + } catch (IOException | InterruptedException e) { + log.error(e.getMessage()); + return null; + } + } + }