Esempio n. 1
0
        public void FindAffinitizedDestination_AffinityDisabledOnBackend_ReturnsAffinityDisabled()
        {
            var provider = new ProviderStub(GetDataProtector().Object, AffinityTestHelper.GetLogger <BaseSessionAffinityProvider <string> >().Object);
            var options  = new BackendConfig.BackendSessionAffinityOptions(false, _defaultOptions.Mode, _defaultOptions.AffinityFailurePolicy, _defaultOptions.Settings);

            Assert.Throws <InvalidOperationException>(() => provider.FindAffinitizedDestinations(new DefaultHttpContext(), new[] { new DestinationInfo("1") }, "backend-1", options));
        }
        public Task <bool> Handle(HttpContext context, BackendConfig.BackendSessionAffinityOptions 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));
        }
Esempio n. 3
0
        public Task <bool> Handle(HttpContext context, BackendConfig.BackendSessionAffinityOptions options, 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(Task.FromResult(true));
        }
Esempio n. 4
0
        private async Task InvokeInternal(HttpContext context, BackendConfig.BackendSessionAffinityOptions options, BackendInfo backend)
        {
            var destinationsFeature = context.GetRequiredDestinationFeature();
            var destinations        = destinationsFeature.Destinations;

            var affinityResult = _operationLogger.Execute(
                "ReverseProxy.FindAffinitizedDestinations",
                () =>
            {
                var currentProvider = _sessionAffinityProviders.GetRequiredServiceById(options.Mode);
                return(currentProvider.FindAffinitizedDestinations(context, destinations, backend.BackendId, options));
            });

            switch (affinityResult.Status)
            {
            case AffinityStatus.OK:
                destinationsFeature.Destinations = affinityResult.Destinations;
                break;

            case AffinityStatus.AffinityKeyNotSet:
                // Nothing to do so just continue processing
                break;

            case AffinityStatus.AffinityKeyExtractionFailed:
            case AffinityStatus.DestinationNotFound:
                var keepProcessing = await _operationLogger.ExecuteAsync("ReverseProxy.HandleAffinityFailure", () =>
                {
                    var failurePolicy = _affinityFailurePolicies.GetRequiredServiceById(options.AffinityFailurePolicy);
                    return(failurePolicy.Handle(context, options, affinityResult.Status));
                });

                if (!keepProcessing)
                {
                    // Policy reported the failure is unrecoverable and took the full responsibility for its handling,
                    // so we simply stop processing.
                    Log.AffinityResolutionFailedForBackend(_logger, backend.BackendId);
                    return;
                }

                Log.AffinityResolutionFailureWasHandledProcessingWillBeContinued(_logger, backend.BackendId, options.AffinityFailurePolicy);

                break;

            default:
                throw new NotSupportedException($"Affinity status '{affinityResult.Status}' is not supported.");
            }

            await _next(context);
        }
        public void FindAffinitizedDestination_CustomHeaderNameIsNotSpecified_UseDefaultName(Dictionary <string, string> settings)
        {
            var options  = new BackendConfig.BackendSessionAffinityOptions(true, "CustomHeader", "Return503", settings);
            var provider = new CustomHeaderSessionAffinityProvider(AffinityTestHelper.GetDataProtector().Object, AffinityTestHelper.GetLogger <CustomHeaderSessionAffinityProvider>().Object);
            var context  = new DefaultHttpContext();
            var affinitizedDestination = _destinations[1];

            context.Request.Headers[CustomHeaderSessionAffinityProvider.DefaultCustomHeaderName] = new[] { affinitizedDestination.DestinationId.ToUTF8BytesInBase64() };

            var affinityResult = provider.FindAffinitizedDestinations(context, _destinations, "backend-1", options);

            Assert.Equal(AffinityStatus.OK, affinityResult.Status);
            Assert.Equal(1, affinityResult.Destinations.Count);
            Assert.Same(affinitizedDestination, affinityResult.Destinations[0]);
        }
        private void AffinitizeRequest(HttpContext context, BackendConfig.BackendSessionAffinityOptions options, DestinationInfo destination)
        {
            var currentProvider = _sessionAffinityProviders.GetRequiredServiceById(options.Mode);

            currentProvider.AffinitizeRequest(context, options, destination);
        }