Search in sources :

Example 1 with DnsDiscoveryObserver

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);
    });
}
Also used : EventLoopAwareNettyIoExecutor(io.servicetalk.transport.netty.internal.EventLoopAwareNettyIoExecutor) CancelImmediatelySubscriber(io.servicetalk.concurrent.internal.CancelImmediatelySubscriber) LoggerFactory(org.slf4j.LoggerFactory) ServiceDiscovererEvent(io.servicetalk.client.api.ServiceDiscovererEvent) Publisher.empty(io.servicetalk.concurrent.api.Publisher.empty) DefaultDnsQuestion(io.netty.handler.codec.dns.DefaultDnsQuestion) DefaultDnsCache(io.netty.resolver.dns.DefaultDnsCache) Collections.singletonList(java.util.Collections.singletonList) InetAddress(java.net.InetAddress) SubscriberUtils.newExceptionForInvalidRequestN(io.servicetalk.concurrent.internal.SubscriberUtils.newExceptionForInvalidRequestN) Duration(java.time.Duration) Map(java.util.Map) DnsClients.mapEventList(io.servicetalk.dns.discovery.netty.DnsClients.mapEventList) BuilderUtils.socketChannel(io.servicetalk.transport.netty.internal.BuilderUtils.socketChannel) SocketChannel(io.netty.channel.socket.SocketChannel) DnsDiscoveryObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver) DefaultDnsRecordDecoder.decodeName(io.netty.handler.codec.dns.DefaultDnsRecordDecoder.decodeName) DnsNameResolver(io.netty.resolver.dns.DnsNameResolver) FutureListener(io.netty.util.concurrent.FutureListener) SubscriberUtils.handleExceptionFromOnSubscribe(io.servicetalk.concurrent.internal.SubscriberUtils.handleExceptionFromOnSubscribe) Collections.emptyList(java.util.Collections.emptyList) Collection(java.util.Collection) ThrowableUtils.unknownStackTrace(io.servicetalk.concurrent.internal.ThrowableUtils.unknownStackTrace) DefaultServiceDiscovererEvent(io.servicetalk.client.api.DefaultServiceDiscovererEvent) EventLoop(io.netty.channel.EventLoop) InetSocketAddress(java.net.InetSocketAddress) List(java.util.List) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) DuplicateSubscribeException(io.servicetalk.concurrent.internal.DuplicateSubscribeException) Function.identity(java.util.function.Function.identity) ResolutionResult(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.ResolutionResult) DnsRecord(io.netty.handler.codec.dns.DnsRecord) DnsNameResolverBuilder(io.netty.resolver.dns.DnsNameResolverBuilder) Publisher(io.servicetalk.concurrent.api.Publisher) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) ByteBuffer.wrap(java.nio.ByteBuffer.wrap) DnsRawRecord(io.netty.handler.codec.dns.DnsRawRecord) HashMap(java.util.HashMap) Cancellable(io.servicetalk.concurrent.Cancellable) DnsResolutionObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsResolutionObserver) RepeatStrategies.repeatWithConstantBackoffDeltaJitter(io.servicetalk.concurrent.api.RepeatStrategies.repeatWithConstantBackoffDeltaJitter) Subscriber(io.servicetalk.concurrent.PublisherSource.Subscriber) ArrayList(java.util.ArrayList) RandomAccess(java.util.RandomAccess) BuilderUtils.datagramChannel(io.servicetalk.transport.netty.internal.BuilderUtils.datagramChannel) SubscribablePublisher(io.servicetalk.concurrent.api.internal.SubscribablePublisher) AVAILABLE(io.servicetalk.client.api.ServiceDiscovererEvent.Status.AVAILABLE) ByteBuf(io.netty.buffer.ByteBuf) ImmediateEventExecutor(io.netty.util.concurrent.ImmediateEventExecutor) SubscriberUtils.deliverErrorFromSource(io.servicetalk.concurrent.internal.SubscriberUtils.deliverErrorFromSource) ServiceDiscovererUtils.calculateDifference(io.servicetalk.dns.discovery.netty.ServiceDiscovererUtils.calculateDifference) SRV(io.netty.handler.codec.dns.DnsRecordType.SRV) Objects.requireNonNull(java.util.Objects.requireNonNull) Comparator.comparing(java.util.Comparator.comparing) Publisher.from(io.servicetalk.concurrent.api.Publisher.from) Publisher.defer(io.servicetalk.concurrent.api.Publisher.defer) SubscriberUtils.safeOnError(io.servicetalk.concurrent.internal.SubscriberUtils.safeOnError) Nullable(javax.annotation.Nullable) IntFunction(java.util.function.IntFunction) Collections.emptyMap(java.util.Collections.emptyMap) Logger(org.slf4j.Logger) SubscriberUtils.isRequestNValid(io.servicetalk.concurrent.internal.SubscriberUtils.isRequestNValid) Promise(io.netty.util.concurrent.Promise) EventLoopAwareNettyIoExecutors.toEventLoopAwareNettyIoExecutor(io.servicetalk.transport.netty.internal.EventLoopAwareNettyIoExecutors.toEventLoopAwareNettyIoExecutor) ListenableAsyncCloseable(io.servicetalk.concurrent.api.ListenableAsyncCloseable) ClosedChannelException(java.nio.channels.ClosedChannelException) FlowControlUtils.addWithOverflowProtection(io.servicetalk.concurrent.internal.FlowControlUtils.addWithOverflowProtection) Completable(io.servicetalk.concurrent.api.Completable) PublisherOperator(io.servicetalk.concurrent.api.PublisherOperator) AsyncCloseables.toAsyncCloseable(io.servicetalk.concurrent.api.AsyncCloseables.toAsyncCloseable) Subscription(io.servicetalk.concurrent.PublisherSource.Subscription) RejectedSubscribeError(io.servicetalk.concurrent.internal.RejectedSubscribeError) IoExecutor(io.servicetalk.transport.api.IoExecutor) Publisher.failed(io.servicetalk.concurrent.api.Publisher.failed) Completable.completed(io.servicetalk.concurrent.api.Completable.completed) ResolvedAddressTypes(io.netty.resolver.ResolvedAddressTypes) Future(io.netty.util.concurrent.Future) Comparator(java.util.Comparator) SECONDS(java.util.concurrent.TimeUnit.SECONDS) HostAndPort(io.servicetalk.transport.api.HostAndPort) DnsDiscoveryObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) Publisher(io.servicetalk.concurrent.api.Publisher) SubscribablePublisher(io.servicetalk.concurrent.api.internal.SubscribablePublisher) HostAndPort(io.servicetalk.transport.api.HostAndPort) Collection(java.util.Collection) InetAddress(java.net.InetAddress)

Example 2 with DnsDiscoveryObserver

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);
}
Also used : DnsDiscoveryObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver) Test(org.junit.jupiter.api.Test)

Example 3 with DnsDiscoveryObserver

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());
}
Also used : DnsDiscoveryObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver) DnsResolutionObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsResolutionObserver) Test(org.junit.jupiter.api.Test)

Example 4 with DnsDiscoveryObserver

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());
}
Also used : DnsDiscoveryObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver) DnsResolutionObserver(io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsResolutionObserver) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.jupiter.api.Test)

Aggregations

DnsDiscoveryObserver (io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsDiscoveryObserver)4 DnsResolutionObserver (io.servicetalk.dns.discovery.netty.DnsServiceDiscovererObserver.DnsResolutionObserver)3 Test (org.junit.jupiter.api.Test)3 ByteBuf (io.netty.buffer.ByteBuf)1 EventLoop (io.netty.channel.EventLoop)1 SocketChannel (io.netty.channel.socket.SocketChannel)1 DefaultDnsQuestion (io.netty.handler.codec.dns.DefaultDnsQuestion)1 DefaultDnsRecordDecoder.decodeName (io.netty.handler.codec.dns.DefaultDnsRecordDecoder.decodeName)1 DnsRawRecord (io.netty.handler.codec.dns.DnsRawRecord)1 DnsRecord (io.netty.handler.codec.dns.DnsRecord)1 SRV (io.netty.handler.codec.dns.DnsRecordType.SRV)1 ResolvedAddressTypes (io.netty.resolver.ResolvedAddressTypes)1 DefaultDnsCache (io.netty.resolver.dns.DefaultDnsCache)1 DnsNameResolver (io.netty.resolver.dns.DnsNameResolver)1 DnsNameResolverBuilder (io.netty.resolver.dns.DnsNameResolverBuilder)1 ReferenceCountUtil (io.netty.util.ReferenceCountUtil)1 Future (io.netty.util.concurrent.Future)1 FutureListener (io.netty.util.concurrent.FutureListener)1 ImmediateEventExecutor (io.netty.util.concurrent.ImmediateEventExecutor)1 Promise (io.netty.util.concurrent.Promise)1