diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 3ceabf3e7..978bd35ca 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -56,6 +56,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.Identifier; @@ -185,6 +186,15 @@ public interface DockerClient extends Closeable { */ UpdateContainerCmd updateContainerCmd(@Nonnull String containerId); + /** + * Rename container. + * + * @param containerId id of the container + * @return command + * @since {@link RemoteApiVersion#VERSION_1_17} + */ + RenameContainerCmd renameContainerCmd(@Nonnull String containerId); + RestartContainerCmd restartContainerCmd(@Nonnull String containerId); CommitCmd commitCmd(@Nonnull String containerId); diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index 8cc42cf15..ae090e434 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -6,6 +6,7 @@ import javax.net.ssl.SSLContext; import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.RemoteApiVersion; public interface DockerCmdExecFactory extends Closeable { @@ -71,6 +72,13 @@ public interface DockerCmdExecFactory extends Closeable { UpdateContainerCmd.Exec createUpdateContainerCmdExec(); + /** + * Rename container. + * + * @since {@link RemoteApiVersion#VERSION_1_17} + */ + RenameContainerCmd.Exec createRenameContainerCmdExec(); + RestartContainerCmd.Exec createRestartContainerCmdExec(); CommitCmd.Exec createCommitCmdExec(); diff --git a/src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java new file mode 100644 index 000000000..bce20251f --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java @@ -0,0 +1,34 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.core.RemoteApiVersion; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * Rename a container. + * + * @since {@link RemoteApiVersion#VERSION_1_17} + */ +public interface RenameContainerCmd extends SyncDockerCmd { + + @CheckForNull + String getContainerId(); + + RenameContainerCmd withContainerId(@Nonnull String containerId); + + @CheckForNull + String getName(); + + RenameContainerCmd withName(@Nonnull String name); + + /** + * @throws NotFoundException No such container + */ + @Override + Void exec() throws NotFoundException; + + interface Exec extends DockerCmdSyncExec { + } +} diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 9d342e249..9f4f0f88b 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -58,6 +58,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.Identifier; import com.github.dockerjava.core.command.AttachContainerCmdImpl; @@ -109,6 +110,7 @@ import com.github.dockerjava.core.command.UpdateContainerCmdImpl; import com.github.dockerjava.core.command.VersionCmdImpl; import com.github.dockerjava.core.command.WaitContainerCmdImpl; +import com.github.dockerjava.core.command.RenameContainerCmdImpl; import javax.annotation.Nonnull; @@ -364,6 +366,11 @@ public UpdateContainerCmd updateContainerCmd(@Nonnull String containerId) { return new UpdateContainerCmdImpl(getDockerCmdExecFactory().createUpdateContainerCmdExec(), containerId); } + @Override + public RenameContainerCmd renameContainerCmd(@Nonnull String containerId) { + return new RenameContainerCmdImpl(getDockerCmdExecFactory().createRenameContainerCmdExec(), containerId); + } + @Override public RestartContainerCmd restartContainerCmd(String containerId) { return new RestartContainerCmdImpl(getDockerCmdExecFactory().createRestartContainerCmdExec(), containerId); diff --git a/src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java new file mode 100644 index 000000000..ebf3ebabf --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java @@ -0,0 +1,52 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.api.exception.NotFoundException; + +import javax.annotation.Nonnull; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class RenameContainerCmdImpl extends AbstrDockerCmd implements RenameContainerCmd { + + private String containerId; + + private String name; + + public RenameContainerCmdImpl(RenameContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public String getName() { + return name; + } + + @Override + public RenameContainerCmd withContainerId(@Nonnull String containerId) { + checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public RenameContainerCmd withName(@Nonnull String name) { + checkNotNull(name, "name was not specified"); + this.name = name; + return this; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index 4716877af..f64cf4e2b 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -80,6 +80,7 @@ import com.github.dockerjava.api.command.UnpauseContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.LocalDirectorySSLConfig; @@ -417,6 +418,11 @@ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec() { + return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java new file mode 100644 index 000000000..c747ea9b0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.core.DockerClientConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RenameContainerCmdExec extends AbstrSyncDockerCmdExec + implements RenameContainerCmd.Exec { + private static final Logger LOG = LoggerFactory.getLogger(RenameContainerCmdExec.class); + + public RenameContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(RenameContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/rename") + .resolveTemplate("id", command.getContainerId()) + .queryParam("name", command.getName()); + + LOG.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(null); + + return null; + } +} diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index 1210c56bc..08a0179a1 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -50,6 +50,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.DockerClientImpl; import com.github.dockerjava.core.LocalDirectorySSLConfig; @@ -102,6 +103,7 @@ import com.github.dockerjava.netty.exec.UpdateContainerCmdExec; import com.github.dockerjava.netty.exec.VersionCmdExec; import com.github.dockerjava.netty.exec.WaitContainerCmdExec; +import com.github.dockerjava.netty.exec.RenameContainerCmdExec; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelInitializer; @@ -465,6 +467,11 @@ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec() { + return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java new file mode 100644 index 000000000..43f97e961 --- /dev/null +++ b/src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.netty.MediaType; +import com.github.dockerjava.netty.WebTarget; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RenameContainerCmdExec extends AbstrSyncDockerCmdExec + implements RenameContainerCmd.Exec { + private static final Logger LOG = LoggerFactory.getLogger(RenameContainerCmdExec.class); + + public RenameContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(RenameContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/rename") + .resolveTemplate("id", command.getContainerId()) + .queryParam("name", command.getName()); + + LOG.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(null); + + return null; + } +} diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index b2b86601c..ba05ab4e3 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -240,6 +240,11 @@ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return delegate.createUpdateContainerCmdExec(); } + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec(){ + return delegate.createRenameContainerCmdExec(); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return delegate.createRestartContainerCmdExec(); diff --git a/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java new file mode 100644 index 000000000..9f503a87b --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java @@ -0,0 +1,71 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.client.AbstractDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.*; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +@Test(groups = "integration") +public class RenameContainerCmdImplTest extends AbstractDockerClientTest { + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void renameContainer() throws DockerException { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + String name1 = inspectContainerResponse.getName(); + + dockerClient.renameContainerCmd(container.getId()) + .withName(getClass().getCanonicalName() + "renameContainer") + .exec(); + + InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect After Rename: {}", inspectContainerResponse2.toString()); + + String name2 = inspectContainerResponse2.getName(); + + assertNotEquals(name1, name2); + + dockerClient.killContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = NotFoundException.class) + public void renameExistingContainer() throws DockerException, InterruptedException { + dockerClient.renameContainerCmd("non-existing") + .withName(getClass().getCanonicalName() + "renameExistingContainer") + .exec(); + } +} diff --git a/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java new file mode 100644 index 000000000..c176bc1d6 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java @@ -0,0 +1,71 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.*; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +@Test(groups = "integration") +public class RenameContainerCmdExecTest extends AbstractNettyDockerClientTest { + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void renameContainer() throws DockerException { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + String name1 = inspectContainerResponse.getName(); + + dockerClient.renameContainerCmd(container.getId()) + .withName(getClass().getCanonicalName() + "renameContainer") + .exec(); + + InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect After Rename: {}", inspectContainerResponse2.toString()); + + String name2 = inspectContainerResponse2.getName(); + + assertNotEquals(name1, name2); + + dockerClient.killContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = NotFoundException.class) + public void renameNonExistingContainer() throws DockerException, InterruptedException { + dockerClient.renameContainerCmd("non-existing") + .withName(getClass().getCanonicalName() + "renameExistingContainer") + .exec(); + } +}