use of io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver in project servicetalk by apple.
the class DefaultDnsClient method dnsSrvQuery.
@Override
public Publisher<Collection<ServiceDiscovererEvent<InetSocketAddress>>> dnsSrvQuery(final String serviceName) {
requireNonNull(serviceName);
return defer(() -> {
// State per subscribe requires defer so each subscribe gets independent state.
final Map<String, ARecordPublisher> aRecordMap = new HashMap<>(8);
final Map<InetSocketAddress, Integer> availableAddresses = srvFilterDuplicateEvents ? new HashMap<>(8) : emptyMap();
final DnsDiscoveryObserver discoveryObserver = newDiscoveryObserver(serviceName);
// inactive events if necessary.
return recoverWithInactiveEvents(new SrvRecordPublisher(serviceName, discoveryObserver), true).flatMapConcatIterable(identity()).flatMapMerge(srvEvent -> {
assertInEventloop();
if (AVAILABLE.equals(srvEvent.status())) {
return defer(() -> {
final ARecordPublisher aPublisher = new ARecordPublisher(srvEvent.address().hostName(), discoveryObserver);
final ARecordPublisher prevAPublisher = aRecordMap.putIfAbsent(srvEvent.address().hostName(), aPublisher);
if (prevAPublisher != null) {
return newDuplicateSrv(serviceName, srvEvent.address().hostName());
}
Publisher<? extends Collection<ServiceDiscovererEvent<InetAddress>>> returnPub = recoverWithInactiveEvents(aPublisher, false);
return srvFilterDuplicateEvents ? srvFilterDups(returnPub, availableAddresses, srvEvent.address().port()) : returnPub.map(events -> mapEventList(events, inetAddress -> new InetSocketAddress(inetAddress, srvEvent.address().port())));
}).retryWhen((i, cause) -> {
assertInEventloop();
// don't retry. Otherwise this is a resolution exception (e.g. UnknownHostException), and retry.
return cause == SrvAddressRemovedException.DNS_SRV_ADDR_REMOVED || aRecordMap.remove(srvEvent.address().hostName()) == null ? Completable.failed(cause) : srvHostNameRepeater.apply(i);
}).onErrorComplete();
} else if (srvEvent instanceof SrvInactiveEvent) {
// Unwrap the list so we can use it in SrvInactiveCombinerOperator below.
return from(((SrvInactiveEvent<HostAndPort, InetSocketAddress>) srvEvent).aggregatedEvents);
} else {
final ARecordPublisher aPublisher = aRecordMap.remove(srvEvent.address().hostName());
if (aPublisher != null) {
aPublisher.cancelAndFail0(SrvAddressRemovedException.DNS_SRV_ADDR_REMOVED);
}
return empty();
}
}, srvConcurrency).liftSync(inactiveEventsOnError ? SrvInactiveCombinerOperator.EMIT : SrvInactiveCombinerOperator.NO_EMIT);
});
}
use of io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver in project servicetalk by apple.
the class DnsServiceDiscovererObserverTest method onNewResolutionThrows.
@Test
void onNewResolutionThrows() throws Exception {
DnsServiceDiscovererObserver observer = mock(DnsServiceDiscovererObserver.class);
DnsDiscoveryObserver discoveryObserver = mock(DnsDiscoveryObserver.class);
when(observer.onNewDiscovery(anyString())).thenReturn(discoveryObserver);
when(discoveryObserver.onNewResolution(anyString())).thenThrow(DELIBERATE_EXCEPTION);
DnsClient client = dnsClient(observer);
Publisher<?> publisher = client.dnsQuery(HOST_NAME);
verifyNoInteractions(observer, discoveryObserver);
// Wait until SD returns at least one address:
publisher.takeAtMost(1).ignoreElements().toFuture().get();
verify(observer).onNewDiscovery(HOST_NAME);
verify(discoveryObserver).onNewResolution(HOST_NAME);
}
use of io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver in project servicetalk by apple.
the class DnsServiceDiscovererObserverTest method resolutionCompletedThrows.
@Test
void resolutionCompletedThrows() throws Exception {
DnsServiceDiscovererObserver observer = mock(DnsServiceDiscovererObserver.class);
DnsDiscoveryObserver discoveryObserver = mock(DnsDiscoveryObserver.class);
DnsResolutionObserver resolutionObserver = mock(DnsResolutionObserver.class);
when(observer.onNewDiscovery(anyString())).thenReturn(discoveryObserver);
when(discoveryObserver.onNewResolution(anyString())).thenReturn(resolutionObserver);
doThrow(DELIBERATE_EXCEPTION).when(resolutionObserver).resolutionCompleted(any());
DnsClient client = dnsClient(observer);
Publisher<?> publisher = client.dnsQuery(HOST_NAME);
verifyNoInteractions(observer, discoveryObserver, resolutionObserver);
// Wait until SD returns at least one address:
publisher.takeAtMost(1).ignoreElements().toFuture().get();
verify(observer).onNewDiscovery(HOST_NAME);
verify(discoveryObserver).onNewResolution(HOST_NAME);
verify(resolutionObserver).resolutionCompleted(any());
}
use of io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver in project servicetalk by apple.
the class DnsServiceDiscovererObserverTest method resolutionFailedThrows.
@Test
void resolutionFailedThrows() throws Exception {
DnsServiceDiscovererObserver observer = mock(DnsServiceDiscovererObserver.class);
DnsDiscoveryObserver discoveryObserver = mock(DnsDiscoveryObserver.class);
DnsResolutionObserver resolutionObserver = mock(DnsResolutionObserver.class);
when(observer.onNewDiscovery(anyString())).thenReturn(discoveryObserver);
when(discoveryObserver.onNewResolution(anyString())).thenReturn(resolutionObserver);
doThrow(DELIBERATE_EXCEPTION).when(resolutionObserver).resolutionFailed(any());
DnsClient client = dnsClient(observer);
Publisher<?> publisher = client.dnsQuery(INVALID);
verifyNoInteractions(observer, discoveryObserver, resolutionObserver);
// Wait until SD returns at least one address:
ExecutionException ee = assertThrows(ExecutionException.class, () -> publisher.takeAtMost(1).ignoreElements().toFuture().get());
verify(observer).onNewDiscovery(INVALID);
verify(discoveryObserver).onNewResolution(INVALID);
verify(resolutionObserver).resolutionFailed(ee.getCause());
}
Aggregations