Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add port filtering methods to Ports #412

Merged
merged 6 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion src/main/java/org/kiwiproject/registry/util/Ports.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<Port> 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<Port> findApplicationPorts(List<Port> 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<Port> ports) {
var adminPorts = findAdminPorts(ports);
checkExactlyOnePort(adminPorts, "admin");
return first(adminPorts);
}

private static void checkExactlyOnePort(List<Port> 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<Port> findAdminPorts(List<Port> 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<Port> findPorts(List<Port> 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
Expand Down
161 changes: 161 additions & 0 deletions src/test/java/org/kiwiproject/registry/util/PortsTest.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}