Search in sources :

Example 51 with ClusterProperties

use of com.linkedin.d2.balancer.properties.ClusterProperties in project rest.li by linkedin.

the class SimpleLoadBalancerStateTest method testClientsShutdownAfterPropertyUpdatesRestRequest.

@Test(groups = { "small", "back-end" })
public void testClientsShutdownAfterPropertyUpdatesRestRequest() throws URISyntaxException, InterruptedException {
    reset();
    URI uri = URI.create("http://cluster-1/test");
    List<String> schemes = new ArrayList<>();
    Map<Integer, PartitionData> partitionData = new HashMap<>(1);
    partitionData.put(DefaultPartitionAccessor.DEFAULT_PARTITION_ID, new PartitionData(1d));
    Map<URI, Map<Integer, PartitionData>> uriData = new HashMap<>();
    uriData.put(uri, partitionData);
    schemes.add("http");
    // set up state
    _state.listenToService("service-1", new NullStateListenerCallback());
    _state.listenToCluster("cluster-1", new NullStateListenerCallback());
    _state.setDelayedExecution(0);
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", Arrays.asList("random"), Collections.<String, Object>emptyMap(), Collections.<String, Object>emptyMap(), Collections.<String, String>emptyMap(), schemes, Collections.<URI>emptySet()));
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    _uriRegistry.put("cluster-1", new UriProperties("cluster-1", uriData));
    URI uri1 = URI.create("http://partition-cluster-1/test1");
    URI uri2 = URI.create("http://partition-cluster-1/test2");
    _state.listenToCluster("partition-cluster-1", new NullStateListenerCallback());
    _clusterRegistry.put("partition-cluster-1", new ClusterProperties("partition-cluster-1", null, new HashMap<>(), new HashSet<>(), new RangeBasedPartitionProperties("id=(\\d+)", 0, 100, 2)));
    _state.listenToService("partition-service-1", new NullStateListenerCallback());
    _serviceRegistry.put("partition-service-1", new ServiceProperties("partition-service-1", "partition-cluster-1", "/partition-test", Arrays.asList("degraderV3"), Collections.<String, Object>emptyMap(), Collections.<String, Object>emptyMap(), Collections.<String, String>emptyMap(), schemes, Collections.<URI>emptySet()));
    Map<Integer, PartitionData> partitionWeight = new HashMap<>();
    partitionWeight.put(0, new PartitionData(1d));
    partitionWeight.put(1, new PartitionData(2d));
    Map<URI, Map<Integer, PartitionData>> partitionDesc = new HashMap<>();
    partitionDesc.put(uri1, partitionWeight);
    partitionWeight.remove(0);
    partitionWeight.put(2, new PartitionData(1d));
    partitionDesc.put(uri2, partitionWeight);
    _uriRegistry.put("partition-cluster-1", new UriProperties("partition-cluster-1", partitionDesc));
    TrackerClient client1 = _state.getClient("partition-service-1", uri1);
    TrackerClient client2 = _state.getClient("partition-service-1", uri2);
    assertEquals(client2.getPartitionWeight(1), 2d);
    assertEquals(client2.getPartitionWeight(2), 1d);
    assertEquals(client1.getPartitionWeight(1), 2d);
    // Get client, then refresh cluster
    TrackerClient client = _state.getClient("service-1", uri);
    client.restRequest(new RestRequestBuilder(URI.create("d2://service-1/foo")).build(), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    // now force a refresh by adding cluster
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    // Get client, then refresh service
    client = _state.getClient("service-1", uri);
    client.restRequest(new RestRequestBuilder(URI.create("d2://service-1/foo")).build(), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    // refresh by adding service
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", Arrays.asList("random"), Collections.<String, Object>emptyMap(), null, null, schemes, null));
    // Get client, then mark server up/down
    client = _state.getClient("service-1", uri);
    client.restRequest(new RestRequestBuilder(URI.create("d2://service-1/foo")).build(), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    _uriRegistry.put("cluster-1", new UriProperties("cluster-1", Collections.<URI, Map<Integer, PartitionData>>emptyMap()));
    _uriRegistry.put("cluster-1", new UriProperties("cluster-1", uriData));
    // Get the client one last time
    client = _state.getClient("service-1", uri);
    client.restRequest(new RestRequestBuilder(URI.create("d2://service-1/foo")).build(), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    TestShutdownCallback callback = new TestShutdownCallback();
    _state.shutdown(callback);
    assertTrue(callback.await(10, TimeUnit.SECONDS), "Failed to shut down state");
    for (TransportClientFactory factory : _clientFactories.values()) {
        SimpleLoadBalancerTest.DoNothingClientFactory f = (SimpleLoadBalancerTest.DoNothingClientFactory) factory;
        assertEquals(f.getRunningClientCount(), 0, "not all clients were shut down");
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) UriProperties(com.linkedin.d2.balancer.properties.UriProperties) RangeBasedPartitionProperties(com.linkedin.d2.balancer.properties.RangeBasedPartitionProperties) RequestContext(com.linkedin.r2.message.RequestContext) TransportClientFactory(com.linkedin.r2.transport.common.TransportClientFactory) HashSet(java.util.HashSet) NullStateListenerCallback(com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) Map(java.util.Map) HashMap(java.util.HashMap) Test(org.testng.annotations.Test) DegraderLoadBalancerTest(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerTest)

Example 52 with ClusterProperties

use of com.linkedin.d2.balancer.properties.ClusterProperties in project rest.li by linkedin.

the class SimpleLoadBalancerStateTest method testServiceStrategyList.

@Test(groups = { "small", "back-end" })
public void testServiceStrategyList() throws URISyntaxException, InterruptedException {
    reset();
    LinkedList<String> strategyList = new LinkedList<>();
    URI uri = URI.create("http://cluster-1/test");
    List<String> schemes = new ArrayList<>();
    Map<URI, Double> weights = new HashMap<>();
    weights.put(uri, 1d);
    schemes.add("http");
    assertNull(_state.getStrategy("service-1", "http"));
    // set up state
    _state.listenToService("service-1", new NullStateListenerCallback());
    _state.listenToCluster("cluster-1", new NullStateListenerCallback());
    assertNull(_state.getStrategy("service-1", "http"));
    // Put degraderV2_1 into the strategyList, it it not one of the supported strategies in
    // this strategyFactory, so we should not get a strategy back for http.
    strategyList.add("degraderV2_1");
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", strategyList, Collections.<String, Object>emptyMap(), null, null, schemes, null));
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    assertNull(_state.getStrategy("service-1", "http"));
    // put the random strategy into the Strategy list, it is one of the supported strategies in the
    // strategyFactory for this unit test
    strategyList.clear();
    strategyList.add("random");
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", strategyList, Collections.<String, Object>emptyMap(), null, null, schemes, null));
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    LoadBalancerStrategy strategy = _state.getStrategy("service-1", "http");
    assertNotNull(strategy);
    assertTrue(strategy instanceof RandomLoadBalancerStrategy);
    // now add the degraderV3 strategy into the Strategy list
    strategyList.addFirst("degraderV3");
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", strategyList, Collections.<String, Object>emptyMap(), null, null, schemes, null));
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    strategy = _state.getStrategy("service-1", "http");
    assertNotNull(strategy);
    assertTrue(strategy instanceof DegraderLoadBalancerStrategyV3);
}
Also used : HashMap(java.util.HashMap) RandomLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.random.RandomLoadBalancerStrategy) ArrayList(java.util.ArrayList) RelativeLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.relative.RelativeLoadBalancerStrategy) LoadBalancerStrategy(com.linkedin.d2.balancer.strategies.LoadBalancerStrategy) RandomLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.random.RandomLoadBalancerStrategy) URI(java.net.URI) LinkedList(java.util.LinkedList) DegraderLoadBalancerStrategyV3(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3) NullStateListenerCallback(com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties) Test(org.testng.annotations.Test) DegraderLoadBalancerTest(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerTest)

Example 53 with ClusterProperties

use of com.linkedin.d2.balancer.properties.ClusterProperties in project rest.li by linkedin.

the class SimpleLoadBalancerStateTest method testRefreshServiceStrategies.

@Test(groups = { "small", "back-end" })
public void testRefreshServiceStrategies() throws URISyntaxException, InterruptedException {
    reset();
    URI uri = URI.create("http://cluster-1/test");
    List<String> schemes = new ArrayList<>();
    Map<URI, Double> weights = new HashMap<>();
    weights.put(uri, 1d);
    schemes.add("http");
    assertNull(_state.getStrategy("service-1", "http"));
    // set up state
    _state.listenToService("service-1", new NullStateListenerCallback());
    _state.listenToCluster("cluster-1", new NullStateListenerCallback());
    assertNull(_state.getStrategy("service-1", "http"));
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", Arrays.asList("random"), Collections.<String, Object>emptyMap(), null, null, schemes, null));
    assertNotNull(_state.getStrategy("service-1", "http"));
    LoadBalancerStrategy strategy = _state.getStrategy("service-1", "http");
    assertNotNull(strategy);
    assertTrue(strategy instanceof RandomLoadBalancerStrategy);
    // check that we're getting the exact same strategy (by pointer) every time
    assertTrue(strategy == _state.getStrategy("service-1", "http"));
    assertTrue(strategy == _state.getStrategy("service-1", "http"));
    // now make sure adding a cluster property won't change the strategy
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    // we should still have the same strategy now
    LoadBalancerStrategy newStrategy = _state.getStrategy("service-1", "http");
    assertNotNull(newStrategy);
    assertTrue(strategy == newStrategy);
    assertTrue(newStrategy instanceof RandomLoadBalancerStrategy);
    strategy = newStrategy;
    // refresh by adding service
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", Arrays.asList("random"), Collections.<String, Object>emptyMap(), null, null, schemes, null));
    // we should have a different strategy
    newStrategy = _state.getStrategy("service-1", "http");
    assertNotNull(newStrategy);
    assertFalse(strategy == newStrategy);
    assertTrue(newStrategy instanceof RandomLoadBalancerStrategy);
    TestShutdownCallback callback = new TestShutdownCallback();
    _state.shutdown(callback);
    assertTrue(callback.await(10, TimeUnit.SECONDS), "Failed to shut down state");
}
Also used : HashMap(java.util.HashMap) RandomLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.random.RandomLoadBalancerStrategy) ArrayList(java.util.ArrayList) RelativeLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.relative.RelativeLoadBalancerStrategy) LoadBalancerStrategy(com.linkedin.d2.balancer.strategies.LoadBalancerStrategy) RandomLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.random.RandomLoadBalancerStrategy) URI(java.net.URI) NullStateListenerCallback(com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties) Test(org.testng.annotations.Test) DegraderLoadBalancerTest(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerTest)

Example 54 with ClusterProperties

use of com.linkedin.d2.balancer.properties.ClusterProperties in project rest.li by linkedin.

the class SimpleLoadBalancerStateTest method testRegisterClusterListenerDuplicates.

@Test
public void testRegisterClusterListenerDuplicates() {
    reset();
    MockClusterListener clusterListener = new MockClusterListener();
    _state.registerClusterListener(clusterListener);
    _state.registerClusterListener(clusterListener);
    _state.listenToCluster(CLUSTER1_CLUSTER_NAME, new NullStateListenerCallback());
    _clusterRegistry.put(CLUSTER1_CLUSTER_NAME, new ClusterProperties(CLUSTER1_CLUSTER_NAME));
    assertEquals(clusterListener.getClusterAddedCount(CLUSTER1_CLUSTER_NAME), 1, "expected 1 call since duplicates are not allowed");
}
Also used : NullStateListenerCallback(com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties) Test(org.testng.annotations.Test) DegraderLoadBalancerTest(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerTest)

Example 55 with ClusterProperties

use of com.linkedin.d2.balancer.properties.ClusterProperties in project rest.li by linkedin.

the class SimpleLoadBalancerStateTest method testClientsShutdownAfterPropertyUpdatesStreamRequest.

@Test(groups = { "small", "back-end" })
public void testClientsShutdownAfterPropertyUpdatesStreamRequest() throws URISyntaxException, InterruptedException {
    reset();
    URI uri = URI.create("http://cluster-1/test");
    List<String> schemes = new ArrayList<>();
    Map<Integer, PartitionData> partitionData = new HashMap<>(1);
    partitionData.put(DefaultPartitionAccessor.DEFAULT_PARTITION_ID, new PartitionData(1d));
    Map<URI, Map<Integer, PartitionData>> uriData = new HashMap<>();
    uriData.put(uri, partitionData);
    schemes.add("http");
    // set up state
    _state.listenToService("service-1", new NullStateListenerCallback());
    _state.listenToCluster("cluster-1", new NullStateListenerCallback());
    _state.setDelayedExecution(0);
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", Arrays.asList("random"), Collections.<String, Object>emptyMap(), Collections.<String, Object>emptyMap(), Collections.<String, String>emptyMap(), schemes, Collections.<URI>emptySet()));
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    _uriRegistry.put("cluster-1", new UriProperties("cluster-1", uriData));
    URI uri1 = URI.create("http://partition-cluster-1/test1");
    URI uri2 = URI.create("http://partition-cluster-1/test2");
    _state.listenToCluster("partition-cluster-1", new NullStateListenerCallback());
    _clusterRegistry.put("partition-cluster-1", new ClusterProperties("partition-cluster-1", null, new HashMap<>(), new HashSet<>(), new RangeBasedPartitionProperties("id=(\\d+)", 0, 100, 2)));
    _state.listenToService("partition-service-1", new NullStateListenerCallback());
    _serviceRegistry.put("partition-service-1", new ServiceProperties("partition-service-1", "partition-cluster-1", "/partition-test", Arrays.asList("degraderV3"), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), schemes, Collections.emptySet()));
    Map<Integer, PartitionData> partitionWeight = new HashMap<>();
    partitionWeight.put(0, new PartitionData(1d));
    partitionWeight.put(1, new PartitionData(2d));
    Map<URI, Map<Integer, PartitionData>> partitionDesc = new HashMap<>();
    partitionDesc.put(uri1, partitionWeight);
    partitionWeight.remove(0);
    partitionWeight.put(2, new PartitionData(1d));
    partitionDesc.put(uri2, partitionWeight);
    _uriRegistry.put("partition-cluster-1", new UriProperties("partition-cluster-1", partitionDesc));
    TrackerClient client1 = _state.getClient("partition-service-1", uri1);
    TrackerClient client2 = _state.getClient("partition-service-1", uri2);
    assertEquals(client2.getPartitionWeight(1), 2d);
    assertEquals(client2.getPartitionWeight(2), 1d);
    assertEquals(client1.getPartitionWeight(1), 2d);
    // Get client, then refresh cluster
    TrackerClient client = _state.getClient("service-1", uri);
    client.streamRequest(new StreamRequestBuilder(URI.create("d2://service-1/foo")).build(EntityStreams.emptyStream()), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    // now force a refresh by adding cluster
    _clusterRegistry.put("cluster-1", new ClusterProperties("cluster-1"));
    // Get client, then refresh service
    client = _state.getClient("service-1", uri);
    client.streamRequest(new StreamRequestBuilder(URI.create("d2://service-1/foo")).build(EntityStreams.emptyStream()), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    // refresh by adding service
    _serviceRegistry.put("service-1", new ServiceProperties("service-1", "cluster-1", "/test", Arrays.asList("random"), Collections.<String, Object>emptyMap(), null, null, schemes, null));
    // Get client, then mark server up/down
    client = _state.getClient("service-1", uri);
    client.streamRequest(new StreamRequestBuilder(URI.create("d2://service-1/foo")).build(EntityStreams.emptyStream()), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    _uriRegistry.put("cluster-1", new UriProperties("cluster-1", Collections.<URI, Map<Integer, PartitionData>>emptyMap()));
    _uriRegistry.put("cluster-1", new UriProperties("cluster-1", uriData));
    // Get the client one last time
    client = _state.getClient("service-1", uri);
    client.streamRequest(new StreamRequestBuilder(URI.create("d2://service-1/foo")).build(EntityStreams.emptyStream()), new RequestContext(), Collections.emptyMap(), new TransportCallbackAdapter<>(Callbacks.empty()));
    TestShutdownCallback callback = new TestShutdownCallback();
    _state.shutdown(callback);
    assertTrue(callback.await(10, TimeUnit.SECONDS), "Failed to shut down state");
    for (TransportClientFactory factory : _clientFactories.values()) {
        SimpleLoadBalancerTest.DoNothingClientFactory f = (SimpleLoadBalancerTest.DoNothingClientFactory) factory;
        assertEquals(f.getRunningClientCount(), 0, "not all clients were shut down");
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) UriProperties(com.linkedin.d2.balancer.properties.UriProperties) RangeBasedPartitionProperties(com.linkedin.d2.balancer.properties.RangeBasedPartitionProperties) RequestContext(com.linkedin.r2.message.RequestContext) TransportClientFactory(com.linkedin.r2.transport.common.TransportClientFactory) HashSet(java.util.HashSet) NullStateListenerCallback(com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties) Map(java.util.Map) HashMap(java.util.HashMap) Test(org.testng.annotations.Test) DegraderLoadBalancerTest(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerTest)

Aggregations

ClusterProperties (com.linkedin.d2.balancer.properties.ClusterProperties)72 HashMap (java.util.HashMap)51 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)49 Test (org.testng.annotations.Test)47 ArrayList (java.util.ArrayList)42 UriProperties (com.linkedin.d2.balancer.properties.UriProperties)41 URI (java.net.URI)38 Map (java.util.Map)32 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)24 DegraderLoadBalancerTest (com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerTest)24 List (java.util.List)20 NullStateListenerCallback (com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback)18 LoadBalancerStrategy (com.linkedin.d2.balancer.strategies.LoadBalancerStrategy)18 None (com.linkedin.common.util.None)16 TransportClientFactory (com.linkedin.r2.transport.common.TransportClientFactory)16 FutureCallback (com.linkedin.common.callback.FutureCallback)15 HashSet (java.util.HashSet)14 DarkClusterConfigMap (com.linkedin.d2.DarkClusterConfigMap)13 RequestContext (com.linkedin.r2.message.RequestContext)13 ClusterPropertiesJsonSerializer (com.linkedin.d2.balancer.properties.ClusterPropertiesJsonSerializer)12