Rework dyndns provider registry and add tests
All checks were successful
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
Ryan Harg 2024-11-27 14:11:56 +01:00
parent 98f1a855f7
commit fcac4fb75b
5 changed files with 74 additions and 43 deletions

View file

@ -1,7 +1,7 @@
package de.rpr.ddnsclient;
import de.rpr.ddnsclient.dyndns.DynDns;
import de.rpr.ddnsclient.dyndns.DynDnsRouter;
import de.rpr.ddnsclient.dyndns.DyndnsProviderRegistry;
import de.rpr.ddnsclient.lookup.DnsResolver;
import de.rpr.ddnsclient.lookup.PublicIpLookup;
import de.rpr.ddnsclient.model.Config;
@ -16,14 +16,13 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@ApplicationScoped
public class Updater {
private static final Logger log = Logger.getLogger(Updater.class);
private final DynDnsRouter dynDnsRouter;
private final DyndnsProviderRegistry dyndnsProviderRegistry;
private final PublicIpLookup publicIpLookup;
private final DnsResolver dnsResolver;
private final Duration backoff;
@ -33,12 +32,12 @@ public class Updater {
private final Map<String, LocalDateTime> updateMap = new HashMap<>();
@Inject
public Updater(DynDnsRouter dynDnsRouter,
public Updater(DyndnsProviderRegistry dyndnsProviderRegistry,
PublicIpLookup publicIpLookup,
DnsResolver dnsResolver,
Config config,
@ConfigProperty(name = "ddnsclient.backoff-duration", defaultValue = "300s") Duration backoff) {
this.dynDnsRouter = dynDnsRouter;
this.dyndnsProviderRegistry = dyndnsProviderRegistry;
this.publicIpLookup = publicIpLookup;
this.dnsResolver = dnsResolver;
this.config = config;
@ -70,7 +69,7 @@ public class Updater {
if (!publicIps.equals(registeredIps)) {
log.tracef("IPs changed, updating...");
DynDns dynDns = dynDnsRouter.get(cfg.provider());
DynDns dynDns = dyndnsProviderRegistry.get(cfg.provider());
dynDns.update(cfg.hostname(), publicIps, new DyndnsAuth(null, null, cfg.token()));
updateMap.put(cfg.hostname(), LocalDateTime.now());
} else {

View file

@ -1,27 +0,0 @@
package de.rpr.ddnsclient.dyndns;
import de.rpr.ddnsclient.model.DyndnsAuth;
import io.quarkus.arc.All;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.List;
@ApplicationScoped
public class DynDnsRouter {
private final List<DynDns> dynDnsList;
@SuppressWarnings("CdiInjectionPointsInspection")
@Inject
public DynDnsRouter(@All List<DynDns> dynDnsList) {
this.dynDnsList = dynDnsList;
}
public DynDns get(String name) {
return dynDnsList.stream()
.filter(it -> it.name().equals(name))
.findFirst()
.orElseThrow(() -> new IllegalStateException("Unknown DynDns provider"));
}
}

View file

@ -0,0 +1,30 @@
package de.rpr.ddnsclient.dyndns;
import io.quarkus.arc.All;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ApplicationScoped
public class DyndnsProviderRegistry {
private final Map<String, DynDns> dynDnsMap;
@SuppressWarnings("CdiInjectionPointsInspection")
public DyndnsProviderRegistry(@All List<DynDns> dynDnsList) {
if (dynDnsList == null || dynDnsList.isEmpty()) {
throw new IllegalStateException("No dyndns services implemented1");
}
this.dynDnsMap = dynDnsList.stream().collect(Collectors.toMap(DynDns::name, dynDns -> dynDns));
}
public DynDns get(String name) {
if (!dynDnsMap.containsKey(name)) {
throw new IllegalStateException("Unknown DynDns provider");
}
return dynDnsMap.get(name);
}
}

View file

@ -2,7 +2,7 @@ package de.rpr.ddnsclient;
import de.rpr.ddnsclient.dyndns.Ddnss;
import de.rpr.ddnsclient.dyndns.DynDns;
import de.rpr.ddnsclient.dyndns.DynDnsRouter;
import de.rpr.ddnsclient.dyndns.DyndnsProviderRegistry;
import de.rpr.ddnsclient.lookup.DnsResolver;
import de.rpr.ddnsclient.lookup.PublicIpLookup;
import de.rpr.ddnsclient.model.Config;
@ -25,7 +25,7 @@ import static org.mockito.Mockito.*;
class UpdaterTest {
@Mock
DynDnsRouter dynDnsRouter;
DyndnsProviderRegistry dyndnsProviderRegistry;
@Mock
PublicIpLookup publicIpLookup;
@Mock
@ -40,7 +40,7 @@ class UpdaterTest {
@Test
void should_throw_exception_if_config_is_empty() {
Config config = new Config();
Updater updater = new Updater(dynDnsRouter, publicIpLookup, dnsResolver, config, backoff);
Updater updater = new Updater(dyndnsProviderRegistry, publicIpLookup, dnsResolver, config, backoff);
Assertions.assertThrows(IllegalStateException.class, updater::run);
}
@ -56,7 +56,7 @@ class UpdaterTest {
add(new Value("ddnss", "host2.example.org", null, null, "token"));
}};
Updater updater = new Updater(dynDnsRouter, publicIpLookup, dnsResolver, multipleConfigEntries, backoff);
Updater updater = new Updater(dyndnsProviderRegistry, publicIpLookup, dnsResolver, multipleConfigEntries, backoff);
updater.run();
ArgumentCaptor<String> hostnameCaptor = ArgumentCaptor.forClass(String.class);
@ -74,10 +74,10 @@ class UpdaterTest {
when(publicIpLookup.get()).thenReturn(ips);
when(dnsResolver.resolve("example.org")).thenReturn(ips);
Updater updater = new Updater(dynDnsRouter, publicIpLookup, dnsResolver, ddnssConfig, backoff);
Updater updater = new Updater(dyndnsProviderRegistry, publicIpLookup, dnsResolver, ddnssConfig, backoff);
updater.run();
verify(dynDnsRouter, never()).get(any());
verify(dyndnsProviderRegistry, never()).get(any());
}
@ -86,13 +86,13 @@ class UpdaterTest {
DynDns ddnss = mock(Ddnss.class);
when(dynDnsRouter.get("ddnss")).thenReturn(ddnss);
when(dyndnsProviderRegistry.get("ddnss")).thenReturn(ddnss);
IPs publicIps = new IPs("ipv4", "ipv6");
when(publicIpLookup.get()).thenReturn(publicIps);
when(dnsResolver.resolve("example.org")).thenReturn(new IPs("registered_ipv4", "registered_ipv6"));
Updater updater = new Updater(dynDnsRouter, publicIpLookup, dnsResolver, ddnssConfig, backoff);
Updater updater = new Updater(dyndnsProviderRegistry, publicIpLookup, dnsResolver, ddnssConfig, backoff);
updater.run();
verify(ddnss).update(
@ -107,13 +107,13 @@ class UpdaterTest {
DynDns ddnss = mock(Ddnss.class);
when(dynDnsRouter.get("ddnss")).thenReturn(ddnss);
when(dyndnsProviderRegistry.get("ddnss")).thenReturn(ddnss);
IPs publicIps = new IPs("ipv4", "ipv6");
when(publicIpLookup.get()).thenReturn(publicIps);
when(dnsResolver.resolve("example.org")).thenReturn(new IPs("registered_ipv4", "registered_ipv6"));
Updater updater = new Updater(dynDnsRouter, publicIpLookup, dnsResolver, ddnssConfig, backoff);
Updater updater = new Updater(dyndnsProviderRegistry, publicIpLookup, dnsResolver, ddnssConfig, backoff);
updater.run();
updater.run();

View file

@ -0,0 +1,29 @@
package de.rpr.ddnsclient.dyndns;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
class DyndnsProviderRegistryTest {
@Test
void empty_dyndns_list_should_throw_exception() {
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> new DyndnsProviderRegistry(List.of()));
}
@Test
void existing_dyndns_provider_should_be_returned() {
DyndnsProviderRegistry registry = new DyndnsProviderRegistry(List.of(new Ddnss()));
assertThat(registry.get("ddnss")).isNotNull();
}
@Test
void unknown_dyndns_provider_should_throw_exception() {
DyndnsProviderRegistry registry = new DyndnsProviderRegistry(List.of(new Ddnss()));
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> registry.get("unknown"));
}
}