Skip to content

Commit

Permalink
Add optional 'command' to Docker compose service
Browse files Browse the repository at this point in the history
  • Loading branch information
onobc authored and snicoll committed Sep 15, 2023
1 parent e1d85b7 commit 85a17e7
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,47 @@

package io.spring.start.site.container;

import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Consumer;

import io.spring.initializr.generator.container.docker.compose.ComposeService.Builder;
import io.spring.initializr.generator.container.docker.compose.ComposeService;

/**
* Description of a Docker service.
*
* @author Stephane Nicoll
* @author Chris Bono
*/
public class DockerService implements Consumer<Builder> {
public final class DockerService implements Consumer<ComposeService.Builder> {

private final String image;

private final String imageTag;

private final String website;

private final String command;

private final int[] ports;

DockerService(String image, String imageTag, String website, int... ports) {
this.image = image;
this.imageTag = imageTag;
this.website = website;
this.ports = ports;
private DockerService(DockerService.Builder builder) {
this.image = builder.image;
this.imageTag = builder.imageTag;
this.website = builder.website;
this.command = builder.command;
this.ports = builder.ports.stream().mapToInt(Number::intValue).toArray();
}

/**
* Return a new builder using the specified image and optional tag.
* @param imageAndTag the image (and optional tag) to use for the service
* @return the new builder instance.
*/
public static DockerService.Builder withImageAndTag(String imageAndTag) {
return new DockerService.Builder(imageAndTag);
}

/**
Expand Down Expand Up @@ -67,6 +84,14 @@ public String getWebsite() {
return this.website;
}

/**
* Return the command to use to override the default command (optional).
* @return the command
*/
public String getCommand() {
return this.command;
}

/**
* Return the ports that should be exposed by the service.
* @return the ports to expose
Expand All @@ -76,8 +101,72 @@ public int[] getPorts() {
}

@Override
public void accept(Builder builder) {
builder.image(this.image).imageTag(this.imageTag).imageWebsite(this.website).ports(this.ports);
public void accept(ComposeService.Builder builder) {
builder.image(this.image)
.imageTag(this.imageTag)
.imageWebsite(this.website)
.command(this.command)
.ports(this.ports);
}

/**
* Builder for {@link DockerService}.
*/
public static class Builder {

private String image;

private String imageTag = "latest";

private String website;

private String command;

private final Set<Integer> ports = new TreeSet<>();

protected Builder(String imageAndTag) {
String[] split = imageAndTag.split(":", 2);
String tag = (split.length == 1) ? "latest" : split[1];
image(split[0]).imageTag(tag);
}

public DockerService.Builder image(String image) {
this.image = image;
return this;
}

public DockerService.Builder imageTag(String imageTag) {
this.imageTag = imageTag;
return this;
}

public DockerService.Builder website(String website) {
this.website = website;
return this;
}

public DockerService.Builder command(String command) {
this.command = command;
return this;
}

public DockerService.Builder ports(Collection<Integer> ports) {
this.ports.addAll(ports);
return this;
}

public DockerService.Builder ports(int... ports) {
return ports(Arrays.stream(ports).boxed().toList());
}

/**
* Builds the {@link DockerService} instance.
* @return the built instance
*/
public DockerService build() {
return new DockerService(this);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*
* @author Stephane Nicoll
* @author Moritz Halbritter
* @author Chris Bono
*/
public class SimpleDockerServiceResolver implements DockerServiceResolver {

Expand All @@ -48,59 +49,83 @@ public SimpleDockerServiceResolver() {
}

private static DockerService activeMQ() {
return new DockerService("symptoma/activemq", "latest", "https://hub.docker.com/r/symptoma/activemq", 61616);
return DockerService.withImageAndTag("symptoma/activemq")
.website("https://hub.docker.com/r/symptoma/activemq")
.ports(61616)
.build();
}

private static DockerService cassandra() {
return new DockerService("cassandra", "latest", "https://hub.docker.com/_/cassandra", 9042);
return DockerService.withImageAndTag("cassandra")
.website("https://hub.docker.com/_/cassandra")
.ports(9042)
.build();
}

private static DockerService elasticsearch() {
// They don't provide a 'latest' tag
return new DockerService("docker.elastic.co/elasticsearch/elasticsearch", "7.17.10",
"https://www.docker.elastic.co/r/elasticsearch", 9200, 9300);
return DockerService.withImageAndTag("docker.elastic.co/elasticsearch/elasticsearch:7.17.10")
.website("https://www.docker.elastic.co/r/elasticsearch")
.ports(9200, 9300)
.build();
}

private static DockerService kafka() {
return new DockerService("confluentinc/cp-kafka", "latest", "https://hub.docker.com/r/confluentinc/cp-kafka",
9092);
return DockerService.withImageAndTag("confluentinc/cp-kafka")
.website("https://hub.docker.com/r/confluentinc/cp-kafka")
.ports(9092)
.build();
}

private static DockerService mariaDb() {
return new DockerService("mariadb", "latest", "https://hub.docker.com/_/mariadb", 3306);
return DockerService.withImageAndTag("mariadb").website("https://hub.docker.com/_/mariadb").ports(3306).build();
}

private static DockerService mongoDb() {
return new DockerService("mongo", "latest", "https://hub.docker.com/_/mongo", 27017);
return DockerService.withImageAndTag("mongo").website("https://hub.docker.com/_/mongo").ports(27017).build();
}

private static DockerService mysql() {
return new DockerService("mysql", "latest", "https://hub.docker.com/_/mysql", 3306);
return DockerService.withImageAndTag("mysql").website("https://hub.docker.com/_/mysql").ports(3306).build();
}

private static DockerService oracle() {
return new DockerService("gvenzl/oracle-xe", "latest", "https://hub.docker.com/r/gvenzl/oracle-xe", 1521);
return DockerService.withImageAndTag("gvenzl/oracle-xe")
.website("https://hub.docker.com/r/gvenzl/oracle-xe")
.ports(1521)
.build();
}

private static DockerService postgres() {
return new DockerService("postgres", "latest", "https://hub.docker.com/_/postgres", 5432);
return DockerService.withImageAndTag("postgres")
.website("https://hub.docker.com/_/postgres")
.ports(5432)
.build();
}

private static DockerService rabbit() {
return new DockerService("rabbitmq", "latest", "https://hub.docker.com/_/rabbitmq", 5672);
return DockerService.withImageAndTag("rabbitmq")
.website("https://hub.docker.com/_/rabbitmq")
.ports(5672)
.build();
}

private static DockerService redis() {
return new DockerService("redis", "latest", "https://hub.docker.com/_/redis", 6379);
return DockerService.withImageAndTag("redis").website("https://hub.docker.com/_/redis").ports(6379).build();
}

private static DockerService sqlServer() {
return new DockerService("mcr.microsoft.com/mssql/server", "latest",
"https://mcr.microsoft.com/en-us/product/mssql/server/about/", 1433);
return DockerService.withImageAndTag("mcr.microsoft.com/mssql/server")
.website("https://mcr.microsoft.com/en-us/product/mssql/server/about/")
.ports(1433)
.build();
}

private static DockerService zipkin() {
return new DockerService("openzipkin/zipkin", "latest", "https://hub.docker.com/r/openzipkin/zipkin/", 9411);
return DockerService.withImageAndTag("openzipkin/zipkin")
.website("https://hub.docker.com/r/openzipkin/zipkin/")
.ports(9411)
.build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.spring.start.site.container;

import java.util.List;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for {@link DockerService}.
*
* @author Chris Bono
*/
class DockerServiceTests {

@Test
void builderWithMinimalOptions() {
DockerService service = DockerService.withImageAndTag("acme/toolbox").build();
assertThat(service.getImage()).isEqualTo("acme/toolbox");
assertThat(service.getImageTag()).isEqualTo("latest");
assertThat(service.getWebsite()).isNull();
assertThat(service.getCommand()).isNull();
assertThat(service.getPorts()).isEmpty();
}

@Test
void builderWithAllOptions() {
DockerService service = DockerService.withImageAndTag("acme/toolbox")
.imageTag("1.0")
.website("acme/toolbox-dot-com")
.command("bin/acme run")
.ports(8007, 8008)
.build();
assertThat(service.getImage()).isEqualTo("acme/toolbox");
assertThat(service.getImageTag()).isEqualTo("1.0");
assertThat(service.getWebsite()).isEqualTo("acme/toolbox-dot-com");
assertThat(service.getCommand()).isEqualTo("bin/acme run");
assertThat(service.getPorts()).containsExactly(8007, 8008);
}

@Test
void builderWithImageAndTagUsesTag() {
DockerService service = DockerService.withImageAndTag("acme/toolbox:1.0").build();
assertThat(service.getImage()).isEqualTo("acme/toolbox");
assertThat(service.getImageTag()).isEqualTo("1.0");
}

@Test
void builderWithImageAndTagIsOverriddenByImageTag() {
DockerService service = DockerService.withImageAndTag("acme/toolbox:1.0").imageTag("2.0").build();
assertThat(service.getImage()).isEqualTo("acme/toolbox");
assertThat(service.getImageTag()).isEqualTo("2.0");
}

@Test
void builderWithCollectionOfPorts() {
DockerService service = DockerService.withImageAndTag("acme/toolbox").ports(List.of(8007, 8008)).build();
assertThat(service.getPorts()).containsExactly(8007, 8008);
}

}

0 comments on commit 85a17e7

Please sign in to comment.