Ejemplo n.º 1
0
    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));
    }
Ejemplo n.º 2
0
    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));
    }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 6
0
    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);
        }
    }
Ejemplo n.º 10
0
        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));
        }
Ejemplo n.º 11
0
 public AffinityResult(IReadOnlyList <DestinationState>?destinations, AffinityStatus status)
 {
     Destinations = destinations;
     Status       = status;
 }