From 23777bea80d8eafd819d3a062c9be7cf02c49f3a Mon Sep 17 00:00:00 2001 From: Tad Cordle Date: Tue, 10 Jul 2018 19:08:52 -0400 Subject: [PATCH] Use Port class instead of strings (#511) --- .../builder/BuildStepsIntegrationTest.java | 10 +-- .../tools/jib/builder/BuildConfiguration.java | 11 +-- .../cloud/tools/jib/configuration/Port.java | 78 +++++++++++++++++ .../jib/configuration/PortsWithProtocol.java | 87 ------------------- .../jib/frontend/ExposedPortsParser.java | 41 ++++----- .../google/cloud/tools/jib/image/Image.java | 14 +-- .../json/ContainerConfigurationTemplate.java | 32 +++++-- .../jib/builder/BuildConfigurationTest.java | 5 +- .../jib/frontend/ExposedPortsParserTest.java | 57 ++++++------ .../cloud/tools/jib/image/ImageTest.java | 9 +- .../ContainerConfigurationTemplateTest.java | 10 ++- .../image/json/ImageToJsonTranslatorTest.java | 8 +- .../image/json/JsonToImageTranslatorTest.java | 9 +- .../test/resources/json/containerconfig.json | 2 +- .../json/translated_ocimanifest.json | 2 +- .../json/translated_v22manifest.json | 2 +- .../tools/jib/gradle/BuildDockerTask.java | 3 +- .../tools/jib/gradle/BuildImageTask.java | 3 +- .../tools/jib/gradle/DockerContextTask.java | 2 +- .../tools/jib/maven/BuildDockerMojo.java | 2 +- .../cloud/tools/jib/maven/BuildImageMojo.java | 2 +- .../tools/jib/maven/DockerContextMojo.java | 2 +- 22 files changed, 210 insertions(+), 181 deletions(-) create mode 100644 jib-core/src/main/java/com/google/cloud/tools/jib/configuration/Port.java delete mode 100644 jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortsWithProtocol.java diff --git a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java index 979e7fa32c..c8f0d1ae00 100644 --- a/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java +++ b/jib-core/src/integration-test/java/com/google/cloud/tools/jib/builder/BuildStepsIntegrationTest.java @@ -58,8 +58,7 @@ public void testSteps_forBuildToDockerRegistry() .setMainClass("HelloWorld") .setJavaArguments(Collections.singletonList("An argument.")) .setExposedPorts( - ExposedPortsParser.parse( - Arrays.asList("1000", "2000-2002/tcp", "3000/udp"), logger)) + ExposedPortsParser.parse(Arrays.asList("1000", "2000-2002/tcp", "3000/udp"))) .setAllowHttp(true) .build(); @@ -83,7 +82,7 @@ public void testSteps_forBuildToDockerRegistry() new Command("docker", "inspect", imageReference).run(), CoreMatchers.containsString( " \"ExposedPorts\": {\n" - + " \"1000\": {},\n" + + " \"1000/tcp\": {},\n" + " \"2000/tcp\": {},\n" + " \"2001/tcp\": {},\n" + " \"2002/tcp\": {},\n" @@ -104,8 +103,7 @@ public void testSteps_forBuildToDockerDaemon() .setMainClass("HelloWorld") .setJavaArguments(Collections.singletonList("An argument.")) .setExposedPorts( - ExposedPortsParser.parse( - Arrays.asList("1000", "2000-2002/tcp", "3000/udp"), logger)) + ExposedPortsParser.parse(Arrays.asList("1000", "2000-2002/tcp", "3000/udp"))) .build(); Path cacheDirectory = temporaryCacheDirectory.newFolder().toPath(); @@ -120,7 +118,7 @@ public void testSteps_forBuildToDockerDaemon() new Command("docker", "inspect", "testdocker").run(), CoreMatchers.containsString( " \"ExposedPorts\": {\n" - + " \"1000\": {},\n" + + " \"1000/tcp\": {},\n" + " \"2000/tcp\": {},\n" + " \"2001/tcp\": {},\n" + " \"2002/tcp\": {},\n" diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java index 42c2768d01..4b63826137 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/BuildConfiguration.java @@ -18,6 +18,7 @@ import com.google.cloud.tools.jib.configuration.CacheConfiguration; import com.google.cloud.tools.jib.configuration.LayerConfiguration; +import com.google.cloud.tools.jib.configuration.Port; import com.google.cloud.tools.jib.image.ImageReference; import com.google.cloud.tools.jib.image.json.BuildableManifestTemplate; import com.google.cloud.tools.jib.image.json.V22ManifestTemplate; @@ -48,7 +49,7 @@ public static class Builder { private ImmutableList javaArguments = ImmutableList.of(); private ImmutableList jvmFlags = ImmutableList.of(); private ImmutableMap environmentMap = ImmutableMap.of(); - private ImmutableList exposedPorts = ImmutableList.of(); + private ImmutableList exposedPorts = ImmutableList.of(); private Class targetFormat = V22ManifestTemplate.class; @Nullable private CacheConfiguration applicationLayersCacheConfiguration; @Nullable private CacheConfiguration baseImageLayersCacheConfiguration; @@ -123,7 +124,7 @@ public Builder setEnvironment(@Nullable Map environmentMap) { return this; } - public Builder setExposedPorts(@Nullable List exposedPorts) { + public Builder setExposedPorts(@Nullable List exposedPorts) { if (exposedPorts != null) { Preconditions.checkArgument(!exposedPorts.contains(null)); this.exposedPorts = ImmutableList.copyOf(exposedPorts); @@ -279,7 +280,7 @@ public static Builder builder(BuildLogger buildLogger) { private final ImmutableList javaArguments; private final ImmutableList jvmFlags; private final ImmutableMap environmentMap; - private final ImmutableList exposedPorts; + private final ImmutableList exposedPorts; private final Class targetFormat; @Nullable private final CacheConfiguration applicationLayersCacheConfiguration; @Nullable private final CacheConfiguration baseImageLayersCacheConfiguration; @@ -299,7 +300,7 @@ private BuildConfiguration( ImmutableList javaArguments, ImmutableList jvmFlags, ImmutableMap environmentMap, - ImmutableList exposedPorts, + ImmutableList exposedPorts, Class targetFormat, @Nullable CacheConfiguration applicationLayersCacheConfiguration, @Nullable CacheConfiguration baseImageLayersCacheConfiguration, @@ -396,7 +397,7 @@ public ImmutableMap getEnvironment() { return environmentMap; } - public ImmutableList getExposedPorts() { + public ImmutableList getExposedPorts() { return exposedPorts; } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/Port.java b/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/Port.java new file mode 100644 index 0000000000..b479375354 --- /dev/null +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/Port.java @@ -0,0 +1,78 @@ +/* + * Copyright 2018 Google LLC. All rights reserved. + * + * 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 + * + * http://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 com.google.cloud.tools.jib.configuration; + +import java.util.Objects; + +/** Holds port number and protocol for an exposed port. */ +public class Port { + + /** Represents the protocol portion of the port. */ + public enum Protocol { + TCP("tcp"), + UDP("udp"); + + private final String stringRepresentation; + + Protocol(String stringRepresentation) { + this.stringRepresentation = stringRepresentation; + } + + @Override + public String toString() { + return stringRepresentation; + } + } + + private final int port; + private final Protocol protocol; + + public Port(int port, Protocol protocol) { + this.port = port; + this.protocol = protocol; + } + + public int getPort() { + return port; + } + + public Protocol getProtocol() { + return protocol; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (other == null || !(other instanceof Port)) { + return false; + } + Port otherPort = (Port) other; + return port == otherPort.port && protocol == otherPort.protocol; + } + + @Override + public int hashCode() { + return Objects.hash(port, protocol); + } + + @Override + public String toString() { + return port + "/" + protocol; + } +} diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortsWithProtocol.java b/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortsWithProtocol.java deleted file mode 100644 index 9fdf5b4583..0000000000 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/configuration/PortsWithProtocol.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2018 Google LLC. All rights reserved. - * - * 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 - * - * http://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 com.google.cloud.tools.jib.configuration; - -import com.google.common.base.Preconditions; - -/** Holds port number and protocol for an exposed port. */ -public class PortsWithProtocol { - - /** Represents the protocol portion of the port. */ - public enum Protocol { - TCP("tcp"), - UDP("udp"); - - private final String stringRepresentation; - - Protocol(String stringRepresentation) { - this.stringRepresentation = stringRepresentation; - } - - @Override - public String toString() { - return stringRepresentation; - } - } - - /** - * Creates a new {@link PortsWithProtocol} with the specified range and protocol. - * - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @param protocol the protocol - * @return the {@link PortsWithProtocol} - */ - public static PortsWithProtocol forRange(int minPort, int maxPort, Protocol protocol) { - Preconditions.checkArgument( - minPort <= maxPort, "minPort must be less than or equal to maxPort in port range"); - return new PortsWithProtocol(minPort, maxPort, protocol); - } - - /** - * Creates a new {@link PortsWithProtocol} with the port number and protocol. - * - * @param port the port number - * @param protocol the protocol - * @return the {@link PortsWithProtocol} - */ - public static PortsWithProtocol forSingle(int port, Protocol protocol) { - return new PortsWithProtocol(port, port, protocol); - } - - private final int minPort; - private final int maxPort; - private final Protocol protocol; - - public int getMinPort() { - return minPort; - } - - public int getMaxPort() { - return maxPort; - } - - public Protocol getProtocol() { - return protocol; - } - - private PortsWithProtocol(int minPort, int maxPort, Protocol protocol) { - this.minPort = minPort; - this.maxPort = maxPort; - this.protocol = protocol; - } -} diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java b/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java index d81445d048..a2bf282103 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/frontend/ExposedPortsParser.java @@ -16,41 +16,37 @@ package com.google.cloud.tools.jib.frontend; -import com.google.cloud.tools.jib.builder.BuildLogger; -import com.google.cloud.tools.jib.configuration.PortsWithProtocol; -import com.google.common.annotations.VisibleForTesting; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** Utility for parsing exposed ports from plugin configuration */ public class ExposedPortsParser { /** * Pattern used for parsing information out of exposed port configurations. * - *

Examples: 100, 200-210, 1000/tcp, 2000/udp, 500-600/tcp + *

Example matches: 100, 200-210, 1000/tcp, 2000/udp, 500-600/tcp */ - private static final Pattern portPattern = Pattern.compile("(\\d+)(?:-(\\d+))?(/tcp|/udp)?"); + private static final Pattern portPattern = Pattern.compile("(\\d+)(?:-(\\d+))?(?:/(tcp|udp))?"); /** - * TODO: Return list of {@link PortsWithProtocol}s instead of strings + * Converts/validates a list of strings representing port ranges to an expanded list of {@link + * Port}s. * - *

Converts/validates a list of ports with ranges to an expanded form without ranges. - * - *

Example: {@code ["1000/tcp", "2000-2002/tcp"] -> ["1000/tcp", "2000/tcp", "2001/tcp", - * "2002/tcp"]} + *

For example: ["1000", "2000-2002"] will expand to a list of {@link Port}s with the port + * numbers [1000, 2000, 2001, 2002] * * @param ports the list of port numbers/ranges - * @param buildLogger used to log warning messages - * @return the ports as a list of integers + * @return the ports as a list of {@link Port} * @throws NumberFormatException if any of the ports are in an invalid format or out of range */ - @VisibleForTesting - public static ImmutableList parse(List ports, BuildLogger buildLogger) - throws NumberFormatException { - ImmutableList.Builder result = new ImmutableList.Builder<>(); + public static ImmutableList parse(List ports) throws NumberFormatException { + ImmutableList.Builder result = new ImmutableList.Builder<>(); for (String port : ports) { Matcher matcher = portPattern.matcher(port); @@ -70,7 +66,8 @@ public static ImmutableList parse(List ports, BuildLogger buildL if (!Strings.isNullOrEmpty(matcher.group(2))) { max = Integer.parseInt(matcher.group(2)); } - String protocol = matcher.group(3); + Protocol protocol = + Protocol.UDP.toString().equals(matcher.group(3)) ? Protocol.UDP : Protocol.TCP; // Error if configured as 'max-min' instead of 'min-max' if (min > max) { @@ -80,14 +77,12 @@ public static ImmutableList parse(List ports, BuildLogger buildL // Warn for possibly invalid port numbers if (min < 1 || max > 65535) { - // TODO: Add details/use HelpfulSuggestions for these warnings - buildLogger.warn("Port number '" + port + "' is out of usual range (1-65535)."); + throw new NumberFormatException( + "Port number '" + port + "' is out of usual range (1-65535)."); } - // Add all numbers in range to list - String portString = (protocol == null ? "" : protocol); - for (int portNum = min; portNum <= max; portNum++) { - result.add(portNum + portString); + for (int portNumber = min; portNumber <= max; portNumber++) { + result.add(new Port(portNumber, protocol)); } } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/image/Image.java b/jib-core/src/main/java/com/google/cloud/tools/jib/image/Image.java index 94ac660bec..b2735dd523 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/image/Image.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/image/Image.java @@ -16,6 +16,7 @@ package com.google.cloud.tools.jib.image; +import com.google.cloud.tools.jib.configuration.Port; import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Map; @@ -31,7 +32,7 @@ public static class Builder { private ImmutableList entrypoint = ImmutableList.of(); private ImmutableList javaArguments = ImmutableList.of(); - private ImmutableList exposedPorts = ImmutableList.of(); + private ImmutableList exposedPorts = ImmutableList.of(); /** * Sets the environment with a map from environment variable names to values. @@ -94,11 +95,10 @@ public Builder setJavaArguments(List javaArguments) { /** * Sets the items in the "ExposedPorts" field in the container configuration. * - * @param exposedPorts the map of exposed ports to add, with the key in the format it would - * appear in the configuration json (e.g. "portNum/tcp") + * @param exposedPorts the list of exposed ports to add * @return this */ - public Builder setExposedPorts(ImmutableList exposedPorts) { + public Builder setExposedPorts(ImmutableList exposedPorts) { this.exposedPorts = exposedPorts; return this; } @@ -142,14 +142,14 @@ public static Builder builder() { private final ImmutableList javaArguments; /** Ports that the container listens on. */ - private final ImmutableList exposedPorts; + private final ImmutableList exposedPorts; private Image( ImageLayers layers, ImmutableList environment, ImmutableList entrypoint, ImmutableList javaArguments, - ImmutableList exposedPorts) { + ImmutableList exposedPorts) { this.layers = layers; this.environmentBuilder = environment; this.entrypoint = entrypoint; @@ -169,7 +169,7 @@ public ImmutableList getJavaArguments() { return javaArguments; } - public ImmutableList getExposedPorts() { + public ImmutableList getExposedPorts() { return exposedPorts; } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplate.java b/jib-core/src/main/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplate.java index 5ce03316e2..f646d12d6a 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplate.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplate.java @@ -17,6 +17,8 @@ package com.google.cloud.tools.jib.image.json; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.cloud.tools.jib.image.DescriptorDigest; import com.google.cloud.tools.jib.json.JsonTemplate; import com.google.common.annotations.VisibleForTesting; @@ -27,6 +29,8 @@ import java.util.List; import java.util.Map; import java.util.SortedMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.annotation.Nullable; /** @@ -61,6 +65,14 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class ContainerConfigurationTemplate implements JsonTemplate { + /** + * Pattern used for parsing information out of exposed port configurations. Only accepts single + * ports with protocol. + * + *

Example matches: 100, 1000/tcp, 2000/udp + */ + private static final Pattern portPattern = Pattern.compile("(\\d+)(?:/(tcp|udp))?"); + /** * A combined date and time at which the image was created. Constant to maintain reproducibility * and avoid Docker's weird "292 years old" bug. @@ -127,12 +139,12 @@ public void setContainerCmd(List cmd) { config.Cmd = cmd; } - public void setContainerExposedPorts(List exposedPorts) { + public void setContainerExposedPorts(List exposedPorts) { // TODO: Do this conversion somewhere else ImmutableSortedMap.Builder> result = new ImmutableSortedMap.Builder<>(String::compareTo); - for (String port : exposedPorts) { - result.put(port, Collections.emptyMap()); + for (Port port : exposedPorts) { + result.put(port.getPort() + "/" + port.getProtocol(), Collections.emptyMap()); } config.ExposedPorts = result.build(); } @@ -161,14 +173,22 @@ List getContainerCmd() { } @Nullable - ImmutableList getContainerExposedPorts() { + ImmutableList getContainerExposedPorts() { // TODO: Do this conversion somewhere else if (config.ExposedPorts == null) { return null; } - ImmutableList.Builder ports = new ImmutableList.Builder<>(); + ImmutableList.Builder ports = new ImmutableList.Builder<>(); for (Map.Entry> entry : config.ExposedPorts.entrySet()) { - ports.add(entry.getKey()); + String port = entry.getKey(); + Matcher matcher = portPattern.matcher(port); + if (!matcher.matches()) { + throw new NumberFormatException("Invalid port configuration: '" + port + "'."); + } + + int portNumber = Integer.parseInt(matcher.group(1)); + String protocol = matcher.group(2); + ports.add(new Port(portNumber, "udp".equals(protocol) ? Protocol.UDP : Protocol.TCP)); } return ports.build(); } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java index 1b270a4dfd..cd463a845a 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/BuildConfigurationTest.java @@ -18,6 +18,8 @@ import com.google.cloud.tools.jib.configuration.CacheConfiguration; import com.google.cloud.tools.jib.configuration.LayerConfiguration; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.cloud.tools.jib.image.ImageReference; import com.google.cloud.tools.jib.image.json.BuildableManifestTemplate; import com.google.cloud.tools.jib.image.json.OCIManifestTemplate; @@ -54,7 +56,8 @@ public void testBuilder() { List expectedJavaArguments = Arrays.asList("arg1", "arg2"); List expectedJvmFlags = Arrays.asList("some", "jvm", "flags"); Map expectedEnvironment = ImmutableMap.of("key", "value"); - ImmutableList expectedExposedPorts = ImmutableList.of("1000", "2000"); + ImmutableList expectedExposedPorts = + ImmutableList.of(new Port(1000, Protocol.TCP), new Port(2000, Protocol.TCP)); Class expectedTargetFormat = OCIManifestTemplate.class; CacheConfiguration expectedApplicationLayersCacheConfiguration = CacheConfiguration.forPath(Paths.get("application/layers")); diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java index e44e8c0d66..eb31b03b26 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/frontend/ExposedPortsParserTest.java @@ -17,6 +17,8 @@ package com.google.cloud.tools.jib.frontend; import com.google.cloud.tools.jib.builder.BuildLogger; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.common.collect.ImmutableList; import java.util.Arrays; import java.util.Collections; @@ -25,7 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; /** Tests for {@link ExposedPortsParser}. */ @@ -35,31 +36,31 @@ public class ExposedPortsParserTest { @Mock private BuildLogger mockLogger; @Test - public void testExpandPortList() { + public void testParse() { List goodInputs = - Arrays.asList("1000", "2000-2003", "3000-3000", "4000/tcp", "5000/udp", "6000-6002/tcp"); - ImmutableList expected = - new ImmutableList.Builder() + Arrays.asList("1000", "2000-2003", "3000-3000", "4000/tcp", "5000/udp", "6000-6002/udp"); + ImmutableList expected = + new ImmutableList.Builder() .add( - "1000", - "2000", - "2001", - "2002", - "2003", - "3000", - "4000/tcp", - "5000/udp", - "6000/tcp", - "6001/tcp", - "6002/tcp") + new Port(1000, Protocol.TCP), + new Port(2000, Protocol.TCP), + new Port(2001, Protocol.TCP), + new Port(2002, Protocol.TCP), + new Port(2003, Protocol.TCP), + new Port(3000, Protocol.TCP), + new Port(4000, Protocol.TCP), + new Port(5000, Protocol.UDP), + new Port(6000, Protocol.UDP), + new Port(6001, Protocol.UDP), + new Port(6002, Protocol.UDP)) .build(); - ImmutableList result = ExposedPortsParser.parse(goodInputs, mockLogger); + ImmutableList result = ExposedPortsParser.parse(goodInputs); Assert.assertEquals(expected, result); List badInputs = Arrays.asList("abc", "/udp", "1000/abc", "a100/tcp", "20/udpabc"); for (String input : badInputs) { try { - ExposedPortsParser.parse(Collections.singletonList(input), mockLogger); + ExposedPortsParser.parse(Collections.singletonList(input)); Assert.fail(); } catch (NumberFormatException ex) { Assert.assertEquals( @@ -73,20 +74,22 @@ public void testExpandPortList() { } try { - ExposedPortsParser.parse(Collections.singletonList("4002-4000"), mockLogger); + ExposedPortsParser.parse(Collections.singletonList("4002-4000")); Assert.fail(); } catch (NumberFormatException ex) { Assert.assertEquals( "Invalid port range '4002-4000'; smaller number must come first.", ex.getMessage()); } - ExposedPortsParser.parse(Collections.singletonList("0"), mockLogger); - Mockito.verify(mockLogger).warn("Port number '0' is out of usual range (1-65535)."); - ExposedPortsParser.parse(Collections.singletonList("70000"), mockLogger); - Mockito.verify(mockLogger).warn("Port number '70000' is out of usual range (1-65535)."); - ExposedPortsParser.parse(Collections.singletonList("0-400"), mockLogger); - Mockito.verify(mockLogger).warn("Port number '0-400' is out of usual range (1-65535)."); - ExposedPortsParser.parse(Collections.singletonList("1-70000"), mockLogger); - Mockito.verify(mockLogger).warn("Port number '1-70000' is out of usual range (1-65535)."); + badInputs = Arrays.asList("0", "70000", "0-400", "1-70000"); + for (String input : badInputs) { + try { + ExposedPortsParser.parse(Collections.singletonList(input)); + Assert.fail(); + } catch (NumberFormatException ex) { + Assert.assertEquals( + "Port number '" + input + "' is out of usual range (1-65535).", ex.getMessage()); + } + } } } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageTest.java index a3cb99c3d7..e97e69742a 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/image/ImageTest.java @@ -17,6 +17,8 @@ package com.google.cloud.tools.jib.image; import com.google.cloud.tools.jib.blob.BlobDescriptor; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.common.collect.ImmutableList; import java.util.Arrays; import org.junit.Assert; @@ -51,7 +53,8 @@ public void test_smokeTest() throws LayerPropertyNotFoundException { .setEnvironmentVariable("VARIABLE", "VALUE") .setEntrypoint(Arrays.asList("some", "command")) .setJavaArguments(Arrays.asList("arg1", "arg2")) - .setExposedPorts(ImmutableList.of("1000", "2000")) + .setExposedPorts( + ImmutableList.of(new Port(1000, Protocol.TCP), new Port(2000, Protocol.TCP))) .addLayer(mockLayer) .build(); @@ -60,6 +63,8 @@ public void test_smokeTest() throws LayerPropertyNotFoundException { Assert.assertEquals(expectedEnvironment, image.getEnvironment()); Assert.assertEquals(Arrays.asList("some", "command"), image.getEntrypoint()); Assert.assertEquals(Arrays.asList("arg1", "arg2"), image.getJavaArguments()); - Assert.assertEquals(ImmutableList.of("1000", "2000"), image.getExposedPorts()); + Assert.assertEquals( + ImmutableList.of(new Port(1000, Protocol.TCP), new Port(2000, Protocol.TCP)), + image.getExposedPorts()); } } diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplateTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplateTest.java index 40ce3ed1b5..2aa3d5d65e 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplateTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ContainerConfigurationTemplateTest.java @@ -16,6 +16,8 @@ package com.google.cloud.tools.jib.image.json; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.cloud.tools.jib.image.DescriptorDigest; import com.google.cloud.tools.jib.json.JsonTemplateMapper; import com.google.common.io.Resources; @@ -37,14 +39,14 @@ /** Tests for {@link ContainerConfigurationTemplate}. */ public class ContainerConfigurationTemplateTest { - private List exposedPorts; + private List exposedPorts; @Before public void setup() { exposedPorts = new ArrayList<>(); - exposedPorts.add("1000"); - exposedPorts.add("2000/tcp"); - exposedPorts.add("3000/udp"); + exposedPorts.add(new Port(1000, Protocol.TCP)); + exposedPorts.add(new Port(2000, Protocol.TCP)); + exposedPorts.add(new Port(3000, Protocol.UDP)); } @Test diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ImageToJsonTranslatorTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ImageToJsonTranslatorTest.java index fbabefc8bd..4bf9758de2 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ImageToJsonTranslatorTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/ImageToJsonTranslatorTest.java @@ -19,6 +19,8 @@ import com.google.cloud.tools.jib.blob.Blob; import com.google.cloud.tools.jib.blob.BlobDescriptor; import com.google.cloud.tools.jib.cache.CachedLayer; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.cloud.tools.jib.image.DescriptorDigest; import com.google.cloud.tools.jib.image.Image; import com.google.cloud.tools.jib.image.LayerPropertyNotFoundException; @@ -56,7 +58,11 @@ public void setUp() throws DigestException, LayerPropertyNotFoundException { testImageBuilder.setJavaArguments(Arrays.asList("arg1", "arg2")); - testImageBuilder.setExposedPorts(ImmutableList.of("1000", "2000/tcp", "3000/udp")); + testImageBuilder.setExposedPorts( + ImmutableList.of( + new Port(1000, Protocol.TCP), + new Port(2000, Protocol.TCP), + new Port(3000, Protocol.UDP))); DescriptorDigest fakeDigest = DescriptorDigest.fromDigest( diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/JsonToImageTranslatorTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/JsonToImageTranslatorTest.java index 3097c6f123..05dc73e0ea 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/JsonToImageTranslatorTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/image/json/JsonToImageTranslatorTest.java @@ -17,6 +17,8 @@ package com.google.cloud.tools.jib.image.json; import com.google.cloud.tools.jib.blob.BlobDescriptor; +import com.google.cloud.tools.jib.configuration.Port; +import com.google.cloud.tools.jib.configuration.Port.Protocol; import com.google.cloud.tools.jib.image.DescriptorDigest; import com.google.cloud.tools.jib.image.Image; import com.google.cloud.tools.jib.image.Layer; @@ -106,6 +108,11 @@ private void testToImage_buildable( layers.get(0).getDiffId()); Assert.assertEquals(Arrays.asList("some", "entrypoint", "command"), image.getEntrypoint()); Assert.assertEquals(Arrays.asList("VAR1=VAL1", "VAR2=VAL2"), image.getEnvironment()); - Assert.assertEquals(ImmutableList.of("1000", "2000/tcp", "3000/udp"), image.getExposedPorts()); + Assert.assertEquals( + ImmutableList.of( + new Port(1000, Protocol.TCP), + new Port(2000, Protocol.TCP), + new Port(3000, Protocol.UDP)), + image.getExposedPorts()); } } diff --git a/jib-core/src/test/resources/json/containerconfig.json b/jib-core/src/test/resources/json/containerconfig.json index 5a04548713..6c83f82c47 100644 --- a/jib-core/src/test/resources/json/containerconfig.json +++ b/jib-core/src/test/resources/json/containerconfig.json @@ -1 +1 @@ -{"created":"1970-01-01T00:00:00Z","architecture":"amd64","os":"linux","config":{"Env":["VAR1=VAL1","VAR2=VAL2"],"Entrypoint":["some","entrypoint","command"],"Cmd":["arg1","arg2"],"ExposedPorts":{"1000":{},"2000/tcp":{},"3000/udp":{}}},"rootfs":{"type":"layers","diff_ids":["sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"]}} \ No newline at end of file +{"created":"1970-01-01T00:00:00Z","architecture":"amd64","os":"linux","config":{"Env":["VAR1=VAL1","VAR2=VAL2"],"Entrypoint":["some","entrypoint","command"],"Cmd":["arg1","arg2"],"ExposedPorts":{"1000/tcp":{},"2000/tcp":{},"3000/udp":{}}},"rootfs":{"type":"layers","diff_ids":["sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"]}} \ No newline at end of file diff --git a/jib-core/src/test/resources/json/translated_ocimanifest.json b/jib-core/src/test/resources/json/translated_ocimanifest.json index 0e96752886..b1b1d8c803 100644 --- a/jib-core/src/test/resources/json/translated_ocimanifest.json +++ b/jib-core/src/test/resources/json/translated_ocimanifest.json @@ -1 +1 @@ -{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"sha256:bd8e1e8905936a1492fdd86587ec6c2d6c557cbfdeaf28c6229e708e0454c79a","size":349},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad","size":1000}]} \ No newline at end of file +{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"sha256:71050b2d503c7463cfe574c0b37b6575aed1ace518c0c9174ddb9cd91b57ff4a","size":353},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad","size":1000}]} \ No newline at end of file diff --git a/jib-core/src/test/resources/json/translated_v22manifest.json b/jib-core/src/test/resources/json/translated_v22manifest.json index 91773a0b9f..8d35a1fd6d 100644 --- a/jib-core/src/test/resources/json/translated_v22manifest.json +++ b/jib-core/src/test/resources/json/translated_v22manifest.json @@ -1 +1 @@ -{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:bd8e1e8905936a1492fdd86587ec6c2d6c557cbfdeaf28c6229e708e0454c79a","size":349},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad","size":1000}]} \ No newline at end of file +{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:71050b2d503c7463cfe574c0b37b6575aed1ace518c0c9174ddb9cd91b57ff4a","size":353},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","digest":"sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad","size":1000}]} \ No newline at end of file diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java index 2cd592f0c9..1465486d3c 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildDockerTask.java @@ -105,8 +105,7 @@ public void buildDocker() throws InvalidImageReferenceException { .setMainClass(mainClass) .setJavaArguments(jibExtension.getArgs()) .setJvmFlags(jibExtension.getJvmFlags()) - .setExposedPorts( - ExposedPortsParser.parse(jibExtension.getExposedPorts(), gradleBuildLogger)) + .setExposedPorts(ExposedPortsParser.parse(jibExtension.getExposedPorts())) .setAllowHttp(jibExtension.getAllowInsecureRegistries()); CacheConfiguration applicationLayersCacheConfiguration = CacheConfiguration.forPath(gradleProjectProperties.getCacheDirectory()); diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java index 61e92b8177..2d4d32cbaa 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/BuildImageTask.java @@ -111,8 +111,7 @@ public void buildImage() throws InvalidImageReferenceException { .setMainClass(mainClass) .setJavaArguments(jibExtension.getArgs()) .setJvmFlags(jibExtension.getJvmFlags()) - .setExposedPorts( - ExposedPortsParser.parse(jibExtension.getExposedPorts(), gradleBuildLogger)) + .setExposedPorts(ExposedPortsParser.parse(jibExtension.getExposedPorts())) .setTargetFormat(jibExtension.getFormat()) .setAllowHttp(jibExtension.getAllowInsecureRegistries()); CacheConfiguration applicationLayersCacheConfiguration = diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java index 3477db3021..55c78fff86 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/DockerContextTask.java @@ -121,7 +121,7 @@ public void generateDockerContext() { try { // Validate port input, but don't save the output because we don't want the ranges expanded // here. - ExposedPortsParser.parse(jibExtension.getExposedPorts(), gradleBuildLogger); + ExposedPortsParser.parse(jibExtension.getExposedPorts()); new DockerContextGenerator(gradleProjectProperties.getSourceFilesConfiguration()) .setBaseImage(jibExtension.getBaseImage()) diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java index 184c46abc5..700cabc37a 100644 --- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java +++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildDockerMojo.java @@ -83,7 +83,7 @@ public void execute() throws MojoExecutionException { .setJavaArguments(getArgs()) .setJvmFlags(getJvmFlags()) .setEnvironment(getEnvironment()) - .setExposedPorts(ExposedPortsParser.parse(getExposedPorts(), mavenBuildLogger)) + .setExposedPorts(ExposedPortsParser.parse(getExposedPorts())) .setAllowHttp(getAllowInsecureRegistries()); CacheConfiguration applicationLayersCacheConfiguration = CacheConfiguration.forPath(mavenProjectProperties.getCacheDirectory()); diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java index ac4622b41c..100b8759ee 100644 --- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java +++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java @@ -104,7 +104,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { .setJavaArguments(getArgs()) .setJvmFlags(getJvmFlags()) .setEnvironment(getEnvironment()) - .setExposedPorts(ExposedPortsParser.parse(getExposedPorts(), mavenBuildLogger)) + .setExposedPorts(ExposedPortsParser.parse(getExposedPorts())) .setTargetFormat(ImageFormat.valueOf(getFormat()).getManifestTemplateClass()) .setAllowHttp(getAllowInsecureRegistries()); CacheConfiguration applicationLayersCacheConfiguration = diff --git a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java index e306707f97..66fc7e54b0 100644 --- a/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java +++ b/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/DockerContextMojo.java @@ -59,7 +59,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { try { // Validate port input, but don't save the output because we don't want the ranges expanded // here. - ExposedPortsParser.parse(getExposedPorts(), mavenBuildLogger); + ExposedPortsParser.parse(getExposedPorts()); new DockerContextGenerator(mavenProjectProperties.getSourceFilesConfiguration()) .setBaseImage(getBaseImage())