public async Task Handle_FailedAffinityStatus_ReturnTrue(AffinityStatus status) { var policy = new RedistributeAffinityFailurePolicy(); Assert.Equal(SessionAffinityConstants.FailurePolicies.Redistribute, policy.Name); Assert.True(await policy.Handle(new DefaultHttpContext(), cluster: null, affinityStatus: status)); }
public async Task Handle_SuccessfulAffinityStatus_Throw(AffinityStatus status) { var policy = new RedistributeAffinityFailurePolicy(); var context = new DefaultHttpContext(); await Assert.ThrowsAsync <InvalidOperationException>(() => policy.Handle(context, cluster: null, affinityStatus: status)); }
public async Task Handle_FaultyAffinityStatus_RespondWith503(AffinityStatus status) { var policy = new Return503ErrorAffinityFailurePolicy(); var context = new DefaultHttpContext(); Assert.Equal(SessionAffinityConstants.AffinityFailurePolicies.Return503Error, policy.Name); Assert.False(await policy.Handle(context, default, status));
public Task <bool> Handle(HttpContext context, ClusterState cluster, AffinityStatus affinityStatus) { if (affinityStatus == AffinityStatus.OK || affinityStatus == AffinityStatus.AffinityKeyNotSet) { throw new InvalidOperationException($"{nameof(Return503ErrorAffinityFailurePolicy)} is called to handle a successful request's affinity status {affinityStatus}."); } context.Response.StatusCode = 503; return(TaskUtilities.FalseTask); }
public Task <bool> Handle(HttpContext context, SessionAffinityConfig config, AffinityStatus affinityStatus) { if (affinityStatus == AffinityStatus.OK || affinityStatus == AffinityStatus.AffinityKeyNotSet) { throw new InvalidOperationException($"{nameof(RedistributeAffinityFailurePolicy)} is called to handle a successful request's affinity status {affinityStatus}."); } // Available destinations list have not been changed in the context, // so simply allow processing to proceed to load balancing. return(TaskUtilities.TrueTask); }
public async Task Invoke_SuccessfulFlow_CallNext(AffinityStatus status, string foundDestinationId) { var cluster = GetCluster(); var endpoint = GetEndpoint(cluster); DestinationState foundDestination = null; if (foundDestinationId != null) { cluster.Destinations.TryGetValue(foundDestinationId, out foundDestination); } var invokedMode = string.Empty; const string expectedMode = "Policy-B"; var policies = RegisterAffinityPolicies( true, cluster.Destinations.Values.ToList(), ("Policy-A", AffinityStatus.DestinationNotFound, (DestinationState)null, (Action <ISessionAffinityPolicy>)(p => throw new InvalidOperationException($"Policy {p.Name} call is not expected."))), (expectedMode, status, foundDestination, p => invokedMode = p.Name)); var nextInvoked = false; var middleware = new SessionAffinityMiddleware(c => { nextInvoked = true; return(Task.CompletedTask); }, policies.Select(p => p.Object), new IAffinityFailurePolicy[0], new Mock <ILogger <SessionAffinityMiddleware> >().Object); var context = new DefaultHttpContext(); context.SetEndpoint(endpoint); var destinationFeature = GetReverseProxyFeature(cluster); context.Features.Set(destinationFeature); await middleware.Invoke(context); Assert.Equal(expectedMode, invokedMode); Assert.True(nextInvoked); policies[0].VerifyGet(p => p.Name, Times.Once); policies[0].VerifyNoOtherCalls(); policies[1].VerifyAll(); if (foundDestinationId != null) { Assert.Equal(1, destinationFeature.AvailableDestinations.Count); Assert.Equal(foundDestinationId, destinationFeature.AvailableDestinations[0].DestinationId); } else { Assert.True(cluster.Destinations.Values.SequenceEqual(destinationFeature.AvailableDestinations)); } }
public async Task Invoke_SuccessfulFlow_CallNext(AffinityStatus status, string foundDestinationId) { var cluster = GetCluster(); var foundDestinations = foundDestinationId != null?Destinations.Where(d => d.DestinationId == foundDestinationId).ToArray() : null; var invokedMode = string.Empty; const string expectedMode = "Mode-B"; var providers = RegisterAffinityProviders( true, Destinations, cluster.ClusterId, ("Mode-A", AffinityStatus.DestinationNotFound, (RuntimeModel.DestinationInfo[])null, (Action <ISessionAffinityProvider>)(p => throw new InvalidOperationException($"Provider {p.Mode} call is not expected."))), (expectedMode, status, foundDestinations, p => invokedMode = p.Mode)); var nextInvoked = false; var middleware = new AffinitizedDestinationLookupMiddleware(c => { nextInvoked = true; return(Task.CompletedTask); }, providers.Select(p => p.Object), new IAffinityFailurePolicy[0], GetOperationLogger(false), new Mock <ILogger <AffinitizedDestinationLookupMiddleware> >().Object); var context = new DefaultHttpContext(); context.Features.Set(cluster); var destinationFeature = GetDestinationsFeature(Destinations); context.Features.Set(destinationFeature); await middleware.Invoke(context); Assert.Equal(expectedMode, invokedMode); Assert.True(nextInvoked); providers[0].VerifyGet(p => p.Mode, Times.Once); providers[0].VerifyNoOtherCalls(); providers[1].VerifyAll(); if (foundDestinationId != null) { Assert.Equal(1, destinationFeature.Destinations.Count); Assert.Equal(foundDestinationId, destinationFeature.Destinations[0].DestinationId); } else { Assert.Same(Destinations, destinationFeature.Destinations); } }
public async Task Invoke_ErrorFlow_CallFailurePolicy(AffinityStatus affinityStatus, bool keepProcessing) { var cluster = GetCluster(); var providers = RegisterAffinityProviders(true, Destinations, cluster.ClusterId, ("Mode-B", affinityStatus, null, _ => { })); var invokedPolicy = string.Empty; const string expectedPolicy = "Policy-1"; var failurePolicies = RegisterFailurePolicies( affinityStatus, ("Policy-0", false, p => throw new InvalidOperationException($"Policy {p.Name} call is not expected.")), (expectedPolicy, keepProcessing, p => invokedPolicy = p.Name)); var nextInvoked = false; var logger = AffinityTestHelper.GetLogger <AffinitizedDestinationLookupMiddleware>(); var middleware = new AffinitizedDestinationLookupMiddleware(c => { nextInvoked = true; return(Task.CompletedTask); }, providers.Select(p => p.Object), failurePolicies.Select(p => p.Object), GetOperationLogger(true), logger.Object); var context = new DefaultHttpContext(); context.Features.Set(cluster); var destinationFeature = GetDestinationsFeature(Destinations); context.Features.Set(destinationFeature); await middleware.Invoke(context); Assert.Equal(expectedPolicy, invokedPolicy); Assert.Equal(keepProcessing, nextInvoked); failurePolicies[0].VerifyGet(p => p.Name, Times.Once); failurePolicies[0].VerifyNoOtherCalls(); failurePolicies[1].VerifyAll(); if (!keepProcessing) { logger.Verify( l => l.Log(LogLevel.Warning, EventIds.AffinityResolutionFailedForCluster, It.IsAny <It.IsAnyType>(), null, (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Once); } }
public void Request_FindAffinitizedDestinations( HttpContext context, DestinationState[] allDestinations, AffinityStatus expectedStatus, DestinationState expectedDestination, byte[] expectedEncryptedKey, bool unprotectCalled, LogLevel?expectedLogLevel, EventId expectedEventId) { var dataProtector = GetDataProtector(); var logger = AffinityTestHelper.GetLogger <BaseSessionAffinityPolicy <string> >(); var provider = new ProviderStub(dataProtector.Object, logger.Object); var cluster = new ClusterState("cluster"); var affinityResult = provider.FindAffinitizedDestinations(context, cluster, _defaultOptions, allDestinations); if (unprotectCalled) { dataProtector.Verify(p => p.Unprotect(It.Is <byte[]>(b => b.SequenceEqual(expectedEncryptedKey))), Times.Once); } Assert.Equal(expectedStatus, affinityResult.Status); Assert.Same(expectedDestination, affinityResult.Destinations?.FirstOrDefault()); if (expectedLogLevel != null) { logger.Verify( l => l.Log(expectedLogLevel.Value, expectedEventId, It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Once); } if (expectedDestination != null) { Assert.Equal(1, affinityResult.Destinations.Count); } else { Assert.Null(affinityResult.Destinations); } }
public Task <bool> Handle(HttpContext context, ClusterConfig.ClusterSessionAffinityOptions options, AffinityStatus affinityStatus) { if (affinityStatus == AffinityStatus.OK || affinityStatus == AffinityStatus.AffinityKeyNotSet) { throw new InvalidOperationException($"{nameof(Return503ErrorAffinityFailurePolicy)} is called to handle a successful request's affinity status {affinityStatus}."); } context.Response.StatusCode = 503; return(Task.FromResult(false)); }
public AffinityResult(IReadOnlyList <DestinationState>?destinations, AffinityStatus status) { Destinations = destinations; Status = status; }