content: /*
   * Copyright 2010 Proofpoint, Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package io.airlift.discovery.client;
  
  import com.google.common.collect.ImmutableMap;
  import com.google.common.collect.ImmutableSet;
  import com.google.inject.Binder;
  import com.google.inject.Guice;
  import com.google.inject.Injector;
  import com.google.inject.Key;
  import com.google.inject.Module;
  import com.google.inject.Provider;
  import com.google.inject.TypeLiteral;
  import io.airlift.configuration.ConfigurationFactory;
  import io.airlift.configuration.ConfigurationModule;
  import io.airlift.discovery.client.testing.TestingDiscoveryModule;
  import io.airlift.node.testing.TestingNodeModule;
  import org.junit.jupiter.api.Test;
  
  import java.util.Map;
  import java.util.Set;
  
  import static io.airlift.discovery.client.DiscoveryBinder.discoveryBinder;
  import static io.airlift.discovery.client.ServiceTypes.serviceType;
  import static org.assertj.core.api.Assertions.assertThat;
  
  public class TestDiscoveryBinder
  {
      @Test
      public void testBindSelector()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(),
                  binder -> discoveryBinder(binder).bindServiceAnnouncement(new ServiceAnnouncementProvider().get()));
  
          Set<ServiceAnnouncement> announcements = injector.getInstance(Key.get(new TypeLiteral<Set<ServiceAnnouncement>>() {}));
          assertThat(announcements).isEqualTo(ImmutableSet.of(ANNOUNCEMENT));
      }
  
      @Test
      public void testBindSelectorProviderClass()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(),
                  binder -> discoveryBinder(binder).bindServiceAnnouncement(ServiceAnnouncementProvider.class));
  
          Set<ServiceAnnouncement> announcements = injector.getInstance(Key.get(new TypeLiteral<Set<ServiceAnnouncement>>() {}));
          assertThat(announcements).isEqualTo(ImmutableSet.of(ANNOUNCEMENT));
      }
  
      @Test
      public void testBindSelectorProviderInstance()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(),
                  binder -> discoveryBinder(binder).bindServiceAnnouncement(new ServiceAnnouncementProvider()));
  
          Set<ServiceAnnouncement> announcements = injector.getInstance(Key.get(new TypeLiteral<Set<ServiceAnnouncement>>() {}));
          assertThat(announcements).isEqualTo(ImmutableSet.of(ANNOUNCEMENT));
      }
  
      @Test
      public void testBindSelectorString()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(),
                  binder -> discoveryBinder(binder).bindSelector("apple"));
  
          assertCanCreateServiceSelector(injector, "apple", ServiceSelectorConfig.DEFAULT_POOL);
      }
  
      @Test
      public void testBindSelectorAnnotation()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(),
                  binder -> discoveryBinder(binder).bindSelector(serviceType("apple")));
  
          assertCanCreateServiceSelector(injector, "apple", ServiceSelectorConfig.DEFAULT_POOL);
      }
  
      @Test
      public void testBindSelectorStringWithPool()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(ImmutableMap.of("discovery.apple.pool", "apple-pool")),
                  binder -> discoveryBinder(binder).bindSelector("apple"));
  
          assertCanCreateServiceSelector(injector, "apple", "apple-pool");
      }
  
      @Test
      public void testBindSelectorAnnotationWithPool()
      {
          Injector injector = Guice.createInjector(
                  new TestModule(ImmutableMap.of("discovery.apple.pool", "apple-pool")),
                  binder -> discoveryBinder(binder).bindSelector(serviceType("apple")));
  
          assertCanCreateServiceSelector(injector, "apple", "apple-pool");
      }
  
      private void assertCanCreateServiceSelector(Injector injector, String expectedType, String expectedPool)
      {
          ServiceSelector actualServiceSelector = injector.getInstance(Key.get(ServiceSelector.class, serviceType(expectedType)));
          assertThat(actualServiceSelector).isNotNull();
          assertThat(actualServiceSelector.getType()).isEqualTo(expectedType);
          assertThat(actualServiceSelector.getPool()).isEqualTo(expectedPool);
      }
  
      private static class TestModule
              implements Module
      {
          private Map<String, String> configProperties;
  
          private TestModule()
          {
              configProperties = ImmutableMap.of();
          }
  
          private TestModule(Map<String, String> configProperties)
          {
              this.configProperties = ImmutableMap.copyOf(configProperties);
          }
  
          @Override
          public void configure(Binder binder)
          {
              binder.install(new ConfigurationModule(new ConfigurationFactory(configProperties)));
              binder.install(new TestingNodeModule());
              binder.install(new TestingDiscoveryModule());
          }
      }
  
      private static final ServiceAnnouncement ANNOUNCEMENT = ServiceAnnouncement.serviceAnnouncement("apple").addProperty("a", "apple").build();
  
      private static class ServiceAnnouncementProvider
              implements Provider<ServiceAnnouncement>
      {
          @Override
          public ServiceAnnouncement get()
          {
              return ANNOUNCEMENT;
          }
      }
  }
  