/// <summary>
 /// Initializes a new instance of the <see cref="ActionSelectionContext"/> class.
 /// </summary>
 /// <param name="httpContext">The current <see cref="HttpContext">HTTP context</see>.</param>
 /// <param name="matchingActions">The <see cref="IReadOnlyList{T}">read-only list</see> of <see cref="ActionDescriptor">actions</see> matching the current route.</param>
 /// <param name="requestedVersion">The currently requested <see cref="ApiVersion"/>. This parameter can be <c>null</c>.</param>
 public ActionSelectionContext(HttpContext httpContext, IReadOnlyList <ActionDescriptor> matchingActions, ApiVersion?requestedVersion)
 {
     allVersions      = new Lazy <ApiVersionModel>(CreateAggregatedModel);
     HttpContext      = httpContext;
     MatchingActions  = matchingActions;
     RequestedVersion = requestedVersion;
 }
        /// <summary>
        /// Verifies the requested API version is not ambiguous.
        /// </summary>
        /// <param name="context">The current <see cref="RouteContext">route context</see>.</param>
        /// <param name="apiVersion">The requested <see cref="ApiVersion">API version</see> or <c>null</c>.</param>
        /// <returns>True if the requested API version is ambiguous; otherwise, false.</returns>
        /// <remarks>This method will also change the <see cref="RouteContext.Handler"/> to an appropriate
        /// error response if the API version is ambiguous.</remarks>
        protected virtual bool IsRequestedApiVersionAmbiguous(RouteContext context, out ApiVersion?apiVersion)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var httpContext = context.HttpContext;

            try
            {
                apiVersion = httpContext.GetRequestedApiVersion();
            }
            catch (AmbiguousApiVersionException ex)
            {
                Logger.LogInformation(ex.Message);
                apiVersion = default;

                var handlerContext = new RequestHandlerContext(Options.ErrorResponses)
                {
                    Code    = AmbiguousApiVersion,
                    Message = ex.Message,
                };

                context.SetHandlerOrEndpoint(new BadRequestHandler(handlerContext));
                return(true);
            }

            return(false);
        }
Exemplo n.º 3
0
 public AnomalyDetectorRestClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri endpoint, ApiVersion?apiVersion = null)
 {
     ClientDiagnostics = clientDiagnostics ?? throw new ArgumentNullException(nameof(clientDiagnostics));
     _pipeline         = pipeline ?? throw new ArgumentNullException(nameof(pipeline));
     _endpoint         = endpoint ?? throw new ArgumentNullException(nameof(endpoint));
     _apiVersion       = apiVersion ?? ApiVersion.V11Preview1;
 }
        /// <summary>
        /// Verifies the requested API version is not ambiguous.
        /// </summary>
        /// <param name="context">The current <see cref="RouteContext">route context</see>.</param>
        /// <param name="apiVersion">The requested <see cref="ApiVersion">API version</see> or <c>null</c>.</param>
        /// <returns>True if the requested API version is ambiguous; otherwise, false.</returns>
        /// <remarks>This method will also change the <see cref="RouteContext.Handler"/> to an appropriate
        /// error response if the API version is ambiguous.</remarks>
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        protected virtual bool IsRequestedApiVersionAmbiguous(RouteContext context, out ApiVersion?apiVersion)
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var httpContext = context.HttpContext;

            try
            {
                apiVersion = httpContext.GetRequestedApiVersion();
            }
            catch (AmbiguousApiVersionException ex)
            {
                Logger.LogInformation(ex.Message);
                apiVersion = default;

                var handlerContext = new RequestHandlerContext(Options.ErrorResponses)
                {
                    Code    = AmbiguousApiVersion,
                    Message = ex.Message,
                };

                context.Handler = new BadRequestHandler(handlerContext);
                return(true);
            }

            return(false);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns a value indicating whether the provided action maps to the specified API version.
        /// </summary>
        /// <param name="action">The <see cref="HttpActionDescriptor">action</see> to evaluate.</param>
        /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to test the mapping for.</param>
        /// <returns>One of the <see cref="ApiVersionMapping"/> values.</returns>
        public static ApiVersionMapping MappingTo(this HttpActionDescriptor action, ApiVersion?apiVersion)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var model = action.GetApiVersionModel();

            if (model.IsApiVersionNeutral || (apiVersion != null && model.DeclaredApiVersions.Contains(apiVersion)))
            {
                return(Explicit);
            }
            else if (model.DeclaredApiVersions.Count == 0)
            {
                model = action.ControllerDescriptor.GetApiVersionModel();

                if (apiVersion != null && model.DeclaredApiVersions.Contains(apiVersion))
                {
                    return(Implicit);
                }
            }

            return(None);
        }
Exemplo n.º 6
0
 public AnomalyDetectorRestClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri endpoint, ApiVersion?apiVersion = default)
 {
     this.endpoint      = endpoint ?? throw new ArgumentNullException(nameof(endpoint));
     this.apiVersion    = apiVersion ?? ApiVersion.V11Preview1;
     _clientDiagnostics = clientDiagnostics;
     _pipeline          = pipeline;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ActionSelectionContext"/> class.
        /// </summary>
        /// <param name="httpContext">The current <see cref="HttpContext">HTTP context</see>.</param>
        /// <param name="matchingActions">The <see cref="IReadOnlyList{T}">read-only list</see> of <see cref="ActionDescriptor">actions</see> matching the current route.</param>
        /// <param name="requestedVersion">The currently requested <see cref="ApiVersion"/>. This parameter can be <c>null</c>.</param>
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        public ActionSelectionContext(HttpContext httpContext, IReadOnlyList <ActionDescriptor> matchingActions, ApiVersion?requestedVersion)
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        {
            allVersions      = new Lazy <ApiVersionModel>(CreateAggregatedModel);
            HttpContext      = httpContext;
            MatchingActions  = matchingActions;
            RequestedVersion = requestedVersion;
        }
        internal HttpResponseMessage?CreateBadRequestResponse(ApiVersion?requestedVersion)
        {
            var response = requestedVersion == null?
                           CreateBadRequestForUnspecifiedApiVersionOrInvalidApiVersion(versionNeutral : false) :
                               CreateBadRequestForUnsupportedApiVersion(requestedVersion);

            if (response != null)
            {
                ApiVersionReporter.Report(response.Headers, allApiVersions);
            }

            return(response);
        }
Exemplo n.º 9
0
        public AnomalyDetectorClient(Uri endpoint, AzureKeyCredential credential, ApiVersion?apiVersion = default, AnomalyDetectorClientOptions options = null)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            if (credential == null)
            {
                throw new ArgumentNullException(nameof(credential));
            }
            apiVersion ??= ApiVersion.V11Preview1;

            options ??= new AnomalyDetectorClientOptions();
            _clientDiagnostics = new ClientDiagnostics(options);
            _pipeline          = HttpPipelineBuilder.Build(options, new AzureKeyCredentialPolicy(credential, "Ocp-Apim-Subscription-Key"));
            RestClient         = new AnomalyDetectorRestClient(_clientDiagnostics, _pipeline, endpoint, apiVersion);
        }
Exemplo n.º 10
0
        public AnomalyDetectorClient(Uri endpoint, TokenCredential credential, ApiVersion?apiVersion = default, AnomalyDetectorClientOptions options = null)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException(nameof(endpoint));
            }
            if (credential == null)
            {
                throw new ArgumentNullException(nameof(credential));
            }
            apiVersion ??= ApiVersion.V11Preview1;

            options ??= new AnomalyDetectorClientOptions();
            _clientDiagnostics = new ClientDiagnostics(options);
            string[] scopes = { "https://cognitiveservices.azure.com/.default" };
            _pipeline  = HttpPipelineBuilder.Build(options, new BearerTokenAuthenticationPolicy(credential, scopes));
            RestClient = new AnomalyDetectorRestClient(_clientDiagnostics, _pipeline, endpoint, apiVersion);
        }
Exemplo n.º 11
0
        internal bool TryGetApiVersionForType(Type type, out ApiVersion?apiVersion)
        {
            foreach (var(version, manifest) in _versions)
            {
                foreach (var(_, value) in manifest)
                {
                    if (value != type)
                    {
                        continue;
                    }
                    apiVersion = version;
                    return(true);
                }
            }

            apiVersion = default;
            return(false);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Returns a value indicating whether the provided action maps to the specified API version.
        /// </summary>
        /// <param name="action">The <see cref="ActionDescriptor">action</see> to evaluate.</param>
        /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to test the mapping for.</param>
        /// <returns>One of the <see cref="ApiVersionMapping"/> values.</returns>
        public static ApiVersionMapping MappingTo(this ActionDescriptor action, ApiVersion?apiVersion)
        {
            var model = action.GetApiVersionModel();

            if (model.IsApiVersionNeutral || (apiVersion != null && model.DeclaredApiVersions.Contains(apiVersion)))
            {
                return(Explicit);
            }
            else if (model.DeclaredApiVersions.Count == 0)
            {
                var parentModel = action.GetProperty <ControllerModel>()?.GetProperty <ApiVersionModel>();

                if (parentModel != null && (apiVersion != null && parentModel.DeclaredApiVersions.Contains(apiVersion)))
                {
                    return(Implicit);
                }
            }

            return(None);
        }
        /// <summary>
        /// Returns a value indicating whether the provided action maps to the specified API version.
        /// </summary>
        /// <param name="action">The <see cref="HttpActionDescriptor">action</see> to evaluate.</param>
        /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to test the mapping for.</param>
        /// <returns>One of the <see cref="ApiVersionMapping"/> values.</returns>
        public static ApiVersionMapping MappingTo(this HttpActionDescriptor action, ApiVersion?apiVersion)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var model = action.GetApiVersionModel();

            if (model.IsApiVersionNeutral)
            {
                return(Explicit);
            }

            if (apiVersion is null)
            {
                return(None);
            }

            var mappedWithImplementation = model.DeclaredApiVersions.Contains(apiVersion) &&
                                           model.ImplementedApiVersions.Contains(apiVersion);

            if (mappedWithImplementation)
            {
                return(Explicit);
            }

            var deriveFromParent = model.DeclaredApiVersions.Count == 0;

            if (deriveFromParent)
            {
                model = action.ControllerDescriptor.GetApiVersionModel();

                if (model.DeclaredApiVersions.Contains(apiVersion))
                {
                    return(Implicit);
                }
            }

            return(None);
        }
        /// <summary>
        /// Returns a value indicating whether the provided action maps to the specified API version.
        /// </summary>
        /// <param name="action">The <see cref="ActionDescriptor">action</see> to evaluate.</param>
        /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to test the mapping for.</param>
        /// <returns>One of the <see cref="ApiVersionMapping"/> values.</returns>
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        public static ApiVersionMapping MappingTo(this ActionDescriptor action, ApiVersion?apiVersion)
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        {
            var model = action.GetApiVersionModel();

            if (model.IsApiVersionNeutral || (apiVersion != null && model.DeclaredApiVersions.Contains(apiVersion)))
            {
                return(Explicit);
            }
            else if (model.DeclaredApiVersions.Count == 0)
            {
                var parentModel = action.GetProperty <ControllerModel>()?.GetProperty <ApiVersionModel>();

                if (parentModel != null && (apiVersion != null && parentModel.DeclaredApiVersions.Contains(apiVersion)))
                {
                    return(Implicit);
                }
            }

            return(None);
        }
        static bool MatchesApiVersion(CandidateSet candidates, ApiVersion?apiVersion)
        {
            var bestMatches     = new List <int>();
            var implicitMatches = new List <int>();

            for (var i = 0; i < candidates.Count; i++)
            {
                if (!candidates.IsValidCandidate(i))
                {
                    continue;
                }

                ref var candidate = ref candidates[i];
                var     action    = candidate.Endpoint.Metadata.GetMetadata <ActionDescriptor>();

                if (action == null)
                {
                    continue;
                }

                // remember whether the candidate is currently valid. a matching api version will not
                // make the candidate valid; however, we want to short-circuit with 400 if no candidates
                // match the api version at all.
                switch (action.MappingTo(apiVersion))
                {
                case Explicit:
                    bestMatches.Add(i);
                    break;

                case Implicit:
                    implicitMatches.Add(i);
                    break;
                }

                // perf: always make the candidate invalid so we only need to loop through the
                // final, best matches for any remaining candidates
                candidates.SetValidity(i, false);
            }
Exemplo n.º 16
0
        bool IsRequestedApiVersionAmbiguous(HttpContext httpContext, out ApiVersion?apiVersion)
        {
            try
            {
                apiVersion = httpContext.GetRequestedApiVersion();
            }
            catch (AmbiguousApiVersionException ex)
            {
                Logger.LogInformation(ex.Message);
                apiVersion = default;

                var handlerContext = new RequestHandlerContext(Options.ErrorResponses)
                {
                    Code    = AmbiguousApiVersion,
                    Message = ex.Message,
                };

                httpContext.SetEndpoint(new BadRequestHandler(handlerContext));
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Returns a value indicating whether the provided action maps to the specified API version.
        /// </summary>
        /// <param name="action">The <see cref="ActionDescriptor">action</see> to evaluate.</param>
        /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to test the mapping for.</param>
        /// <returns>One of the <see cref="ApiVersionMapping"/> values.</returns>
        public static ApiVersionMapping MappingTo(this ActionDescriptor action, ApiVersion?apiVersion)
        {
            var model = action.GetApiVersionModel();

            if (model.IsApiVersionNeutral)
            {
                return(Explicit);
            }

            if (apiVersion is null)
            {
                return(None);
            }

            var mappedWithImplementation = model.DeclaredApiVersions.Contains(apiVersion) &&
                                           model.ImplementedApiVersions.Contains(apiVersion);

            if (mappedWithImplementation)
            {
                return(Explicit);
            }

            var deriveFromParent = model.DeclaredApiVersions.Count == 0;

            if (deriveFromParent)
            {
                model = action.GetProperty <ControllerModel>()?.GetProperty <ApiVersionModel>();

                if (model is not null && model.DeclaredApiVersions.Contains(apiVersion))
                {
                    return(Implicit);
                }
            }

            return(None);
        }
Exemplo n.º 18
0
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
        public static bool TryParse(string?text, out ApiVersion?version)
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
#endif
        {
            version = null;

            if (IsNullOrEmpty(text))
            {
                return(false);
            }

            var match = Match(text, ParsePattern, Singleline);

            if (!match.Success)
            {
                return(false);
            }

            var status = default(string);

            if (match.Groups[4].Success)
            {
                status = match.Groups[4].Value;

                if (!IsNullOrEmpty(status) && !IsValidStatus(status))
                {
                    return(false);
                }
            }

            var culture = InvariantCulture;
            var group   = default(DateTime? );
            var major   = default(int?);
            var minor   = default(int?);

            if (match.Groups[1].Success)
            {
                if (!TryParseExact(match.Groups[1].Value, GroupVersionFormat, culture, DateTimeStyles.None, out var temp))
                {
                    return(false);
                }

                group = temp;
            }

            var matchGroup = match.Groups[2];

            if (matchGroup.Success && matchGroup.Length > 0)
            {
                major = int.Parse(matchGroup.Value, culture);
            }

            matchGroup = match.Groups[3];

            if (matchGroup.Success && matchGroup.Length > 0)
            {
                minor = int.Parse(matchGroup.Value, culture);
            }

            if (group == null && major == null && minor == null)
            {
                return(false);
            }

            version = new ApiVersion(group, major, minor, status);
            return(true);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Attempts to parse the specified text into an API version.
        /// </summary>
        /// <param name="text">The text to parse.</param>
        /// <param name="version">The parsed <see cref="ApiVersion">API version</see>, if the operation is successful.</param>
        /// <returns>True if the operation succeeded; otherwise false.</returns>
#if NETAPPCORE3_1
        public static bool TryParse(string text, [NotNullWhen(true)] out ApiVersion?version)
 /// <inheritdoc />
 public virtual IEdmModel?SelectModel(ApiVersion?apiVersion) =>
 apiVersion != null && Models.TryGetValue(apiVersion, out var model) ? model : default;
 /// <summary>
 /// Returns a value indicating whether the provided action maps to the specified API version.
 /// </summary>
 /// <param name="action">The <see cref="ActionDescriptor">action</see> to evaluate.</param>
 /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to test the mapping for.</param>
 /// <returns>True if the <paramref name="action"/> explicitly or implicitly maps to the specified
 /// <paramref name="apiVersion">API version</paramref>; otherwise, false.</returns>
 public static bool IsMappedTo(this ActionDescriptor action, ApiVersion?apiVersion) => action.MappingTo(apiVersion) > None;
        /// <summary>
        /// Returns a value indicating whether the specified controller should be mapped using attribute routing conventions.
        /// </summary>
        /// <param name="controller">The <see cref="HttpControllerDescriptor">controller descriptor</see> to evaluate.</param>
        /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to evaluate.</param>
        /// <returns>True if the <paramref name="controller"/> should be mapped as an OData controller; otherwise, false.</returns>
        /// <remarks>The default implementation always returns <c>true</c>.</remarks>
        public virtual bool ShouldMapController(HttpControllerDescriptor controller, ApiVersion?apiVersion)
        {
            var model = controller.GetApiVersionModel();

            return(model.IsApiVersionNeutral || model.DeclaredApiVersions.Contains(apiVersion));
        }
 internal HttpResponseException CreateBadRequest(ApiVersion?requestedVersion) => new HttpResponseException(CreateBadRequestResponse(requestedVersion));
Exemplo n.º 24
0
        protected static ICollection <HttpControllerDescriptor> SelectBestCandidates(IReadOnlyList <CandidateAction> candidates, ApiVersion?apiVersion)
        {
            var bestMatch       = default(HttpActionDescriptor);
            var bestMatches     = new HashSet <HttpControllerDescriptor>();
            var implicitMatches = new HashSet <HttpControllerDescriptor>();

            for (var i = 0; i < candidates.Count; i++)
            {
                var action = candidates[i].ActionDescriptor;

                switch (action.MappingTo(apiVersion))
                {
                case Explicit:
                    bestMatch = action;
                    bestMatches.Add(action.ControllerDescriptor);
                    break;

                case Implicit:
                    implicitMatches.Add(action.ControllerDescriptor);
                    break;
                }
            }

            switch (bestMatches.Count)
            {
            case 0:
                bestMatches.UnionWith(implicitMatches);
                break;

            case 1:
                if (bestMatch !.GetApiVersionModel().IsApiVersionNeutral)
                {
                    bestMatches.UnionWith(implicitMatches);
                }

                break;
            }

            return(bestMatches);
        }
Exemplo n.º 25
0
        public static bool TryParse(string?text, out ApiVersion?version)
#endif
        {
            version = null;

            if (IsNullOrEmpty(text))
            {
                return(false);
            }

            var match = Match(text, ParsePattern, Singleline);

            if (!match.Success)
            {
                return(false);
            }

            var status = default(string);

            if (match.Groups[4].Success)
            {
                status = match.Groups[4].Value;

                if (!IsNullOrEmpty(status) && !IsValidStatus(status))
                {
                    return(false);
                }
            }

            var culture = InvariantCulture;
            var group   = default(DateTime? );
            var major   = default(int?);
            var minor   = default(int?);

            if (match.Groups[1].Success)
            {
                if (!TryParseExact(match.Groups[1].Value, GroupVersionFormat, culture, DateTimeStyles.None, out var temp))
                {
                    return(false);
                }

                group = temp;
            }

            var matchGroup = match.Groups[2];

            if (matchGroup.Success && matchGroup.Length > 0)
            {
                major = int.Parse(matchGroup.Value, culture);
            }

            matchGroup = match.Groups[3];

            if (matchGroup.Success && matchGroup.Length > 0)
            {
                minor = int.Parse(matchGroup.Value, culture);
            }

            if (group == null && major == null && minor == null)
            {
                return(false);
            }

            version = new ApiVersion(group, major, minor, status);
            return(true);
        }
 public ApiConfig(ApiKey apiKey, string game, string protocol, string host, int?port, ApiVersion?version)
 {
     this.ApiKey   = apiKey;
     this.Game     = game;
     this.Protocol = protocol ?? DEFAULT_PROTOCOL;
     this.Host     = host;
     this.Port     = port == null ? DEFAULT_PORT : (int)port;
     this.Version  = version == null ? CURRENT_VERSION : (ApiVersion)version;
 }
Exemplo n.º 27
0
 internal static void ApiVersionUnspecified(this ILogger logger, ApiVersion?apiVersion, string actionNames) => apiVersionUnspecifiedWithDefaultVersion(logger, apiVersion, actionNames, null);
 /// <summary>
 /// Returns a value indicating whether the specified action should be mapped using attribute routing conventions.
 /// </summary>
 /// <param name="action">The <see cref="ControllerActionDescriptor">controller action descriptor</see> to evaluate.</param>
 /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> to evaluate.</param>
 /// <returns>True if the <paramref name="action"/> should be mapped as an OData action or function; otherwise, false.</returns>
 /// <remarks>This method will match any OData action that explicitly or implicitly matches the API version applied
 /// to the associated <see cref="ApiVersionModel">model</see>.</remarks>
 public virtual bool ShouldMapAction(ControllerActionDescriptor action, ApiVersion?apiVersion) => action.IsMappedTo(apiVersion);
Exemplo n.º 29
0
 internal static void ApiVersionUnmatched(this ILogger logger, ApiVersion?apiVersion, string actionNames) => apiVersionUnmatched(logger, apiVersion, actionNames, null);
Exemplo n.º 30
0
 internal AnomalyDetectorClient(ClientDiagnostics clientDiagnostics, HttpPipeline pipeline, Uri endpoint, ApiVersion?apiVersion = default)
 {
     RestClient         = new AnomalyDetectorRestClient(clientDiagnostics, pipeline, endpoint, apiVersion);
     _clientDiagnostics = clientDiagnostics;
     _pipeline          = pipeline;
 }