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");
}
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);
}
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);
}
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());
}
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;
}
Aggregations