Skip to content

Commit

Permalink
Introduce builder Docker compose service
Browse files Browse the repository at this point in the history
  • Loading branch information
onobc committed Sep 8, 2023
1 parent c7f9b5c commit 8387b2d
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@

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;

Expand All @@ -38,12 +42,21 @@ public class DockerService implements Consumer<Builder> {

private final int[] ports;

DockerService(String image, String imageTag, String website, String command, int... ports) {
this.image = image;
this.imageTag = imageTag;
this.website = website;
this.command = command;
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 @@ -88,12 +101,72 @@ public int[] getPorts() {
}

@Override
public void accept(Builder builder) {
public void accept(ComposeService.Builder builder) {
builder.image(this.image)
.imageTag(this.imageTag)
.imageWebsite(this.website)
.ports(this.ports)
.command(this.command);
.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,61 +49,83 @@ public SimpleDockerServiceResolver() {
}

private static DockerService activeMQ() {
return new DockerService("symptoma/activemq", "latest", "https://hub.docker.com/r/symptoma/activemq", null,
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", null, 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", null, 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",
null, 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", null, 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", null, 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", null, 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", null, 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", null, 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", null, 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", null, 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/", null, 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/", null,
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 8387b2d

Please sign in to comment.