Search in sources :

Example 1 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testCreateStrategiesWithNoDarkClusters.

@Test
public void testCreateStrategiesWithNoDarkClusters() {
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    RestRequest dummyRestRequest = new RestRequestBuilder(URI.create("foo")).build();
    boolean requestSent = strategy.handleRequest(dummyRestRequest, dummyRestRequest, new RequestContext());
    Assert.assertTrue(strategy instanceof NoOpDarkClusterStrategy);
    Assert.assertFalse(requestSent, "default empty strategy should not send request");
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) Test(org.testng.annotations.Test)

Example 2 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testStrategyFallThruWithNoFallback.

@Test
public void testStrategyFallThruWithNoFallback() {
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    DarkClusterStrategyNameArray darkClusterStrategyList = new DarkClusterStrategyNameArray();
    // Only ConstantQPS strategy is present, with no alternative.
    darkClusterStrategyList.addAll(Collections.singletonList(CONSTANT_QPS));
    darkClusterConfig1.setDarkClusterStrategyPrioritizedList(darkClusterStrategyList);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy = _strategyFactory.get(DARK_CLUSTER_NAME);
    // test that we didn't find a strategy corresponding to Constant QPS and fell through. It will end up with the NoOpStrategy.
    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 3 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testRemoveDarkClusters.

@Test
public void testRemoveDarkClusters() {
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    DarkClusterConfig darkClusterConfig2 = createRelativeTrafficMultiplierConfig(0.1f);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig1);
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME2, darkClusterConfig2);
    // now trigger a refresh on the source cluster.
    _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");
    DarkClusterStrategy strategy2 = _strategyFactory.get(DARK_CLUSTER_NAME2);
    Assert.assertTrue(strategy2 instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy2).getMultiplier(), 0.1f, "expected 0.1f multiplier");
    // update the clusterInfoProvider, and refresh the strategyMap
    _clusterInfoProvider.removeDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME2);
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy3 = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy3 instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    // there should be no strategy entry for DARK_CLUSTER_NAME2, so it should return the NO_OP strategy
    DarkClusterStrategy strategy4 = _strategyFactory.get(DARK_CLUSTER_NAME2);
    Assert.assertSame(strategy4, NO_OP_DARK_CLUSTER_STRATEGY);
}
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 4 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class TestDarkClusterStrategyFactory method testUpdateStrategyDarkClusterChange.

@Test
public void testUpdateStrategyDarkClusterChange() {
    DarkClusterConfig darkClusterConfig1 = createRelativeTrafficMultiplierConfig(0.5f);
    DarkClusterConfig darkClusterConfig2 = createRelativeTrafficMultiplierConfig(0.1f);
    _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 the strategy.
    _clusterInfoProvider.addDarkClusterConfig(SOURCE_CLUSTER_NAME, DARK_CLUSTER_NAME, darkClusterConfig2);
    // now trigger a refresh on the dark cluster. Note that darkClusterConfig1 is ignored since there should already be an entry for this
    // dark cluster, and we should get the strategy associated with darkClusterConfig2 back.
    _clusterInfoProvider.notifyListenersClusterAdded(SOURCE_CLUSTER_NAME);
    DarkClusterStrategy strategy3 = _strategyFactory.get(DARK_CLUSTER_NAME);
    Assert.assertTrue(strategy3 instanceof RelativeTrafficMultiplierDarkClusterStrategy);
    Assert.assertEquals(((RelativeTrafficMultiplierDarkClusterStrategy) strategy3).getMultiplier(), 0.1f, "expected 0.1f multiplier");
    // if someone has a handle to old strategies, those should still be usable.
    RestRequest dummyRestRequest = new RestRequestBuilder(URI.create("foo")).build();
    strategy.handleRequest(dummyRestRequest, dummyRestRequest, new RequestContext());
}
Also used : RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) RestRequest(com.linkedin.r2.message.rest.RestRequest) DarkClusterConfig(com.linkedin.d2.DarkClusterConfig) NoOpDarkClusterStrategy(com.linkedin.darkcluster.api.NoOpDarkClusterStrategy) RelativeTrafficMultiplierDarkClusterStrategy(com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test)

Example 5 with DarkClusterStrategy

use of com.linkedin.darkcluster.api.DarkClusterStrategy in project rest.li by linkedin.

the class DarkClusterManagerImpl method handleDarkRequest.

@Override
public boolean handleDarkRequest(RestRequest originalRequest, RequestContext originalRequestContext) {
    String uri = originalRequest.getURI().toString();
    boolean darkRequestSent = false;
    try {
        final boolean whiteListed = _whiteListRegEx != null && _whiteListRegEx.matcher(uri).matches();
        final boolean blackedListed = _blackListRegEx != null && _blackListRegEx.matcher(uri).matches();
        // 4) custom dark gatekeeper returns true for the given request and requestContext
        if ((isSafe(originalRequest) || whiteListed) && !blackedListed) {
            // the request is already immutable, and a new requestContext will be created in BaseDarkClusterDispatcher.
            // We don't need to copy them here, but doing it just for safety.
            RestRequest reqCopy = originalRequest.builder().build();
            RequestContext newRequestContext = new RequestContext(originalRequestContext);
            DarkClusterConfigMap configMap = _facilities.getClusterInfoProvider().getDarkClusterConfigMap(_sourceClusterName);
            for (String darkClusterName : configMap.keySet()) {
                if (_darkGateKeeper.shouldDispatchToDark(originalRequest, originalRequestContext, darkClusterName)) {
                    RestRequest newD2Request = rewriteRequest(reqCopy, darkClusterName);
                    // now find the strategy appropriate for each dark cluster
                    DarkClusterStrategy strategy = _darkClusterStrategyFactory.get(darkClusterName);
                    darkRequestSent = strategy.handleRequest(reqCopy, newD2Request, newRequestContext);
                }
            }
        }
    } catch (Throwable e) {
        _notifier.notify(() -> new RuntimeException("DarkCanaryDispatcherFilter failed to send request: " + uri, e));
    }
    return darkRequestSent;
}
Also used : DarkClusterConfigMap(com.linkedin.d2.DarkClusterConfigMap) RestRequest(com.linkedin.r2.message.rest.RestRequest) DarkClusterStrategy(com.linkedin.darkcluster.api.DarkClusterStrategy) RequestContext(com.linkedin.r2.message.RequestContext)

Aggregations

DarkClusterStrategy (com.linkedin.darkcluster.api.DarkClusterStrategy)13 Test (org.testng.annotations.Test)12 NoOpDarkClusterStrategy (com.linkedin.darkcluster.api.NoOpDarkClusterStrategy)11 RelativeTrafficMultiplierDarkClusterStrategy (com.linkedin.darkcluster.impl.RelativeTrafficMultiplierDarkClusterStrategy)10 DarkClusterConfig (com.linkedin.d2.DarkClusterConfig)9 RequestContext (com.linkedin.r2.message.RequestContext)5 RestRequest (com.linkedin.r2.message.rest.RestRequest)5 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)4 DarkClusterStrategyNameArray (com.linkedin.d2.DarkClusterStrategyNameArray)3 DarkClusterConfigMap (com.linkedin.d2.DarkClusterConfigMap)1 Facilities (com.linkedin.d2.balancer.Facilities)1 DarkClusterDispatcher (com.linkedin.darkcluster.api.DarkClusterDispatcher)1 DarkClusterManager (com.linkedin.darkcluster.api.DarkClusterManager)1 DarkClusterStrategyFactory (com.linkedin.darkcluster.api.DarkClusterStrategyFactory)1 DarkRequestHeaderGenerator (com.linkedin.darkcluster.api.DarkRequestHeaderGenerator)1 BaseDarkClusterDispatcherImpl (com.linkedin.darkcluster.impl.BaseDarkClusterDispatcherImpl)1 DarkClusterManagerImpl (com.linkedin.darkcluster.impl.DarkClusterManagerImpl)1 DefaultDarkClusterDispatcher (com.linkedin.darkcluster.impl.DefaultDarkClusterDispatcher)1 IdenticalTrafficMultiplierDarkClusterStrategy (com.linkedin.darkcluster.impl.IdenticalTrafficMultiplierDarkClusterStrategy)1 URI (java.net.URI)1