From 6cd1bd03696917f0fe22d54c07f58ea58f8aec0a Mon Sep 17 00:00:00 2001 From: Scott Leberknight <174812+sleberknight@users.noreply.github.com> Date: Fri, 26 Apr 2024 19:38:38 -0400 Subject: [PATCH] Add port filtering methods to Ports (#412) * Add findOnlyApplicationPort to find the single application port * Add findApplicationPorts to find only application ports * Add findOnlyAdminPort to find the single admin port * Add findAdminPorts to find only admin ports * Add findPorts to find ports of a specific type * Add additional test for findPort method to cover all branches Closes #411 --- .../org/kiwiproject/registry/util/Ports.java | 72 +++++++- .../kiwiproject/registry/util/PortsTest.java | 161 ++++++++++++++++++ 2 files changed, 232 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kiwiproject/registry/util/Ports.java b/src/main/java/org/kiwiproject/registry/util/Ports.java index fd83434..851c290 100644 --- a/src/main/java/org/kiwiproject/registry/util/Ports.java +++ b/src/main/java/org/kiwiproject/registry/util/Ports.java @@ -1,5 +1,9 @@ package org.kiwiproject.registry.util; +import static com.google.common.base.Preconditions.checkState; +import static org.kiwiproject.base.KiwiPreconditions.checkArgumentNotNull; +import static org.kiwiproject.collect.KiwiLists.first; + import lombok.experimental.UtilityClass; import org.kiwiproject.registry.model.Port; import org.kiwiproject.registry.model.Port.PortType; @@ -8,11 +12,77 @@ import java.util.List; /** - * Utility methods for finding a desired port out of a list of port definitions + * Utility methods for finding a desired port out of a list of port definitions, + * or finding application or admin ports. */ @UtilityClass public class Ports { + /** + * Find the single application port. If there are none or more than one, throw an exception. + * + * @param ports the ports to filter + * @return the application port + * @throws IllegalStateException if there are none or there is more than one port + */ + public static Port findOnlyApplicationPort(List ports) { + var applicationPorts = findApplicationPorts(ports); + checkExactlyOnePort(applicationPorts, "application"); + return first(applicationPorts); + } + + /** + * Find only the application ports in the list of ports. + * + * @param ports the ports to filter + * @return a list of application ports + */ + public static List findApplicationPorts(List ports) { + return findPorts(ports, PortType.APPLICATION); + } + + /** + * Find the single admin port. If there are none or more than one, throw an exception. + * + * @param ports the ports to filter + * @return the admin port + * @throws IllegalStateException if there are none or there is more than one port + */ + public static Port findOnlyAdminPort(List ports) { + var adminPorts = findAdminPorts(ports); + checkExactlyOnePort(adminPorts, "admin"); + return first(adminPorts); + } + + private static void checkExactlyOnePort(List ports, String portType) { + int numPorts = ports.size(); + checkState(numPorts == 1, "expected one %s port but found %s", portType, numPorts); + } + + /** + * Find only the admin ports in the list of ports. + * + * @param ports the ports to filter + * @return a list of application ports + */ + public static List findAdminPorts(List ports) { + return findPorts(ports, PortType.ADMIN); + } + + /** + * Find all ports having the specified {@link PortType}. + * + * @param ports the ports to filter + * @param portType the type of port to find + * @return a list of ports having the specified type + */ + public static List findPorts(List ports, PortType portType) { + checkArgumentNotNull(portType, "portType must not be null"); + return ports.stream() + .filter(port -> port.getType() == portType) + .toList(); + } + /** * Finds the first port of a given type (Application or Admin) from the list. If multiple ports are found and at * least one is marked secure, that port will be given priority. If multiple ports are found with the same security diff --git a/src/test/java/org/kiwiproject/registry/util/PortsTest.java b/src/test/java/org/kiwiproject/registry/util/PortsTest.java index 01dc077..a743c2e 100644 --- a/src/test/java/org/kiwiproject/registry/util/PortsTest.java +++ b/src/test/java/org/kiwiproject/registry/util/PortsTest.java @@ -1,10 +1,13 @@ package org.kiwiproject.registry.util; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.kiwiproject.registry.model.Port; import org.kiwiproject.registry.model.Port.PortType; import org.kiwiproject.registry.model.Port.Security; @@ -79,6 +82,26 @@ void shouldReturnDefaultPortIfCriteriaDoesNotFindOne() { assertThat(port.getSecure()).isEqualTo(Security.SECURE); assertThat(port.getType()).isEqualTo(PortType.APPLICATION); } + + @ParameterizedTest + @CsvSource(textBlock = """ + APPLICATION, SECURE, 9090 + APPLICATION, NOT_SECURE, 8080 + ADMIN, SECURE, 9091 + ADMIN, NOT_SECURE, 8081 + """) + void shouldFindExpectedPort(PortType portType, Security security, int expectedPortNumber) { + var ports = List.of( + newApplicationPort(8080, Security.NOT_SECURE), + newAdminPort(8081, Security.NOT_SECURE), + newApplicationPort(9090, Security.SECURE), + newAdminPort(9091, Security.SECURE) + ); + + var port = Ports.findPort(ports, portType, security); + + assertThat(port.getNumber()).isEqualTo(expectedPortNumber); + } } @Nested @@ -102,4 +125,142 @@ void shouldReturnHttpIfPortIsNotSecure() { assertThat(scheme).isEqualTo("http"); } } + + @Nested + class FindOnlyApplicationPort { + + @Test + void shouldGetTheSingleApplicationPort() { + var ports = List.of(newApplicationPort(8080), newAdminPort(8081)); + + var applicationPort = Ports.findOnlyApplicationPort(ports); + assertThat(applicationPort.getNumber()).isEqualTo(8080); + } + + @Test + void shouldThrowIllegalStateWhenNoApplicationPorts() { + assertThatIllegalStateException() + .isThrownBy(() -> Ports.findOnlyApplicationPort(List.of())) + .withMessage("expected one application port but found 0"); + } + + @Test + void shouldThrowIllegalStateWhenMoreThanOneApplicationPort() { + var ports = List.of(newApplicationPort(8080), newApplicationPort(9090)); + assertThatIllegalStateException() + .isThrownBy(() -> Ports.findOnlyApplicationPort(ports)) + .withMessage("expected one application port but found 2"); + } + } + + @Nested + class FindApplicationPorts { + + @Test + void shouldFindOnlyApplicationPorts() { + var ports = List.of(newApplicationPort(8080), + newAdminPort(8081), + newApplicationPort(8082), + newAdminPort(8083)); + + var applicationPorts = Ports.findApplicationPorts(ports); + assertThat(applicationPorts).extracting(Port::getNumber).containsOnly(8080, 8082); + } + + @Test + void shouldBeEmptyWhenThereAreNoApplicationPorts() { + var ports = List.of(newAdminPort(8081)); + assertThat(Ports.findApplicationPorts(ports)).isEmpty(); + } + } + + @Nested + class FindOnlyAdminPort { + + @Test + void shouldGetTheSingleAdminPort() { + var ports = List.of(newApplicationPort(8080), newAdminPort(8081)); + + var adminPort = Ports.findOnlyAdminPort(ports); + assertThat(adminPort.getNumber()).isEqualTo(8081); + } + + @Test + void shouldThrowIllegalStateWhenNoAdminPorts() { + assertThatIllegalStateException() + .isThrownBy(() -> Ports.findOnlyAdminPort(List.of())) + .withMessage("expected one admin port but found 0"); + } + + @Test + void shouldThrowIllegalStateWhenMoreThanOneApplicationPort() { + var ports = List.of(newAdminPort(8081), newAdminPort(9091)); + assertThatIllegalStateException() + .isThrownBy(() -> Ports.findOnlyAdminPort(ports)) + .withMessage("expected one admin port but found 2"); + } + } + + @Nested + class FindAdminPorts { + + @Test + void shouldFindOnlyAdminPorts() { + var ports = List.of(newApplicationPort(8080), + newAdminPort(8081), + newApplicationPort(8082), + newAdminPort(8083)); + + var adminPorts = Ports.findAdminPorts(ports); + assertThat(adminPorts).extracting(Port::getNumber).containsOnly(8081, 8083); + } + + @Test + void shouldBeEmptyWhenThereAreNoApplicationPorts() { + var ports = List.of(newApplicationPort(8080)); + assertThat(Ports.findAdminPorts(ports)).isEmpty(); + } + } + + @Nested + class FindPortsOfType { + + @Test + void shouldFindApplicationPorts() { + var ports = List.of(newApplicationPort(8080), + newAdminPort(8081), + newApplicationPort(8082), + newAdminPort(8083)); + + var applicationPorts = Ports.findPorts(ports, PortType.APPLICATION); + assertThat(applicationPorts).extracting(Port::getNumber).containsOnly(8080, 8082); + } + + @Test + void shouldFindAdminPorts() { + var ports = List.of(newApplicationPort(8080), + newAdminPort(8081), + newApplicationPort(8082), + newAdminPort(8083)); + + var adminPorts = Ports.findPorts(ports, PortType.ADMIN); + assertThat(adminPorts).extracting(Port::getNumber).containsOnly(8081, 8083); + } + } + + private static Port newApplicationPort(int number) { + return newApplicationPort(number, Security.SECURE); + } + + private static Port newApplicationPort(int number, Security security) { + return Port.of(number, PortType.APPLICATION, security); + } + + private static Port newAdminPort(int number) { + return newAdminPort(number, Security.SECURE); + } + + private static Port newAdminPort(int number, Security security) { + return Port.of(number, PortType.ADMIN, security); + } }