diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Constants.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Constants.cs index 48ae551..1301013 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Constants.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Constants.cs @@ -22,4 +22,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols /// public const int CloseConnectionMessageType = 11; } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/IServerlessProtocol.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/IServerlessProtocol.cs index 93fc391..8819ed6 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/IServerlessProtocol.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/IServerlessProtocol.cs @@ -1,10 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.Buffers; -using System.Collections.Generic; -using System.Text; namespace Microsoft.Azure.SignalR.Serverless.Protocols { @@ -24,4 +21,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols /// A value that is true if the was successfully parsed; otherwise, false. bool TryParseMessage(ref ReadOnlySequence input, out ServerlessMessage message); } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MemoryBufferWriter.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MemoryBufferWriter.cs index e7dcf11..ba3c5ee 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MemoryBufferWriter.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MemoryBufferWriter.cs @@ -39,6 +39,7 @@ namespace Microsoft.AspNetCore.Internal public override bool CanRead => false; public override bool CanSeek => false; public override bool CanWrite => true; + public override long Position { get => throw new NotSupportedException(); @@ -258,10 +259,16 @@ namespace Microsoft.AspNetCore.Internal Debug.Assert(_bytesWritten == totalWritten + _position); } - public override void Flush() { } + public override void Flush() + { + } + public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask; + public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException(); + public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); + public override void SetLength(long value) => throw new NotSupportedException(); public override void WriteByte(byte value) @@ -341,4 +348,4 @@ namespace Microsoft.AspNetCore.Internal } } } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MessagePackHelper.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MessagePackHelper.cs index b37ce92..f1e72c7 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MessagePackHelper.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/MessagePackHelper.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using MessagePack; namespace Microsoft.Azure.SignalR.Serverless.Protocols @@ -187,4 +186,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols } } } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/ReadOnlySequenceStream.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/ReadOnlySequenceStream.cs index ed41a6d..4301cd7 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/ReadOnlySequenceStream.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/Internal/ReadOnlySequenceStream.cs @@ -3,9 +3,7 @@ using System; using System.Buffers; -using System.Collections.Generic; using System.IO; -using System.Text; namespace Microsoft.Azure.SignalR.Serverless.Protocols { @@ -99,4 +97,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols } } } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/JsonServerlessProtocol.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/JsonServerlessProtocol.cs index 41b20bc..6b78a0b 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/JsonServerlessProtocol.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/JsonServerlessProtocol.cs @@ -4,7 +4,6 @@ using System; using System.Buffers; using System.IO; -using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -57,4 +56,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols } } } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/MessagePackServerlessProtocol.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/MessagePackServerlessProtocol.cs index aaca50b..8ea62af 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/MessagePackServerlessProtocol.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/MessagePackServerlessProtocol.cs @@ -1,10 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.Buffers; -using System.Collections.Generic; -using System.IO; using MessagePack; @@ -49,4 +46,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols return invocationMessage; } } -} +} \ No newline at end of file diff --git a/src/Microsoft.Azure.SignalR.Serverless.Protocols/ServerlessMessage.cs b/src/Microsoft.Azure.SignalR.Serverless.Protocols/ServerlessMessage.cs index 3ee0147..dcb3807 100644 --- a/src/Microsoft.Azure.SignalR.Serverless.Protocols/ServerlessMessage.cs +++ b/src/Microsoft.Azure.SignalR.Serverless.Protocols/ServerlessMessage.cs @@ -32,4 +32,4 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols [JsonProperty(PropertyName = "error")] public string Error { get; set; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Auth/DefaultSecurityTokenValidator.cs b/src/SignalRServiceExtension/Auth/DefaultSecurityTokenValidator.cs index 57805f0..4438c2d 100644 --- a/src/SignalRServiceExtension/Auth/DefaultSecurityTokenValidator.cs +++ b/src/SignalRServiceExtension/Auth/DefaultSecurityTokenValidator.cs @@ -30,7 +30,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { if (request?.Headers.TryGetValue(AuthHeaderName, out var authHeader) == true) { - var authHeaderValue = authHeader.ToString(); + var authHeaderValue = authHeader.ToString(); if (authHeaderValue.StartsWith(BearerPrefix, StringComparison.OrdinalIgnoreCase)) { var token = authHeaderValue.Substring(BearerPrefix.Length); @@ -59,7 +59,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService // 'nbf' claim is greater than 'exp' claim ex is SecurityTokenInvalidLifetimeException || - // Signature is not properly formatted. + // Signature is not properly formatted. ex is SecurityTokenInvalidSignatureException || // 1. 'exp' claim is missing and TokenValidationParameters.RequireExpirationTime is true. diff --git a/src/SignalRServiceExtension/Auth/SignalRConnectionDetail.cs b/src/SignalRServiceExtension/Auth/SignalRConnectionDetail.cs index 87e6106..42c91b6 100644 --- a/src/SignalRServiceExtension/Auth/SignalRConnectionDetail.cs +++ b/src/SignalRServiceExtension/Auth/SignalRConnectionDetail.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.Collections.Generic; using System.Security.Claims; @@ -16,7 +15,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService /// User identity for a SignalR connection /// public string UserId { get; set; } - + /// /// Custom claims that added to SignalR access token. /// diff --git a/src/SignalRServiceExtension/Bindings/JTokenExtensions.cs b/src/SignalRServiceExtension/Bindings/JTokenExtensions.cs index 1497836..eee15db 100644 --- a/src/SignalRServiceExtension/Bindings/JTokenExtensions.cs +++ b/src/SignalRServiceExtension/Bindings/JTokenExtensions.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using Newtonsoft.Json.Linq; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService diff --git a/src/SignalRServiceExtension/Bindings/SignalRConnectionInfo.cs b/src/SignalRServiceExtension/Bindings/SignalRConnectionInfo.cs index e504315..905b7d7 100644 --- a/src/SignalRServiceExtension/Bindings/SignalRConnectionInfo.cs +++ b/src/SignalRServiceExtension/Bindings/SignalRConnectionInfo.cs @@ -9,6 +9,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { [JsonProperty("url")] public string Url { get; set; } + [JsonProperty("accessToken")] public string AccessToken { get; set; } } diff --git a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/AttributeCloner.cs b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/AttributeCloner.cs index cc6f97c..0ca4aab 100644 --- a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/AttributeCloner.cs +++ b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/AttributeCloner.cs @@ -14,6 +14,7 @@ using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using BindingData = System.Collections.Generic.IReadOnlyDictionary; using BindingDataContract = System.Collections.Generic.IReadOnlyDictionary; + // Func to transform Attribute,BindingData into value for cloned attribute property/constructor arg // Attribute is the new cloned attribute - null if constructor arg (new cloned attr not created yet) using BindingDataResolver = System.Func, object>; @@ -21,6 +22,7 @@ using BindingDataResolver = System.Func; #pragma warning disable CS0618 // Type or member is obsolete + namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { // Clone an attribute and resolve it. @@ -98,7 +100,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService // transforms binding data to appropriate resolver (appsetting, autoresolve, or originalValue) private BindingDataResolver GetResolver(PropertyInfo propInfo, INameResolver nameResolver, BindingDataContract contract) { - // Do the attribute lookups once upfront, and then cache them (via func closures) for subsequent runtime usage. + // Do the attribute lookups once upfront, and then cache them (via func closures) for subsequent runtime usage. object originalValue = propInfo.GetValue(_source); ConnectionStringAttribute connStrAttr = propInfo.GetCustomAttribute(); AppSettingAttribute appSettingAttr = propInfo.GetCustomAttribute(); @@ -109,7 +111,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { validator(originalValue); - // No special attributes, treat as literal. + // No special attributes, treat as literal. return (newAttr, bindingData) => originalValue; } @@ -119,7 +121,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService throw new InvalidOperationException($"Property '{propInfo.Name}' can only be annotated with one of the types {nameof(AppSettingAttribute)}, {nameof(AutoResolveAttribute)}, and {nameof(ConnectionStringAttribute)}."); } - // attributes only work on string properties. + // attributes only work on string properties. if (propInfo.PropertyType != typeof(string)) { throw new InvalidOperationException($"{nameof(ConnectionStringAttribute)}, {nameof(AutoResolveAttribute)}, or {nameof(AppSettingAttribute)} property '{propInfo.Name}' must be of type string."); @@ -144,7 +146,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return GetAutoResolveResolver(str, autoResolveAttr, nameResolver, propInfo, contract, validator); } - // Apply AutoResolve attribute + // Apply AutoResolve attribute internal BindingDataResolver GetAutoResolveResolver(string originalValue, AutoResolveAttribute autoResolveAttr, INameResolver nameResolver, PropertyInfo propInfo, BindingDataContract contract, Validator validator) { if (string.IsNullOrWhiteSpace(originalValue)) @@ -187,19 +189,19 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService throw new InvalidOperationException($"Unable to resolve the value for property '{propInfo.DeclaringType.Name}.{propInfo.Name}'. Make sure the setting exists and has a valid value."); } - // validate after the %% is substituted. + // validate after the %% is substituted. validator(resolvedValue); return (newAttr, bindingData) => resolvedValue; } - // Run validition. This needs to be run at different stages. + // Run validition. This needs to be run at different stages. // In general, run as early as possible. If there are { } tokens, then we can't run until runtime. - // But if there are no { }, we can run statically. + // But if there are no { }, we can run statically. // If there's no [AutoResolve], [AppSettings], then we can run immediately. private static Validator GetValidatorFunc(PropertyInfo propInfo, bool dontLogValues) { - // This implicitly caches the attribute lookup once and then shares for each runtime invocation. + // This implicitly caches the attribute lookup once and then shares for each runtime invocation. var attrs = propInfo.GetCustomAttributes(); return (value) => @@ -225,8 +227,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService }; } - // Resolve for AutoResolve.Default templates. - // These only have access to the {sys} builtin variable and don't get access to trigger binding data. + // Resolve for AutoResolve.Default templates. + // These only have access to the {sys} builtin variable and don't get access to trigger binding data. internal static BindingDataResolver GetBuiltinTemplateResolver(string originalValue, INameResolver nameResolver, Validator validator) { string resolvedValue = nameResolver.ResolveWholeString(originalValue); @@ -234,13 +236,13 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService var template = BindingTemplate.FromString(resolvedValue); if (!template.HasParameters) { - // No { } tokens, bind eagerly up front. + // No { } tokens, bind eagerly up front. validator(originalValue); } SystemBindingData.ValidateStaticContract(template); - // For static default contracts, we only have access to the built in binding data. + // For static default contracts, we only have access to the built in binding data. return (newAttr, bindingData) => { var newValue = template.Bind(SystemBindingData.GetSystemBindingData(bindingData)); @@ -257,7 +259,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService if (!template.HasParameters) { - // No { } tokens, bind eagerly up front. + // No { } tokens, bind eagerly up front. validator(resolvedValue); } @@ -334,7 +336,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { if (bindingData == null) { - // Skip validation if no binding data provided. We can't do the { } substitutions. + // Skip validation if no binding data provided. We can't do the { } substitutions. return template?.Pattern; } @@ -363,7 +365,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService } } - // return the default policy + // return the default policy return new DefaultResolutionPolicy(); } @@ -377,16 +379,16 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService /// Class providing support for built in system binding expressions /// /// - /// It's expected this class is created and added to the binding data. + /// It's expected this class is created and added to the binding data. /// private class SystemBindingData { - // The public name for this binding in the binding expressions. + // The public name for this binding in the binding expressions. public const string Name = "sys"; - // An internal name for this binding that uses characters that gaurantee it can't be overwritten by a user. - // This is never seen by the user. - // This ensures that we can always unambiguously retrieve this later. + // An internal name for this binding that uses characters that gaurantee it can't be overwritten by a user. + // This is never seen by the user. + // This ensures that we can always unambiguously retrieve this later. private const string InternalKeyName = "$sys"; private static readonly IReadOnlyDictionary DefaultSystemContract = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -395,13 +397,13 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService }; /// - /// The method name that the binding lives in. - /// The method name can be override by the + /// The method name that the binding lives in. + /// The method name can be override by the /// public string MethodName { get; set; } /// - /// Get the current UTC date. + /// Get the current UTC date. /// public DateTime UtcNow => DateTime.UtcNow; @@ -411,7 +413,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public Guid RandGuid => Guid.NewGuid(); // Given a full bindingData, create a binding data with just the system object . - // This can be used when resolving default contracts that shouldn't be using an instance binding data. + // This can be used when resolving default contracts that shouldn't be using an instance binding data. internal static IReadOnlyDictionary GetSystemBindingData(IReadOnlyDictionary bindingData) { var data = GetFromData(bindingData); @@ -422,8 +424,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return systemBindingData; } - // Validate that a template only uses static (non-instance) binding variables. - // Enforces we're not referring to other data from the trigger. + // Validate that a template only uses static (non-instance) binding variables. + // Enforces we're not referring to other data from the trigger. internal static void ValidateStaticContract(BindingTemplate template) { try @@ -438,12 +440,12 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService internal void AddToBindingData(Dictionary bindingData) { - // User data takes precedence, so if 'sys' already exists, add via the internal name. + // User data takes precedence, so if 'sys' already exists, add via the internal name. string sysName = bindingData.ContainsKey(SystemBindingData.Name) ? SystemBindingData.InternalKeyName : SystemBindingData.Name; bindingData[sysName] = this; } - // Given per-instance binding data, extract just the system binding data object from it. + // Given per-instance binding data, extract just the system binding data object from it. private static SystemBindingData GetFromData(IReadOnlyDictionary bindingData) { object val; @@ -459,10 +461,10 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService } } - // Helpers for providing default behavior for an IAttributeInvokeDescriptor that - // convert between a TAttribute and a string representation (invoke string). - // Properties with [AutoResolve] are the interesting ones to serialize and deserialize. - // Assume any property without a [AutoResolve] attribute is read-only and so doesn't need to be included in the invoke string. + // Helpers for providing default behavior for an IAttributeInvokeDescriptor that + // convert between a TAttribute and a string representation (invoke string). + // Properties with [AutoResolve] are the interesting ones to serialize and deserialize. + // Assume any property without a [AutoResolve] attribute is read-only and so doesn't need to be included in the invoke string. private static class DefaultAttributeInvokerDescriptor { public static TAttribute FromInvokeString(AttributeCloner cloner, string invokeString) @@ -473,8 +475,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService } // Instantiating new attributes can be tricky since sometimes the arg is to the ctor and sometimes - // its a property setter. AttributeCloner already solves this, so use it here to do the actual attribute instantiation. - // This has an instantiation problem similar to what Attribute Cloner has + // its a property setter. AttributeCloner already solves this, so use it here to do the actual attribute instantiation. + // This has an instantiation problem similar to what Attribute Cloner has if (invokeString[0] == '{') { var propertyValues = JsonConvert.DeserializeObject>(invokeString); @@ -516,9 +518,9 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService } /// - /// Resolution policy for { } in binding templates. - /// The default policy is just a direct substitution for the binding data. - /// Derived policies can enforce formatting / escaping when they do injection. + /// Resolution policy for { } in binding templates. + /// The default policy is just a direct substitution for the binding data. + /// Derived policies can enforce formatting / escaping when they do injection. /// private class DefaultResolutionPolicy : IResolutionPolicy { @@ -529,4 +531,5 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService } } } -#pragma warning restore CS0618 // Type or member is obsolete + +#pragma warning restore CS0618 // Type or member is obsolete \ No newline at end of file diff --git a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/BindingBase.cs b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/BindingBase.cs index 2b298b8..788d86d 100644 --- a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/BindingBase.cs +++ b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/Common/BindingBase.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Threading.Tasks; using Microsoft.Azure.WebJobs.Host.Bindings; using Microsoft.Azure.WebJobs.Host.Protocols; @@ -11,7 +10,7 @@ using Microsoft.Extensions.Configuration; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { - // Helper class for implementing IBinding with the attribute resolver pattern. + // Helper class for implementing IBinding with the attribute resolver pattern. internal abstract class BindingBase : IBinding where TAttribute : Attribute { @@ -51,7 +50,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public Task BindAsync(object value, ValueBindingContext context) { - throw new NotImplementedException(); + throw new NotImplementedException(); } public ParameterDescriptor ToParameterDescriptor() @@ -59,5 +58,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return param; } } -} - +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationInputBinding.cs b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationInputBinding.cs index dba5088..d413036 100644 --- a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationInputBinding.cs +++ b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationInputBinding.cs @@ -1,11 +1,11 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Azure.WebJobs.Host.Bindings; using Microsoft.Azure.WebJobs.Host.Protocols; -using System; -using System.Threading.Tasks; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { @@ -35,7 +35,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return Task.FromResult(new SecurityTokenValidationValueProvider(null, "")); } - return Task.FromResult(new SecurityTokenValidationValueProvider(securityTokenValidator.ValidateToken(request), "")); + return Task.FromResult(new SecurityTokenValidationValueProvider(securityTokenValidator.ValidateToken(request), "")); } public Task BindAsync(BindingContext context) diff --git a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationValueProvider.cs b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationValueProvider.cs index 37d3d10..c52d533 100644 --- a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationValueProvider.cs +++ b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SecurityTokenValidationInputBinding/SecurityTokenValidationValueProvider.cs @@ -15,7 +15,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService // todo: fix invoke string in another PR public SecurityTokenValidationValueProvider(SecurityTokenResult result, string invokeString) { - this.result= result; + this.result = result; this.invokeString = invokeString; } @@ -31,4 +31,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public Type Type => typeof(SecurityTokenResult); } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SignalRConnectionInputBinding/SignalRConnectionInfoValueProvider.cs b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SignalRConnectionInputBinding/SignalRConnectionInfoValueProvider.cs index 186008f..c3a0b3e 100644 --- a/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SignalRConnectionInputBinding/SignalRConnectionInfoValueProvider.cs +++ b/src/SignalRServiceExtension/Bindings/SignalRInputBindings/SignalRConnectionInputBinding/SignalRConnectionInfoValueProvider.cs @@ -47,4 +47,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return info; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Bindings/TypeUtility.cs b/src/SignalRServiceExtension/Bindings/TypeUtility.cs index 9f916d1..955ca26 100644 --- a/src/SignalRServiceExtension/Bindings/TypeUtility.cs +++ b/src/SignalRServiceExtension/Bindings/TypeUtility.cs @@ -2,9 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; using System.Reflection; -using System.Text; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { @@ -83,4 +81,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return null; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Client/AzureSignalRClient.cs b/src/SignalRServiceExtension/Client/AzureSignalRClient.cs index 33db4fc..2d6f0cb 100644 --- a/src/SignalRServiceExtension/Client/AzureSignalRClient.cs +++ b/src/SignalRServiceExtension/Client/AzureSignalRClient.cs @@ -51,10 +51,10 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { var serviceHubContext = await GetHubContextAsync(); var negotiateResponse = await serviceHubContext.NegotiateAsync(new NegotiationOptions() - { - UserId = userId, - Claims = BuildJwtClaims(claims, AzureSignalRUserPrefix).ToList(), - HttpContext = httpContext + { + UserId = userId, + Claims = BuildJwtClaims(claims, AzureSignalRUserPrefix).ToList(), + HttpContext = httpContext }); return new SignalRConnectionInfo { diff --git a/src/SignalRServiceExtension/Client/IAzureSignalRSender.cs b/src/SignalRServiceExtension/Client/IAzureSignalRSender.cs index 9be2fd9..e46af31 100644 --- a/src/SignalRServiceExtension/Client/IAzureSignalRSender.cs +++ b/src/SignalRServiceExtension/Client/IAzureSignalRSender.cs @@ -8,13 +8,21 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService internal interface IAzureSignalRSender { Task SendToAll(SignalRData data); + Task SendToConnection(string connectionId, SignalRData data); + Task SendToUser(string userId, SignalRData data); + Task SendToGroup(string group, SignalRData data); + Task AddUserToGroup(SignalRGroupAction action); + Task RemoveUserFromGroup(SignalRGroupAction action); + Task RemoveUserFromAllGroups(SignalRGroupAction action); + Task AddConnectionToGroup(SignalRGroupAction action); + Task RemoveConnectionFromGroup(SignalRGroupAction action); } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Config/IInternalServiceHubContextStore.cs b/src/SignalRServiceExtension/Config/IInternalServiceHubContextStore.cs index 8252fb6..70d441c 100644 --- a/src/SignalRServiceExtension/Config/IInternalServiceHubContextStore.cs +++ b/src/SignalRServiceExtension/Config/IInternalServiceHubContextStore.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. - using Microsoft.Azure.SignalR; +using Microsoft.Azure.SignalR; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { diff --git a/src/SignalRServiceExtension/Config/OptionsSetup.cs b/src/SignalRServiceExtension/Config/OptionsSetup.cs index 9504549..646129d 100644 --- a/src/SignalRServiceExtension/Config/OptionsSetup.cs +++ b/src/SignalRServiceExtension/Config/OptionsSetup.cs @@ -65,4 +65,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return configuration.GetReloadToken(); } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Config/ServiceHubContextStore.cs b/src/SignalRServiceExtension/Config/ServiceHubContextStore.cs index 78a7234..54ca925 100644 --- a/src/SignalRServiceExtension/Config/ServiceHubContextStore.cs +++ b/src/SignalRServiceExtension/Config/ServiceHubContextStore.cs @@ -27,7 +27,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public ValueTask GetAsync(string hubName) { - var pair = store.GetOrAdd(hubName, + var pair = store.GetOrAdd(hubName, (new Lazy>( () => ServiceManager.CreateHubContextAsync(hubName)), default)); return GetAsyncCore(hubName, pair); diff --git a/src/SignalRServiceExtension/Config/SignalRFunctionsHostBuilderExtensions.cs b/src/SignalRServiceExtension/Config/SignalRFunctionsHostBuilderExtensions.cs index e05b5df..28a56d2 100644 --- a/src/SignalRServiceExtension/Config/SignalRFunctionsHostBuilderExtensions.cs +++ b/src/SignalRServiceExtension/Config/SignalRFunctionsHostBuilderExtensions.cs @@ -1,13 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; +using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.Azure.Functions.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection; -using Microsoft.IdentityModel.Tokens; -using System; -using System.Linq; using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.IdentityModel.Tokens; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { @@ -43,13 +43,13 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { throw new NotSupportedException($"{nameof(ISecurityTokenValidator)} already injected."); } - + builder.Services .AddSingleton(s => new DefaultSecurityTokenValidator(configureTokenValidationParameters)); builder.Services. - TryAddSingleton(s => + TryAddSingleton(s => internalSignalRConnectionInfoConfigurer); return builder; diff --git a/src/SignalRServiceExtension/Config/SignalRWebJobsBuilderExtensions.cs b/src/SignalRServiceExtension/Config/SignalRWebJobsBuilderExtensions.cs index 439acc8..ffa73f2 100644 --- a/src/SignalRServiceExtension/Config/SignalRWebJobsBuilderExtensions.cs +++ b/src/SignalRServiceExtension/Config/SignalRWebJobsBuilderExtensions.cs @@ -2,13 +2,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { // Then all resolve jobs are put in resolvers, we can also remove the SignalROption after we apply resolve jobs inside bindings. - + /// /// Extension methods for SignalR Service integration /// diff --git a/src/SignalRServiceExtension/Config/StaticServiceHubContextStore.cs b/src/SignalRServiceExtension/Config/StaticServiceHubContextStore.cs index f64b471..7f5f5f4 100644 --- a/src/SignalRServiceExtension/Config/StaticServiceHubContextStore.cs +++ b/src/SignalRServiceExtension/Config/StaticServiceHubContextStore.cs @@ -14,4 +14,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService internal static IServiceManagerStore ServiceManagerStore { get; set; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Constants.cs b/src/SignalRServiceExtension/Constants.cs index fde4f80..5261f67 100644 --- a/src/SignalRServiceExtension/Constants.cs +++ b/src/SignalRServiceExtension/Constants.cs @@ -35,4 +35,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public const string Connected = "connected"; public const string Disconnected = "disconnected"; } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/ErrorMessages.cs b/src/SignalRServiceExtension/ErrorMessages.cs index 73a61ca..2d80b4e 100644 --- a/src/SignalRServiceExtension/ErrorMessages.cs +++ b/src/SignalRServiceExtension/ErrorMessages.cs @@ -8,4 +8,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public static readonly string EmptyConnectionStringErrorMessageFormat = $"The SignalR Service connection string or endpoints are not set."; } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Exceptions/SignalRTriggerAuthorizeFailedException.cs b/src/SignalRServiceExtension/Exceptions/SignalRTriggerAuthorizeFailedException.cs index 2a0f6d6..f818568 100644 --- a/src/SignalRServiceExtension/Exceptions/SignalRTriggerAuthorizeFailedException.cs +++ b/src/SignalRServiceExtension/Exceptions/SignalRTriggerAuthorizeFailedException.cs @@ -9,4 +9,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Exceptions/SignalRTriggerException.cs b/src/SignalRServiceExtension/Exceptions/SignalRTriggerException.cs index 669f355..c7e5dbc 100644 --- a/src/SignalRServiceExtension/Exceptions/SignalRTriggerException.cs +++ b/src/SignalRServiceExtension/Exceptions/SignalRTriggerException.cs @@ -15,4 +15,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Exceptions/SignalRTriggerParametersNotMatchException.cs b/src/SignalRServiceExtension/Exceptions/SignalRTriggerParametersNotMatchException.cs index 3df51b4..bf965d3 100644 --- a/src/SignalRServiceExtension/Exceptions/SignalRTriggerParametersNotMatchException.cs +++ b/src/SignalRServiceExtension/Exceptions/SignalRTriggerParametersNotMatchException.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace Microsoft.Azure.WebJobs.Extensions.SignalRService -{ +{ internal class SignalRTriggerParametersNotMatchException : SignalRTriggerException { public SignalRTriggerParametersNotMatchException(int excepted, int actual) : base( @@ -10,4 +10,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/Properties/AssemblyInfo.cs b/src/SignalRServiceExtension/Properties/AssemblyInfo.cs index 34468f0..8a132e0 100644 --- a/src/SignalRServiceExtension/Properties/AssemblyInfo.cs +++ b/src/SignalRServiceExtension/Properties/AssemblyInfo.cs @@ -4,4 +4,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("SignalRServiceExtension.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file diff --git a/src/SignalRServiceExtension/SecurityTokenValidationAttribute.cs b/src/SignalRServiceExtension/SecurityTokenValidationAttribute.cs index 5da5804..5315050 100644 --- a/src/SignalRServiceExtension/SecurityTokenValidationAttribute.cs +++ b/src/SignalRServiceExtension/SecurityTokenValidationAttribute.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Azure.WebJobs.Description; using System; +using Microsoft.Azure.WebJobs.Description; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { @@ -11,4 +11,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public class SecurityTokenValidationAttribute : Attribute { } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/SignalRConnectionInfoAttribute.cs b/src/SignalRServiceExtension/SignalRConnectionInfoAttribute.cs index 13b985c..928efc1 100644 --- a/src/SignalRServiceExtension/SignalRConnectionInfoAttribute.cs +++ b/src/SignalRServiceExtension/SignalRConnectionInfoAttribute.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; -using System.Security.Claims; using Microsoft.Azure.WebJobs.Description; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService @@ -25,4 +23,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public string[] ClaimTypeList { get; set; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/SignalRWebJobsStartup.cs b/src/SignalRServiceExtension/SignalRWebJobsStartup.cs index 6107bc7..931d7ca 100644 --- a/src/SignalRServiceExtension/SignalRWebJobsStartup.cs +++ b/src/SignalRServiceExtension/SignalRWebJobsStartup.cs @@ -3,9 +3,9 @@ using Microsoft.Azure.WebJobs.Extensions.SignalRService; using Microsoft.Azure.WebJobs.Hosting; -using Microsoft.Extensions.Hosting; [assembly: WebJobsStartup(typeof(SignalRWebJobsStartup))] + namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { public class SignalRWebJobsStartup : IWebJobsStartup diff --git a/src/SignalRServiceExtension/TriggerBindings/Context/InvocationContext.cs b/src/SignalRServiceExtension/TriggerBindings/Context/InvocationContext.cs index a2c1044..8d06838 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Context/InvocationContext.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Context/InvocationContext.cs @@ -1,64 +1,67 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Collections.Generic; - -namespace Microsoft.Azure.WebJobs.Extensions.SignalRService -{ - public class InvocationContext - { - /// - /// The arguments of invocation message. - /// - public object[] Arguments { get; set; } - - /// - /// The error message of close connection event. - /// Only close connection message can have this property, and it can be empty if connections close with no error. - /// - public string Error { get; set; } - - /// - /// The category of the message. - /// - public string Category { get; set; } - - /// - /// The event of the message. - /// - public string Event { get; set; } - - /// - /// The hub which message belongs to. - /// - public string Hub { get; set; } - - /// - /// The connection-id of the client which send the message. - /// - public string ConnectionId { get; set; } - - /// - /// The user identity of the client which send the message. - /// - public string UserId { get; set; } - - /// - /// The headers of request. - /// Headers with duplicated key will be joined by comma. - /// - public IDictionary Headers { get; set; } - - /// - /// The query of the request when client connect to the service. - /// Queries with duplicated key will be joined by comma. - /// - public IDictionary Query { get; set; } - - /// - /// The claims of the client. - /// If you multiple claims have the same key, only the first one will be reserved. - /// - public IDictionary Claims { get; set; } - } -} +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +namespace Microsoft.Azure.WebJobs.Extensions.SignalRService +{ + public class InvocationContext + { + /// + /// The arguments of invocation message. + /// + public object[] Arguments { get; set; } + + /// + /// The error message of close connection event. + /// Only close connection message can have this property, and it can be empty if connections close with no error. + /// + public string Error { get; set; } + + /// + /// The category of the message. + /// + public string Category { get; set; } + + /// + /// The event of the message. + /// + public string Event { get; set; } + + /// + /// The hub which message belongs to. + /// + public string Hub { get; set; } + + /// + /// The connection-id of the client which send the message. + /// + public string ConnectionId { get; set; } + + /// + /// The user identity of the client which send the message. + /// + public string UserId { get; set; } + + /// + /// The headers of request. + /// Headers with duplicated key will be joined by comma. + /// + public IDictionary Headers { get; set; } + + /// + /// The query of the request when client connect to the service. + /// Queries with duplicated key will be joined by comma. + /// + public IDictionary Query { get; set; } + + /// + /// The claims of the client. + /// If you multiple claims have the same key, only the first one will be reserved. + /// + public IDictionary Claims { get; set; } + } +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Executor/ExecutionContext.cs b/src/SignalRServiceExtension/TriggerBindings/Executor/ExecutionContext.cs index a1ea3fa..8678acb 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Executor/ExecutionContext.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Executor/ExecutionContext.cs @@ -12,4 +12,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public AccessKey[] AccessKeys { get; set; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRConnectMethodExecutor.cs b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRConnectMethodExecutor.cs index ebd884e..ad67d3e 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRConnectMethodExecutor.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRConnectMethodExecutor.cs @@ -1,20 +1,15 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Buffers; -using System.Collections.Generic; using System.Net; using System.Net.Http; -using System.Text; -using System.Threading; using System.Threading.Tasks; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { internal class SignalRConnectMethodExecutor : SignalRMethodExecutor { - public SignalRConnectMethodExecutor(IRequestResolver resolver, ExecutionContext executionContext): base(resolver, executionContext) + public SignalRConnectMethodExecutor(IRequestResolver resolver, ExecutionContext executionContext) : base(resolver, executionContext) { } @@ -34,4 +29,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return new HttpResponseMessage(HttpStatusCode.OK); } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRDisconnectMethodExecutor.cs b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRDisconnectMethodExecutor.cs index 82dbe77..c8a0e7f 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRDisconnectMethodExecutor.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRDisconnectMethodExecutor.cs @@ -1,22 +1,17 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Buffers; -using System.Collections.Generic; using System.Net; using System.Net.Http; -using System.Text; -using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.SignalR.Serverless.Protocols; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { - internal class SignalRDisconnectMethodExecutor: SignalRMethodExecutor + internal class SignalRDisconnectMethodExecutor : SignalRMethodExecutor { - public SignalRDisconnectMethodExecutor(IRequestResolver resolver, ExecutionContext executionContext): base(resolver, executionContext) + public SignalRDisconnectMethodExecutor(IRequestResolver resolver, ExecutionContext executionContext) : base(resolver, executionContext) { } @@ -34,4 +29,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return new HttpResponseMessage(HttpStatusCode.OK); } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRInvocationMethodExecutor.cs b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRInvocationMethodExecutor.cs index dfe1858..0768f7c 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRInvocationMethodExecutor.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRInvocationMethodExecutor.cs @@ -2,12 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Buffers; -using System.Collections.Generic; using System.Net; using System.Net.Http; -using System.Text; -using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR.Protocol; @@ -15,9 +11,9 @@ using InvocationMessage = Microsoft.Azure.SignalR.Serverless.Protocols.Invocatio namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { - internal class SignalRInvocationMethodExecutor: SignalRMethodExecutor + internal class SignalRInvocationMethodExecutor : SignalRMethodExecutor { - public SignalRInvocationMethodExecutor(IRequestResolver resolver, ExecutionContext executionContext): base(resolver, executionContext) + public SignalRInvocationMethodExecutor(IRequestResolver resolver, ExecutionContext executionContext) : base(resolver, executionContext) { } @@ -48,7 +44,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService if (!functionResult.Succeeded) { var errorMessage = functionResult.Exception?.InnerException?.Message ?? - functionResult.Exception?.Message ?? + functionResult.Exception?.Message ?? "Method execution failed."; completionMessage = CompletionMessage.WithError(message.InvocationId, errorMessage); response = new HttpResponseMessage(HttpStatusCode.OK); @@ -81,4 +77,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService } } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRMethodExecutor.cs b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRMethodExecutor.cs index cd3e4f0..b3c8ba9 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRMethodExecutor.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Executor/SignalRMethodExecutor.cs @@ -3,7 +3,7 @@ using System; using System.Net.Http; - using System.Threading; +using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.WebJobs.Host.Executors; @@ -58,4 +58,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return result; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/ISignalRTriggerDispatcher.cs b/src/SignalRServiceExtension/TriggerBindings/ISignalRTriggerDispatcher.cs index 56074e6..05b3ef1 100644 --- a/src/SignalRServiceExtension/TriggerBindings/ISignalRTriggerDispatcher.cs +++ b/src/SignalRServiceExtension/TriggerBindings/ISignalRTriggerDispatcher.cs @@ -4,7 +4,6 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using Microsoft.Azure.WebJobs.Host.Executors; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { @@ -14,4 +13,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService Task ExecuteAsync(HttpRequestMessage req, CancellationToken token = default); } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/InvocationContextExtensions.cs b/src/SignalRServiceExtension/TriggerBindings/InvocationContextExtensions.cs index d048c29..f4aa65f 100644 --- a/src/SignalRServiceExtension/TriggerBindings/InvocationContextExtensions.cs +++ b/src/SignalRServiceExtension/TriggerBindings/InvocationContextExtensions.cs @@ -33,4 +33,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return (await StaticServiceHubContextStore.Get().GetAsync(invocationContext.Hub)).UserGroups; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/NullListener.cs b/src/SignalRServiceExtension/TriggerBindings/NullListener.cs index f5e4fe9..d037ae8 100644 --- a/src/SignalRServiceExtension/TriggerBindings/NullListener.cs +++ b/src/SignalRServiceExtension/TriggerBindings/NullListener.cs @@ -1,14 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.WebJobs.Host.Listeners; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { - internal class NullListener: IListener + internal class NullListener : IListener { public NullListener() { @@ -32,4 +31,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Resolver/SignalRRequestResolver.cs b/src/SignalRServiceExtension/TriggerBindings/Resolver/SignalRRequestResolver.cs index ad37c96..8a02c15 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Resolver/SignalRRequestResolver.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Resolver/SignalRRequestResolver.cs @@ -36,7 +36,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService return contentType == Constants.JsonContentType || contentType == Constants.MessagePackContentType; } - // The algorithm is defined in spec: Hex_encoded(HMAC_SHA256(access-key, connection-id)) + // The algorithm is defined in spec: Hex_encoded(HMAC_SHA256(access-key, connection-id)) public bool ValidateSignature(HttpRequestMessage request, AccessKey[] accessKeys) { if (!_validateSignature) diff --git a/src/SignalRServiceExtension/TriggerBindings/ServerlessHub.cs b/src/SignalRServiceExtension/TriggerBindings/ServerlessHub.cs index 13fee97..e079774 100644 --- a/src/SignalRServiceExtension/TriggerBindings/ServerlessHub.cs +++ b/src/SignalRServiceExtension/TriggerBindings/ServerlessHub.cs @@ -7,7 +7,6 @@ using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using Microsoft.Azure.SignalR.Management; diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRFilterAttribute.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRFilterAttribute.cs index 4a0e579..183ac1e 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRFilterAttribute.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRFilterAttribute.cs @@ -3,7 +3,6 @@ using System; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.WebJobs.Host; @@ -31,5 +30,6 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService /// public abstract Task FilterAsync(InvocationContext invocationContext, CancellationToken cancellationToken); } + #pragma warning restore CS0618 // Type or member is obsolete -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRIgnoreAttribute.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRIgnoreAttribute.cs index 931302d..227b3c4 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRIgnoreAttribute.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRIgnoreAttribute.cs @@ -13,4 +13,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public class SignalRIgnoreAttribute : Attribute { } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRParameterAttribute.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRParameterAttribute.cs index c028db7..55ec4a5 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRParameterAttribute.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRParameterAttribute.cs @@ -15,4 +15,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public class SignalRParameterAttribute : Attribute { } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerAttribute.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerAttribute.cs index cdcc1d3..7183868 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerAttribute.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerAttribute.cs @@ -15,7 +15,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { } - public SignalRTriggerAttribute(string hubName, string category, string @event): this(hubName, category, @event, Array.Empty()) + public SignalRTriggerAttribute(string hubName, string category, string @event) : this(hubName, category, @event, Array.Empty()) { } diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerBinding.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerBinding.cs index fb68734..18e21db 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerBinding.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerBinding.cs @@ -1,248 +1,251 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Azure.SignalR; -using Microsoft.Azure.WebJobs.Host.Bindings; -using Microsoft.Azure.WebJobs.Host.Listeners; -using Microsoft.Azure.WebJobs.Host.Protocols; +using Microsoft.Azure.WebJobs.Host.Bindings; +using Microsoft.Azure.WebJobs.Host.Listeners; +using Microsoft.Azure.WebJobs.Host.Protocols; using Microsoft.Azure.WebJobs.Host.Triggers; -using Newtonsoft.Json.Linq; - -namespace Microsoft.Azure.WebJobs.Extensions.SignalRService -{ - internal class SignalRTriggerBinding : ITriggerBinding - { - private const string ReturnParameterKey = "$return"; - - private readonly ParameterInfo _parameterInfo; - private readonly SignalRTriggerAttribute _attribute; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Azure.WebJobs.Extensions.SignalRService +{ + internal class SignalRTriggerBinding : ITriggerBinding + { + private const string ReturnParameterKey = "$return"; + + private readonly ParameterInfo _parameterInfo; + private readonly SignalRTriggerAttribute _attribute; private readonly ISignalRTriggerDispatcher _dispatcher; - private readonly AccessKey[] _accessKeys; - - public SignalRTriggerBinding(ParameterInfo parameterInfo, SignalRTriggerAttribute attribute, ISignalRTriggerDispatcher dispatcher, AccessKey[] accessKeys) - { - _parameterInfo = parameterInfo ?? throw new ArgumentNullException(nameof(parameterInfo)); - _attribute = attribute ?? throw new ArgumentNullException(nameof(attribute)); + private readonly AccessKey[] _accessKeys; + + public SignalRTriggerBinding(ParameterInfo parameterInfo, SignalRTriggerAttribute attribute, ISignalRTriggerDispatcher dispatcher, AccessKey[] accessKeys) + { + _parameterInfo = parameterInfo ?? throw new ArgumentNullException(nameof(parameterInfo)); + _attribute = attribute ?? throw new ArgumentNullException(nameof(attribute)); _dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher)); _accessKeys = accessKeys ?? throw new ArgumentNullException(nameof(accessKeys)); - BindingDataContract = CreateBindingContract(_attribute, _parameterInfo); - } - - public Task BindAsync(object value, ValueBindingContext context) - { - var bindingData = new Dictionary(StringComparer.OrdinalIgnoreCase); - - if (value is SignalRTriggerEvent triggerEvent) - { - var bindingContext = triggerEvent.Context; - - // If ParameterNames are set, bind them in order. - // To reduce undefined situation, number of arguments should keep consist with that of ParameterNames - if (_attribute.ParameterNames != null && _attribute.ParameterNames.Length != 0) - { - if (bindingContext.Arguments == null || - bindingContext.Arguments.Length != _attribute.ParameterNames.Length) - { - throw new SignalRTriggerParametersNotMatchException(_attribute.ParameterNames.Length, bindingContext.Arguments?.Length ?? 0); - } - - AddParameterNamesBindingData(bindingData, _attribute.ParameterNames, bindingContext.Arguments); - } - - return Task.FromResult(new TriggerData(new SignalRTriggerValueProvider(_parameterInfo, bindingContext), bindingData) - { - ReturnValueProvider = triggerEvent.TaskCompletionSource == null ? null : new TriggerReturnValueProvider(triggerEvent.TaskCompletionSource), - }); - } - - return Task.FromResult(null); - } - - public Task CreateListenerAsync(ListenerFactoryContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - // It's not a real listener, and it doesn't need a start or close. - _dispatcher.Map((_attribute.HubName, _attribute.Category, _attribute.Event), - new ExecutionContext { Executor = context.Executor, AccessKeys = _accessKeys }); - - return Task.FromResult(new NullListener()); - } - - public ParameterDescriptor ToParameterDescriptor() - { - return new ParameterDescriptor - { - Name = _parameterInfo.Name, - }; - } - - /// - /// Type of object in BindAsync - /// - public Type TriggerValueType => typeof(SignalRTriggerEvent); - - // TODO: Use dynamic contract to deal with parameterName - public IReadOnlyDictionary BindingDataContract { get; } - - /// - /// Defined what other bindings can use and return value. - /// - private IReadOnlyDictionary CreateBindingContract(SignalRTriggerAttribute attribute, ParameterInfo parameter) - { - var contract = new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { ReturnParameterKey, typeof(object).MakeByRefType() }, - }; - - // Add names in ParameterNames to binding contract, that user can bind to Functions' parameter directly - if (attribute.ParameterNames != null) - { - var parameters = ((MethodInfo)parameter.Member).GetParameters().ToDictionary(p => p.Name, p => p.ParameterType, StringComparer.OrdinalIgnoreCase); - foreach (var parameterName in attribute.ParameterNames) - { - if (parameters.ContainsKey(parameterName)) - { - contract.Add(parameterName, parameters[parameterName]); - } - else - { - contract.Add(parameterName, typeof(object)); - } - } - } - - return contract; - } - - private void AddParameterNamesBindingData(Dictionary bindingData, string[] parameterNames, object[] arguments) - { - var length = parameterNames.Length; - for (var i = 0; i < length; i++) - { - if (BindingDataContract.TryGetValue(parameterNames[i], out var type)) - { - bindingData.Add(parameterNames[i], ConvertValueIfNecessary(arguments[i], type)); - } - else - { - bindingData.Add(parameterNames[i], arguments[i]); - } - } - } - - private object ConvertValueIfNecessary(object value, Type targetType) - { - if (value != null && !targetType.IsAssignableFrom(value.GetType())) - { - var underlyingTargetType = Nullable.GetUnderlyingType(targetType) ?? targetType; - - var jObject = value as JObject; - if (jObject != null) - { - value = jObject.ToObject(targetType); - } - else if (underlyingTargetType == typeof(Guid) && value.GetType() == typeof(string)) - { - // Guids need to be converted by their own logic - // Intentionally throw here on error to standardize behavior - value = Guid.Parse((string)value); - } - else - { - // if the type is nullable, we only need to convert to the - // correct underlying type - value = Convert.ChangeType(value, underlyingTargetType); - } - } - - return value; - } - - // TODO: Add more supported type - /// - /// A provider that responsible for providing value in various type to be bond to function method parameter. - /// - private class SignalRTriggerValueProvider : IValueBinder - { - private readonly InvocationContext _value; - private readonly ParameterInfo _parameter; - - public SignalRTriggerValueProvider(ParameterInfo parameter, InvocationContext value) - { - _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); - _value = value ?? throw new ArgumentNullException(nameof(value)); - } - - public Task GetValueAsync() - { - if (_parameter.ParameterType == typeof(InvocationContext)) - { - return Task.FromResult(_value); - } - else if (_parameter.ParameterType == typeof(object) || - _parameter.ParameterType == typeof(JObject)) - { - return Task.FromResult(JObject.FromObject(_value)); - } - - return Task.FromResult(null); - } - - public string ToInvokeString() - { - return _value.ToString(); - } - - public Type Type => _parameter.GetType(); - - // No use here - public Task SetValueAsync(object value, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - } - - /// - /// A provider to handle return value. - /// - private class TriggerReturnValueProvider : IValueBinder - { - private readonly TaskCompletionSource _tcs; - - public TriggerReturnValueProvider(TaskCompletionSource tcs) - { - _tcs = tcs; - } - - public Task GetValueAsync() - { - // Useless for return value provider - return null; - } - - public string ToInvokeString() - { - // Useless for return value provider - return string.Empty; - } - - public Type Type => typeof(object).MakeByRefType(); - - public Task SetValueAsync(object value, CancellationToken cancellationToken) - { - _tcs.TrySetResult(value); - return Task.CompletedTask; - } - } - } -} + BindingDataContract = CreateBindingContract(_attribute, _parameterInfo); + } + + public Task BindAsync(object value, ValueBindingContext context) + { + var bindingData = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (value is SignalRTriggerEvent triggerEvent) + { + var bindingContext = triggerEvent.Context; + + // If ParameterNames are set, bind them in order. + // To reduce undefined situation, number of arguments should keep consist with that of ParameterNames + if (_attribute.ParameterNames != null && _attribute.ParameterNames.Length != 0) + { + if (bindingContext.Arguments == null || + bindingContext.Arguments.Length != _attribute.ParameterNames.Length) + { + throw new SignalRTriggerParametersNotMatchException(_attribute.ParameterNames.Length, bindingContext.Arguments?.Length ?? 0); + } + + AddParameterNamesBindingData(bindingData, _attribute.ParameterNames, bindingContext.Arguments); + } + + return Task.FromResult(new TriggerData(new SignalRTriggerValueProvider(_parameterInfo, bindingContext), bindingData) + { + ReturnValueProvider = triggerEvent.TaskCompletionSource == null ? null : new TriggerReturnValueProvider(triggerEvent.TaskCompletionSource), + }); + } + + return Task.FromResult(null); + } + + public Task CreateListenerAsync(ListenerFactoryContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + // It's not a real listener, and it doesn't need a start or close. + _dispatcher.Map((_attribute.HubName, _attribute.Category, _attribute.Event), + new ExecutionContext { Executor = context.Executor, AccessKeys = _accessKeys }); + + return Task.FromResult(new NullListener()); + } + + public ParameterDescriptor ToParameterDescriptor() + { + return new ParameterDescriptor + { + Name = _parameterInfo.Name, + }; + } + + /// + /// Type of object in BindAsync + /// + public Type TriggerValueType => typeof(SignalRTriggerEvent); + + // TODO: Use dynamic contract to deal with parameterName + public IReadOnlyDictionary BindingDataContract { get; } + + /// + /// Defined what other bindings can use and return value. + /// + private IReadOnlyDictionary CreateBindingContract(SignalRTriggerAttribute attribute, ParameterInfo parameter) + { + var contract = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { ReturnParameterKey, typeof(object).MakeByRefType() }, + }; + + // Add names in ParameterNames to binding contract, that user can bind to Functions' parameter directly + if (attribute.ParameterNames != null) + { + var parameters = ((MethodInfo)parameter.Member).GetParameters().ToDictionary(p => p.Name, p => p.ParameterType, StringComparer.OrdinalIgnoreCase); + foreach (var parameterName in attribute.ParameterNames) + { + if (parameters.ContainsKey(parameterName)) + { + contract.Add(parameterName, parameters[parameterName]); + } + else + { + contract.Add(parameterName, typeof(object)); + } + } + } + + return contract; + } + + private void AddParameterNamesBindingData(Dictionary bindingData, string[] parameterNames, object[] arguments) + { + var length = parameterNames.Length; + for (var i = 0; i < length; i++) + { + if (BindingDataContract.TryGetValue(parameterNames[i], out var type)) + { + bindingData.Add(parameterNames[i], ConvertValueIfNecessary(arguments[i], type)); + } + else + { + bindingData.Add(parameterNames[i], arguments[i]); + } + } + } + + private object ConvertValueIfNecessary(object value, Type targetType) + { + if (value != null && !targetType.IsAssignableFrom(value.GetType())) + { + var underlyingTargetType = Nullable.GetUnderlyingType(targetType) ?? targetType; + + var jObject = value as JObject; + if (jObject != null) + { + value = jObject.ToObject(targetType); + } + else if (underlyingTargetType == typeof(Guid) && value.GetType() == typeof(string)) + { + // Guids need to be converted by their own logic + // Intentionally throw here on error to standardize behavior + value = Guid.Parse((string)value); + } + else + { + // if the type is nullable, we only need to convert to the + // correct underlying type + value = Convert.ChangeType(value, underlyingTargetType); + } + } + + return value; + } + + // TODO: Add more supported type + /// + /// A provider that responsible for providing value in various type to be bond to function method parameter. + /// + private class SignalRTriggerValueProvider : IValueBinder + { + private readonly InvocationContext _value; + private readonly ParameterInfo _parameter; + + public SignalRTriggerValueProvider(ParameterInfo parameter, InvocationContext value) + { + _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + public Task GetValueAsync() + { + if (_parameter.ParameterType == typeof(InvocationContext)) + { + return Task.FromResult(_value); + } + else if (_parameter.ParameterType == typeof(object) || + _parameter.ParameterType == typeof(JObject)) + { + return Task.FromResult(JObject.FromObject(_value)); + } + + return Task.FromResult(null); + } + + public string ToInvokeString() + { + return _value.ToString(); + } + + public Type Type => _parameter.GetType(); + + // No use here + public Task SetValueAsync(object value, CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + } + + /// + /// A provider to handle return value. + /// + private class TriggerReturnValueProvider : IValueBinder + { + private readonly TaskCompletionSource _tcs; + + public TriggerReturnValueProvider(TaskCompletionSource tcs) + { + _tcs = tcs; + } + + public Task GetValueAsync() + { + // Useless for return value provider + return null; + } + + public string ToInvokeString() + { + // Useless for return value provider + return string.Empty; + } + + public Type Type => typeof(object).MakeByRefType(); + + public Task SetValueAsync(object value, CancellationToken cancellationToken) + { + _tcs.TrySetResult(value); + return Task.CompletedTask; + } + } + } +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerDispatcher.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerDispatcher.cs index 8c1b1fe..f745b8c 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerDispatcher.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerDispatcher.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Buffers; using System.Collections.Generic; using System.Linq; using System.Net; @@ -16,6 +15,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { private readonly Dictionary<(string hub, string category, string @event), SignalRMethodExecutor> _executors = new Dictionary<(string, string, string), SignalRMethodExecutor>(TupleStringIgnoreCasesComparer.Instance); + private readonly IRequestResolver _resolver; public SignalRTriggerDispatcher(IRequestResolver resolver = null) @@ -27,7 +27,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { if (!_executors.ContainsKey(key)) { - if (string.Equals(key.category,Category.Connections, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(key.category, Category.Connections, StringComparison.OrdinalIgnoreCase)) { if (string.Equals(key.@event, Event.Connected, StringComparison.OrdinalIgnoreCase)) { @@ -65,7 +65,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { return new HttpResponseMessage(HttpStatusCode.BadRequest); } - + if (_executors.TryGetValue(key, out var executor)) { try @@ -103,4 +103,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService !string.IsNullOrEmpty(key.@event); } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerEvent.cs b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerEvent.cs index 54ea964..510b50f 100644 --- a/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerEvent.cs +++ b/src/SignalRServiceExtension/TriggerBindings/SignalRTriggerEvent.cs @@ -17,4 +17,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService /// public TaskCompletionSource TaskCompletionSource { get; set; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Utils/JsonMessageParser.cs b/src/SignalRServiceExtension/TriggerBindings/Utils/JsonMessageParser.cs index 8db0b85..b4cee4c 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Utils/JsonMessageParser.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Utils/JsonMessageParser.cs @@ -17,4 +17,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public override IHubProtocol Protocol { get; } = new JsonHubProtocol(); } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Utils/MessagePackMessageParser.cs b/src/SignalRServiceExtension/TriggerBindings/Utils/MessagePackMessageParser.cs index 57253be..2a67297 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Utils/MessagePackMessageParser.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Utils/MessagePackMessageParser.cs @@ -17,4 +17,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public override IHubProtocol Protocol { get; } = new MessagePackHubProtocol(); } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Utils/MessageParser.cs b/src/SignalRServiceExtension/TriggerBindings/Utils/MessageParser.cs index 5db64bc..1e02bb0 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Utils/MessageParser.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Utils/MessageParser.cs @@ -29,4 +29,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService public abstract IHubProtocol Protocol { get; } } -} +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Utils/SignalRTriggerUtils.cs b/src/SignalRServiceExtension/TriggerBindings/Utils/SignalRTriggerUtils.cs index a49163a..34c6fdf 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Utils/SignalRTriggerUtils.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Utils/SignalRTriggerUtils.cs @@ -1,65 +1,62 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using Microsoft.AspNetCore.WebUtilities; -using Microsoft.Extensions.Primitives; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. -namespace Microsoft.Azure.WebJobs.Extensions.SignalRService -{ - internal static class SignalRTriggerUtils - { - private const string CommaSeparator = ","; - private static readonly char[] HeaderSeparator = { ',' }; - private static readonly string[] ClaimsSeparator = { ": " }; - - - public static IDictionary GetQueryDictionary(string queryString) - { - if (string.IsNullOrEmpty(queryString)) - { - return default; - } - - // The query string looks like "?key1=value1&key2=value2" - var queries = QueryHelpers.ParseQuery(queryString); - return queries.ToDictionary(x => x.Key, x => x.Value.ToString()); - } - - public static IDictionary GetClaimDictionary(string claims) - { - if (string.IsNullOrEmpty(claims)) - { - return default; - } - - // The claim string looks like "a: v, b: v" - return claims.Split(HeaderSeparator, StringSplitOptions.RemoveEmptyEntries) - .Select(p => p.Split(ClaimsSeparator, StringSplitOptions.RemoveEmptyEntries)).Where(l => l.Length == 2) - .GroupBy(s => s[0].Trim(), (k, g) => new KeyValuePair(k, g.Select(gk => gk[1].Trim()).FirstOrDefault())) - .ToDictionary(x => x.Key, x => x.Value); - } - - public static IReadOnlyList GetSignatureList(string signatures) - { - if (string.IsNullOrEmpty(signatures)) - { - return default; - } - - return signatures.Split(HeaderSeparator, StringSplitOptions.RemoveEmptyEntries); - } - - public static IDictionary GetHeaderDictionary(HttpRequestHeaders headers) - { - return headers.ToDictionary(x => x.Key, x => string.Join(CommaSeparator, x.Value.ToArray()), StringComparer.OrdinalIgnoreCase); - } - } -} +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Headers; +using Microsoft.AspNetCore.WebUtilities; + +namespace Microsoft.Azure.WebJobs.Extensions.SignalRService +{ + internal static class SignalRTriggerUtils + { + private const string CommaSeparator = ","; + private static readonly char[] HeaderSeparator = { ',' }; + private static readonly string[] ClaimsSeparator = { ": " }; + + public static IDictionary GetQueryDictionary(string queryString) + { + if (string.IsNullOrEmpty(queryString)) + { + return default; + } + + // The query string looks like "?key1=value1&key2=value2" + var queries = QueryHelpers.ParseQuery(queryString); + return queries.ToDictionary(x => x.Key, x => x.Value.ToString()); + } + + public static IDictionary GetClaimDictionary(string claims) + { + if (string.IsNullOrEmpty(claims)) + { + return default; + } + + // The claim string looks like "a: v, b: v" + return claims.Split(HeaderSeparator, StringSplitOptions.RemoveEmptyEntries) + .Select(p => p.Split(ClaimsSeparator, StringSplitOptions.RemoveEmptyEntries)).Where(l => l.Length == 2) + .GroupBy(s => s[0].Trim(), (k, g) => new KeyValuePair(k, g.Select(gk => gk[1].Trim()).FirstOrDefault())) + .ToDictionary(x => x.Key, x => x.Value); + } + + public static IReadOnlyList GetSignatureList(string signatures) + { + if (string.IsNullOrEmpty(signatures)) + { + return default; + } + + return signatures.Split(HeaderSeparator, StringSplitOptions.RemoveEmptyEntries); + } + + public static IDictionary GetHeaderDictionary(HttpRequestHeaders headers) + { + return headers.ToDictionary(x => x.Key, x => string.Join(CommaSeparator, x.Value.ToArray()), StringComparer.OrdinalIgnoreCase); + } + } +} \ No newline at end of file diff --git a/src/SignalRServiceExtension/TriggerBindings/Utils/TupleStringIgnoreCasesComparer.cs b/src/SignalRServiceExtension/TriggerBindings/Utils/TupleStringIgnoreCasesComparer.cs index 8cce9ca..aed14d9 100644 --- a/src/SignalRServiceExtension/TriggerBindings/Utils/TupleStringIgnoreCasesComparer.cs +++ b/src/SignalRServiceExtension/TriggerBindings/Utils/TupleStringIgnoreCasesComparer.cs @@ -2,13 +2,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections; using System.Collections.Generic; -using System.Text; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService { - internal class TupleStringIgnoreCasesComparer: IEqualityComparer<(string, string, string)> + internal class TupleStringIgnoreCasesComparer : IEqualityComparer<(string, string, string)> { public static readonly TupleStringIgnoreCasesComparer Instance = new TupleStringIgnoreCasesComparer(); @@ -26,4 +24,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService StringComparer.InvariantCultureIgnoreCase.GetHashCode(obj.Item3); } } -} +} \ No newline at end of file diff --git a/test/Microsoft.Azure.SignalR.Serverless.Protocols.Tests/ServerlessProtocolTests.cs b/test/Microsoft.Azure.SignalR.Serverless.Protocols.Tests/ServerlessProtocolTests.cs index b6ec9bc..b49009c 100644 --- a/test/Microsoft.Azure.SignalR.Serverless.Protocols.Tests/ServerlessProtocolTests.cs +++ b/test/Microsoft.Azure.SignalR.Serverless.Protocols.Tests/ServerlessProtocolTests.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; using System.Buffers; using System.Collections.Generic; using System.Text; @@ -13,7 +16,7 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols.Tests { public static IEnumerable GetParameters() { - var protocols = new string[] {"json", "messagepack"}; + var protocols = new string[] { "json", "messagepack" }; foreach (var protocol in protocols) { yield return new object[] { protocol, null, Guid.NewGuid().ToString(), new object[0] }; @@ -46,7 +49,6 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols.Tests new object[] {new object[] { null, Guid.NewGuid().ToString() }} }; } - } [Theory] @@ -67,7 +69,7 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols.Tests } var serverlessProtocol = protocolName == "json" ? (IServerlessProtocol)new JsonServerlessProtocol() : new MessagePackServerlessProtocol(); Assert.True(serverlessProtocol.TryParseMessage(ref payload, out var parsedMessage)); - var invocationMessage = (InvocationMessage) parsedMessage; + var invocationMessage = (InvocationMessage)parsedMessage; Assert.Equal(1, invocationMessage.Type); Assert.Equal(invocationId, invocationMessage.InvocationId); Assert.Equal(target, invocationMessage.Target); @@ -91,11 +93,11 @@ namespace Microsoft.Azure.SignalR.Serverless.Protocols.Tests [InlineData(null)] public void CloseConnectionMessageParseTest(string error) { - var openConnectionPayload = new ReadOnlySequence(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new CloseConnectionMessage() { Type = 11, Error = error}))); + var openConnectionPayload = new ReadOnlySequence(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new CloseConnectionMessage() { Type = 11, Error = error }))); var serverlessProtocol = new JsonServerlessProtocol(); Assert.True(serverlessProtocol.TryParseMessage(ref openConnectionPayload, out var message)); Assert.Equal(error, ((CloseConnectionMessage)message).Error); Assert.Equal(typeof(CloseConnectionMessage), message.GetType()); } } -} +} \ No newline at end of file diff --git a/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/BinaryMessageParser.cs b/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/BinaryMessageParser.cs index 8d8d452..f811298 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/BinaryMessageParser.cs +++ b/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/BinaryMessageParser.cs @@ -1,7 +1,8 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; using System.Buffers; -using System.Collections.Generic; -using System.Text; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common { @@ -82,4 +83,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common return lengthPrefixBuffer.ToArray(); } } -} +} \ No newline at end of file diff --git a/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/TextMessageParser.cs b/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/TextMessageParser.cs index 62fa9af..38743e2 100644 --- a/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/TextMessageParser.cs +++ b/test/Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common/TextMessageParser.cs @@ -1,7 +1,7 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + using System.Buffers; -using System.Collections.Generic; -using System.Text; namespace Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common { @@ -29,4 +29,4 @@ namespace Microsoft.Azure.WebJobs.Extensions.SignalRService.Tests.Common return true; } } -} +} \ No newline at end of file diff --git a/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatClient.cs b/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatClient.cs index 6df04fe..2898a1e 100644 --- a/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatClient.cs +++ b/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatClient.cs @@ -29,7 +29,7 @@ namespace Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests return HttpClient.PostAsync($"{url}/api/{SendPath}", content); } - public static Task Group(string url,SignalRGroupAction action) + public static Task Group(string url, SignalRGroupAction action) { const string GroupPath = "group"; var content = JsonContent.Create(action); diff --git a/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatTests.cs b/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatTests.cs index aa541b8..3d383c3 100644 --- a/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatTests.cs +++ b/test/Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests/SimpleChat/SimpleChatTests.cs @@ -21,6 +21,7 @@ namespace Microsoft.Azure.Webjobs.Extensions.SignalRService.E2ETests { private const string Section = "SimpleChat"; public static readonly SimpleChatClient Client = new(); + public class BaseUrls : IEnumerable { public static readonly IEnumerable Data = from section in UrlConfiguration.GetSection(Section).GetChildren() diff --git a/test/SignalRServiceExtension.Tests/DefaultSecurityTokenValidatorTests.cs b/test/SignalRServiceExtension.Tests/DefaultSecurityTokenValidatorTests.cs index 721eb49..49cd5b6 100644 --- a/test/SignalRServiceExtension.Tests/DefaultSecurityTokenValidatorTests.cs +++ b/test/SignalRServiceExtension.Tests/DefaultSecurityTokenValidatorTests.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Text; using Microsoft.AspNetCore.Http; using Microsoft.Azure.WebJobs.Extensions.SignalRService; using Microsoft.Extensions.Primitives; @@ -31,7 +30,6 @@ namespace SignalRServiceExtension.Tests "", SecurityTokenStatus.Empty } - }; [Theory] @@ -59,4 +57,4 @@ namespace SignalRServiceExtension.Tests Assert.Equal(expectedStatus, securityTokenResult.Status); } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/SignalROutputConverterTests.cs b/test/SignalRServiceExtension.Tests/SignalROutputConverterTests.cs index e013aff..74c91d4 100644 --- a/test/SignalRServiceExtension.Tests/SignalROutputConverterTests.cs +++ b/test/SignalRServiceExtension.Tests/SignalROutputConverterTests.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using Microsoft.Azure.WebJobs.Extensions.SignalRService; using Newtonsoft.Json.Linq; -using System; using Xunit; namespace SignalRServiceExtension.Tests diff --git a/test/SignalRServiceExtension.Tests/Trigger/SignalRMethodExecutorTests.cs b/test/SignalRServiceExtension.Tests/Trigger/SignalRMethodExecutorTests.cs index e0dafea..88c19ff 100644 --- a/test/SignalRServiceExtension.Tests/Trigger/SignalRMethodExecutorTests.cs +++ b/test/SignalRServiceExtension.Tests/Trigger/SignalRMethodExecutorTests.cs @@ -1,6 +1,8 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; using System.Buffers; -using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -30,28 +32,27 @@ namespace SignalRServiceExtension.Tests.Trigger .Returns((data, token) => { _triggeredFunctionDataTcs.TrySetResult(data); - ((SignalRTriggerEvent) data.TriggerValue).TaskCompletionSource?.TrySetResult(string.Empty); + ((SignalRTriggerEvent)data.TriggerValue).TaskCompletionSource?.TrySetResult(string.Empty); return Task.FromResult(new FunctionResult(true)); }); _triggeredFunctionExecutor = executorMoc.Object; } - [Fact] public async Task SignalRConnectMethodExecutorTest() { var resolver = new SignalRRequestResolver(false); - var methodExecutor = new SignalRConnectMethodExecutor(resolver, new ExecutionContext {Executor = _triggeredFunctionExecutor }); + var methodExecutor = new SignalRConnectMethodExecutor(resolver, new ExecutionContext { Executor = _triggeredFunctionExecutor }); var hub = Guid.NewGuid().ToString(); var category = Guid.NewGuid().ToString(); var @event = Guid.NewGuid().ToString(); var connectionId = Guid.NewGuid().ToString(); - var content = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new OpenConnectionMessage {Type = 10})); + var content = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new OpenConnectionMessage { Type = 10 })); var request = TestHelpers.CreateHttpRequestMessage(hub, category, @event, connectionId, contentType: Constants.JsonContentType, content: content); await methodExecutor.ExecuteAsync(request); var result = await _triggeredFunctionDataTcs.Task; - var triggerData = (SignalRTriggerEvent) result.TriggerValue; + var triggerData = (SignalRTriggerEvent)result.TriggerValue; Assert.Null(triggerData.TaskCompletionSource); Assert.Equal(hub, triggerData.Context.Hub); Assert.Equal(category, triggerData.Context.Category); @@ -96,7 +97,7 @@ namespace SignalRServiceExtension.Tests.Trigger var category = Guid.NewGuid().ToString(); var @event = Guid.NewGuid().ToString(); var connectionId = Guid.NewGuid().ToString(); - var arguments = new object[] {Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}; + var arguments = new object[] { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }; var message = new Microsoft.AspNetCore.SignalR.Protocol.InvocationMessage(Guid.NewGuid().ToString(), @event, arguments); IHubProtocol protocol = protocolName == "json" ? (IHubProtocol)new JsonHubProtocol() : new MessagePackHubProtocol(); @@ -126,4 +127,4 @@ namespace SignalRServiceExtension.Tests.Trigger Assert.Equal(arguments, triggerData.Context.Arguments); } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerBindingProviderTests.cs b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerBindingProviderTests.cs index a21977b..29c6852 100644 --- a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerBindingProviderTests.cs +++ b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerBindingProviderTests.cs @@ -1,5 +1,7 @@ -using System; -using System.Collections.Generic; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; using System.Reflection; using System.Threading; using Microsoft.Azure.WebJobs; @@ -25,7 +27,7 @@ namespace SignalRServiceExtension.Tests Assert.Equal(nameof(TestServerlessHub), resolvedAttribute.HubName); Assert.Equal(Category.Messages, resolvedAttribute.Category); Assert.Equal(nameof(TestServerlessHub.TestFunction), resolvedAttribute.Event); - Assert.Equal(new string[] {"arg0", "arg1"}, resolvedAttribute.ParameterNames); + Assert.Equal(new string[] { "arg0", "arg1" }, resolvedAttribute.ParameterNames); // With SignalRIgoreAttribute parameter = typeof(TestServerlessHub).GetMethod(nameof(TestServerlessHub.TestFunctionWithIgnore), BindingFlags.Instance | BindingFlags.NonPublic).GetParameters()[0]; @@ -91,7 +93,7 @@ namespace SignalRServiceExtension.Tests public void ResolveAttributeParameterConflictTest() { var bindingProvider = CreateBindingProvider(); - var attribute = new SignalRTriggerAttribute(string.Empty, string.Empty, String.Empty, new string[] {"arg0"}); + var attribute = new SignalRTriggerAttribute(string.Empty, string.Empty, String.Empty, new string[] { "arg0" }); var parameter = typeof(TestServerlessHub).GetMethod(nameof(TestServerlessHub.TestFunction), BindingFlags.Instance | BindingFlags.NonPublic).GetParameters()[0]; Assert.ThrowsAny(() => bindingProvider.GetParameterResolvedAttribute(attribute, parameter)); } @@ -108,7 +110,7 @@ namespace SignalRServiceExtension.Tests private SignalRTriggerBindingProvider CreateBindingProvider(Exception exception = null) { var configuration = new ConfigurationBuilder().AddInMemoryCollection().Build(); - configuration[Constants.AzureSignalRConnectionStringName]= "Endpoint=http://localhost;AccessKey=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;Version=1.0;"; + configuration[Constants.AzureSignalRConnectionStringName] = "Endpoint=http://localhost;AccessKey=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;Version=1.0;"; configuration["Serverless_ExpressionBindings_HubName"] = "test_hub"; configuration["Serverless_ExpressionBindings_HubCategory"] = "connections"; configuration["Serverless_ExpressionBindings_HubEvent"] = "connected"; @@ -118,37 +120,37 @@ namespace SignalRServiceExtension.Tests public class TestServerlessHub : ServerlessHub { - internal void TestFunction([SignalRTrigger]InvocationContext context, string arg0, int arg1) + internal void TestFunction([SignalRTrigger] InvocationContext context, string arg0, int arg1) { } - internal void TestFunctionWithIgnore([SignalRTrigger]InvocationContext context, string arg0, int arg1, [SignalRIgnore]int arg2) + internal void TestFunctionWithIgnore([SignalRTrigger] InvocationContext context, string arg0, int arg1, [SignalRIgnore] int arg2) { } - internal void TestFunctionWithSpecificType([SignalRTrigger]InvocationContext context, string arg0, int arg1, ILogger logger, CancellationToken token) + internal void TestFunctionWithSpecificType([SignalRTrigger] InvocationContext context, string arg0, int arg1, ILogger logger, CancellationToken token) { } } public class TestNonServerlessHub { - internal void TestFunction([SignalRTrigger]InvocationContext context, - [SignalRParameter]string arg0, - [SignalRParameter]int arg1) + internal void TestFunction([SignalRTrigger] InvocationContext context, + [SignalRParameter] string arg0, + [SignalRParameter] int arg1) { } } public class TestConnectedServerlessHub : ServerlessHub { - internal void OnConnected([SignalRTrigger]InvocationContext context, string arg0, int arg1) + internal void OnConnected([SignalRTrigger] InvocationContext context, string arg0, int arg1) { } - internal void OnDisconnected([SignalRTrigger]InvocationContext context, string arg0, int arg1) + internal void OnDisconnected([SignalRTrigger] InvocationContext context, string arg0, int arg1) { } } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerDispatcherTests.cs b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerDispatcherTests.cs index c89e9c4..774ad5b 100644 --- a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerDispatcherTests.cs +++ b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerDispatcherTests.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; using System.Collections.Generic; using System.Net; using System.Net.Http; @@ -41,11 +44,11 @@ namespace SignalRServiceExtension.Tests var executor = executorMoc.Object; if (throwException) { - Assert.ThrowsAny(() => dispatcher.Map(key, new ExecutionContext {Executor = executor, AccessKeys = null})); + Assert.ThrowsAny(() => dispatcher.Map(key, new ExecutionContext { Executor = executor, AccessKeys = null })); return; } - dispatcher.Map(key, new ExecutionContext {Executor = executor, AccessKeys = null}); + dispatcher.Map(key, new ExecutionContext { Executor = executor, AccessKeys = null }); var request = TestHelpers.CreateHttpRequestMessage(key.hub, key.category, key.@event, Guid.NewGuid().ToString()); await dispatcher.ExecuteAsync(request); executorMoc.Verify(e => e.TryExecuteAsync(It.IsAny(), It.IsAny()), Times.Once); @@ -73,7 +76,7 @@ namespace SignalRServiceExtension.Tests .Returns(Task.FromResult(new FunctionResult(true))); var executor = executorMoc.Object; dispatcher.Map(key, new ExecutionContext { Executor = executor, AccessKeys = null }); - + // Test content type resolver.ValidateContentTypeResult = false; var request = TestHelpers.CreateHttpRequestMessage(key.hub, key.category, key.@event, Guid.NewGuid().ToString()); @@ -120,4 +123,4 @@ namespace SignalRServiceExtension.Tests } } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerResolverTests.cs b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerResolverTests.cs index c322a33..c3a3b8f 100644 --- a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerResolverTests.cs +++ b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerResolverTests.cs @@ -1,7 +1,9 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; using System.Collections.Generic; using System.Net.Http; -using System.Text; using Microsoft.Azure.SignalR; using Microsoft.Azure.WebJobs.Extensions.SignalRService; using SignalRServiceExtension.Tests.Utils; @@ -39,7 +41,6 @@ namespace SignalRServiceExtension.Tests.Trigger yield return new object[] { req, accessKeys, false }; } - [Theory] [MemberData(nameof(SignatureTestData))] internal void SignatureTest(HttpRequestMessage request, AccessKey[] accessKeys, bool validate) @@ -48,4 +49,4 @@ namespace SignalRServiceExtension.Tests.Trigger Assert.Equal(validate, resolver.ValidateSignature(request, accessKeys)); } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerTests.cs b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerTests.cs index b982a50..ddb50c8 100644 --- a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerTests.cs +++ b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerTests.cs @@ -20,13 +20,14 @@ namespace SignalRServiceExtension.Tests { private const string ConnectionString = "Endpoint=http://localhost;AccessKey=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;Version=1.0;"; private static readonly AccessKey[] AccessKeys = new AccessKey[] { new ServiceEndpoint(ConnectionString).AccessKey }; + [Fact] public async Task BindAsyncTest() { var binding = CreateBinding(nameof(TestFunction), new string[0]); var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var context = new InvocationContext(); - var triggerContext = new SignalRTriggerEvent {Context = context, TaskCompletionSource = tcs}; + var triggerContext = new SignalRTriggerEvent { Context = context, TaskCompletionSource = tcs }; var result = await binding.BindAsync(triggerContext, null); Assert.Equal(context, await result.ValueProvider.GetValueAsync()); } @@ -52,7 +53,7 @@ namespace SignalRServiceExtension.Tests public async Task BindingDataTestWithLessParameterNames() { var binding = CreateBinding(nameof(TestFunctionWithTwoStringArgument), "arg0"); - var context = new InvocationContext{Arguments = new object[] {Guid.NewGuid().ToString()}}; + var context = new InvocationContext { Arguments = new object[] { Guid.NewGuid().ToString() } }; var triggerContext = new SignalRTriggerEvent { Context = context }; var result = await binding.BindAsync(triggerContext, null); var bindingData = result.BindingData; @@ -116,4 +117,4 @@ namespace SignalRServiceExtension.Tests { } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerUtilsTests.cs b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerUtilsTests.cs index 904856f..0b5b063 100644 --- a/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerUtilsTests.cs +++ b/test/SignalRServiceExtension.Tests/Trigger/SignalRTriggerUtilsTests.cs @@ -1,7 +1,9 @@ -using System.Collections.Generic; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; -using System.Text; using Microsoft.Azure.WebJobs.Extensions.SignalRService; using Newtonsoft.Json; @@ -13,17 +15,17 @@ namespace SignalRServiceExtension.Tests { public static IEnumerable QueryStringTestData() { - yield return new object[] {"?k=v", new Dictionary {["k"] = "v"}}; + yield return new object[] { "?k=v", new Dictionary { ["k"] = "v" } }; yield return new object[] { "?k1=v1&k2=v2", new Dictionary { ["k1"] = "v1", ["k2"] = "v2" } }; - yield return new object[] { "?k1=v1&k1=v2", new Dictionary { ["k1"] = "v1,v2" }}; - yield return new object[] { "?k1=v1&k1=v2&k2=v3", new Dictionary { ["k1"] = "v1,v2", ["k2"] = "v3"} }; + yield return new object[] { "?k1=v1&k1=v2", new Dictionary { ["k1"] = "v1,v2" } }; + yield return new object[] { "?k1=v1&k1=v2&k2=v3", new Dictionary { ["k1"] = "v1,v2", ["k2"] = "v3" } }; } public static IEnumerable HeaderTestData() { var request1 = new HttpRequestMessage(); request1.Headers.Add("k", "v"); - yield return new object[] {request1.Headers, new Dictionary {["k"] = "v"}}; + yield return new object[] { request1.Headers, new Dictionary { ["k"] = "v" } }; var request2 = new HttpRequestMessage(); request2.Headers.Add("k1", "v1"); @@ -46,7 +48,7 @@ namespace SignalRServiceExtension.Tests { yield return new object[] { "k: v", new Dictionary { ["k"] = "v" } }; yield return new object[] { "k1: v1, k2: v2", new Dictionary { ["k1"] = "v1", ["k2"] = "v2" } }; - yield return new object[] { "k1: v1, k1: v2", new Dictionary { ["k1"] = "v1" }}; + yield return new object[] { "k1: v1, k1: v2", new Dictionary { ["k1"] = "v1" } }; yield return new object[] { "k1: v1, k1: v2, k2: v3", new Dictionary { ["k1"] = "v1", ["k2"] = "v3" } }; } @@ -74,4 +76,4 @@ namespace SignalRServiceExtension.Tests Assert.Equal(JsonConvert.SerializeObject(expectedResult), JsonConvert.SerializeObject(result)); } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLogger.cs b/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLogger.cs index 198f835..b0cd042 100644 --- a/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLogger.cs +++ b/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLogger.cs @@ -34,8 +34,9 @@ namespace SignalRServiceExtension.Tests.Utils.Loggings private class NoopDisposable : IDisposable { public static NoopDisposable Instance = new NoopDisposable(); + public void Dispose() { } } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLoggerProvider.cs b/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLoggerProvider.cs index a566f56..a8167c5 100644 --- a/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLoggerProvider.cs +++ b/test/SignalRServiceExtension.Tests/Utils/Loggings/XunitLoggerProvider.cs @@ -21,4 +21,4 @@ namespace SignalRServiceExtension.Tests.Utils.Loggings public void Dispose() { } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Utils/TestExtensionConfig.cs b/test/SignalRServiceExtension.Tests/Utils/TestExtensionConfig.cs index 4c96ca8..d0ebfbc 100644 --- a/test/SignalRServiceExtension.Tests/Utils/TestExtensionConfig.cs +++ b/test/SignalRServiceExtension.Tests/Utils/TestExtensionConfig.cs @@ -28,4 +28,4 @@ namespace SignalRServiceExtension.Tests.Utils BindToInput(attr => attr.ToBeAutoResolve); } } -} +} \ No newline at end of file diff --git a/test/SignalRServiceExtension.Tests/Utils/TestHelpers.cs b/test/SignalRServiceExtension.Tests/Utils/TestHelpers.cs index 9259b49..ed9a082 100644 --- a/test/SignalRServiceExtension.Tests/Utils/TestHelpers.cs +++ b/test/SignalRServiceExtension.Tests/Utils/TestHelpers.cs @@ -60,7 +60,7 @@ namespace SignalRServiceExtension.Tests.Utils return host.Services.GetService() as JobHost; } - public static HttpRequestMessage CreateHttpRequestMessage(string hub, string category, string @event, string connectionId, + public static HttpRequestMessage CreateHttpRequestMessage(string hub, string category, string @event, string connectionId, string contentType = Constants.JsonContentType, byte[] content = null, string[] signatures = null) { var context = new DefaultHttpContext(); diff --git a/test/SignalRServiceExtension.Tests/Utils/TestTriggerDispatcher.cs b/test/SignalRServiceExtension.Tests/Utils/TestTriggerDispatcher.cs index 5ab316d..c440e66 100644 --- a/test/SignalRServiceExtension.Tests/Utils/TestTriggerDispatcher.cs +++ b/test/SignalRServiceExtension.Tests/Utils/TestTriggerDispatcher.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -13,7 +12,7 @@ using ExecutionContext = Microsoft.Azure.WebJobs.Extensions.SignalRService.Execu namespace SignalRServiceExtension.Tests.Utils { - class TestTriggerDispatcher : ISignalRTriggerDispatcher + internal class TestTriggerDispatcher : ISignalRTriggerDispatcher { public Dictionary<(string, string, string), ExecutionContext> Executors { get; } = new Dictionary<(string, string, string), ExecutionContext>(); @@ -28,4 +27,4 @@ namespace SignalRServiceExtension.Tests.Utils throw new NotImplementedException(); } } -} +} \ No newline at end of file