Search in sources :

Example 16 with DarkClusterConfig

use of com.linkedin.d2.DarkClusterConfig in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testStrategyZeroMultiplier.

@Test
public void testStrategyZeroMultiplier() {
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0f);
    DarkClusterStrategyNameArray darkClusterStrategyList = new DarkClusterStrategyNameArray();
    darkClusterStrategyList.addAll(Collections.singletonList(RELATIVE_TRAFFIC));
    darkClusterConfig1.setDarkClusterStrategyPrioritizedList(darkClusterStrategyList);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    // test that we choose a NoOpDarkClusterStrategy because we want to allow RelativeTrafficMultiplierStrategy with a zero muliplier to be
    // a NoOp. This allows clients to easily turn off traffic without adjusting multiple values.
    Assert.assertTrue(strategy instanceof NoOpDarkClusterStrategy);
}
Also used : DarkClusterStrategyNameArray(com.linkedin.d2.DarkClusterStrategyNameArray) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) Test(org.testng.annotations.Test)

Example 17 with DarkClusterConfig

use of com.linkedin.d2.DarkClusterConfig in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testNoChangeStrategyOnNotification.

@Test
public void testNoChangeStrategyOnNotification() {
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    DarkClusterConfig darkClusterConfig2 = createRelativeTrafficMultiplierConfig(1.0f);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy).getMultiplier(), 0.5f, "expected 0.5f multiplier");
    // update Strategy, then simulating a notification on the dark cluster.
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig2);
    _clusterInfoProvider.notifyListenersClusterAdded(DARK_CLUSTER_NAME);
    // Nothing should have been changed, since we should be ignoring dark cluster changes. (strategy-impacting changes are all captured
    // in the source cluster data)
    DarkClusterStrategy strategy2 = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy2 instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy2).getMultiplier(), 0.5f, "expected 0.5f multiplier");
}
Also used : RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) Test(org.testng.annotations.Test)

Example 18 with DarkClusterConfig

use of com.linkedin.d2.DarkClusterConfig in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testStrategyRaceCondition.

@Test
public void testStrategyRaceCondition() {
    int noopStrategyCount = 0;
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy).getMultiplier(), 0.5f, "expected 0.5f multiplier");
    // this was registered after DarkClusterStrategyFactoryImpl registered it's clusterListener.
    _clusterInfoProvider.registerClusterListener(new DeletingClusterListener(_clusterInfoProvider));
    ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    final CountDownLatch latch = new CountDownLatch(1);
    try {
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
            latch.countDown();
        }, 0, 1, TimeUnit.MILLISECONDS);
        if (!latch.await(30, TimeUnit.SECONDS)) {
            fail("unable to execute task on executor");
        }
        for (int i = 0; i < 100000; i++) {
            strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
            // verified that this will catch race conditions, saw it happen 9/100k times.
            Assert.assertNotNull(strategy, "null at iteration: " + i);
            if (strategy instanceof NoOpDarkClusterStrategy) {
                noopStrategyCount++;
            }
        }
        System.out.println("noopStrategyCount: " + noopStrategyCount);
    } catch (InterruptedException ie) {
        fail("got interrupted exception", ie);
    } finally {
        scheduledExecutorService.shutdown();
    }
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) CountDownLatch(java.util.concurrent.CountDownLatch) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) Test(org.testng.annotations.Test)

Example 19 with DarkClusterConfig

use of com.linkedin.d2.DarkClusterConfig in project rest.li by linkedin.

the class TestDarkClusterManager method testBasic.

@Test(dataProvider = "provideKeys")
public void testBasic(String whitelist, String blacklist, String httpMethod, DarkGateKeeper darkGateKeeper, int expectedWhiteCount, int expectedBlackCount) {
    MockClusterInfoProvider clusterInfoProvider = new MockClusterInfoProvider();
    Facilities facilities = new MockFacilities(clusterInfoProvider);
    MockStrategyFactory strategyFactory = new MockStrategyFactory();
    DarkClusterManager darkClusterManager = new DarkClusterManagerImpl(SOURCE_CLUSTER_NAME, facilities, strategyFactory, whitelist, blacklist, new DoNothingNotifier(), darkGateKeeper);
    strategyFactory.start();
    // This configuration will choose the RelativeTrafficMultiplierDarkClusterStrategy
    DarkClusterConfig darkClusterConfig = createRelativeTrafficMultiplierConfig(1.0f);
    clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig);
    RestRequest restRequest1 = new RestRequestBuilder(URI.create("/white")).setMethod(httpMethod).build();
    boolean whiteStatus = darkClusterManager.handleDarkRequest(restRequest1, new RequestContext());
    RestRequest restRequest2 = new RestRequestBuilder(URI.create("/black")).setMethod(httpMethod).build();
    boolean blackStatus = darkClusterManager.handleDarkRequest(restRequest2, new RequestContext());
    Assert.assertEquals(whiteStatus, expectedWhiteCount > 0, "white uri requests not as expected");
    Assert.assertEquals(blackStatus, expectedBlackCount > 0, "black uri requests not as expected");
    Assert.assertEquals(strategyFactory.strategyGetOrCreateCount, expectedWhiteCount + expectedBlackCount, "unexpected strategy GetOrCreateCount");
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) DarkClusterManagerImpl(com.linkedin.darkcluster.impl.DarkClusterManagerImpl) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) DarkClusterManager(com.linkedin.darkcluster.api.DarkClusterManager) Facilities(com.linkedin.d2.balancer.Facilities) Test(org.testng.annotations.Test)

Example 20 with DarkClusterConfig

use of com.linkedin.d2.DarkClusterConfig in project rest.li by linkedin.

the class TestDarkClusterFilter method testDarkClusterAssemblyWithDarkCluster.

@Test
public void testDarkClusterAssemblyWithDarkCluster() {
    // we need to have a Mock clusterInfoProvider in order to set up a dark cluster.
    MockClusterInfoProvider clusterInfoProvider = new MockClusterInfoProvider();
    _facilities = new MockFacilities(clusterInfoProvider);
    _darkClusterStrategyFactory = new DarkClusterStrategyFactoryImpl(_facilities, SOURCE_CLUSTER_NAME, _darkClusterDispatcher, _notifier, _random, _verifierManager, _rateLimiterSupplier);
    _darkClusterStrategyFactory.start();
    DarkClusterManager darkClusterManager = new DarkClusterManagerImpl(SOURCE_CLUSTER_NAME, _facilities, _darkClusterStrategyFactory, "", "", _notifier);
    _darkClusterFilter = new DarkClusterFilter(darkClusterManager, _verifierManager);
    // set the multiplier to 1 so that traffic gets sent.
    DarkClusterConfig darkClusterConfig = createRelativeTrafficMultiplierConfig(1.0f);
    clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig);
    clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    // send the request, expecting it to make it all the way down to the client
    RestRequest restRequest = new RestRequestBuilder(URI.create("foo")).build();
    _darkClusterFilter.onRestRequest(restRequest, new RequestContext(), new HashMap<>(), new DummyNextFilter());
    Assert.assertEquals(_client.requestAuthorityMap.size(), 1, "expected 1 request to be sent");
    _darkClusterFilter.onRestError(new RuntimeException("test"), new RequestContext(), new HashMap<>(), new DummyNextFilter());
    _darkClusterFilter.onRestResponse(new RestResponseBuilder().build(), new RequestContext(), new HashMap<>(), new DummyNextFilter());
}
Also used : DarkClusterFilter(com.linkedin.darkcluster.filter.DarkClusterFilter) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) DarkClusterStrategyFactoryImpl(com.linkedin.darkcluster.impl.DarkClusterStrategyFactoryImpl) RestRequest(com.linkedin.r2.message.rest.RestRequest) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) DarkClusterManagerImpl(com.linkedin.darkcluster.impl.DarkClusterManagerImpl) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) DarkClusterManager(com.linkedin.darkcluster.api.DarkClusterManager) Test(org.testng.annotations.Test)

Aggregations

DarkClusterConfig (com.linkedin.d2.DarkClusterConfig)23 Test (org.testng.annotations.Test)20 DarkClusterConfigMap (com.linkedin.d2.DarkClusterConfigMap)10 NoOpDarkClusterStrategy (com.linkedin.darkcluster.api.NoOpDarkClusterStrategy)10 DarkClusterStrategyNameArray (com.linkedin.d2.DarkClusterStrategyNameArray)9 DarkClusterStrategy (com.linkedin.darkcluster.api.DarkClusterStrategy)9 RelativeTrafficMultiplierDarkClusterStrategy (com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy)8 RequestContext (com.linkedin.r2.message.RequestContext)5 RestRequest (com.linkedin.r2.message.rest.RestRequest)5 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)5 Facilities (com.linkedin.d2.balancer.Facilities)4 DarkClusterManager (com.linkedin.darkcluster.api.DarkClusterManager)4 DarkClusterManagerImpl (com.linkedin.darkcluster.impl.DarkClusterManagerImpl)4 D2TransportClientProperties (com.linkedin.d2.D2TransportClientProperties)2 ClusterProperties (com.linkedin.d2.balancer.properties.ClusterProperties)2 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)2 UriProperties (com.linkedin.d2.balancer.properties.UriProperties)2 MockStore (com.linkedin.d2.discovery.stores.mock.MockStore)2 DarkClusterStrategyFactoryImpl (com.linkedin.darkcluster.impl.DarkClusterStrategyFactoryImpl)2 ConstantQpsRateLimiter (com.linkedin.r2.transport.http.client.ConstantQpsRateLimiter)2