/// <summary> /// 拦截服务请求 /// </summary> public override async Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { Endpoint endpoint = OwinContextReader.Current.GetEndpoint(); bool needAuthorize = AspNetSetting.Authorized; bool allowAnonymous = endpoint.Metadata.GetMetadata <AllowAnonymousAttribute>() != null; if (needAuthorize && !allowAnonymous) { string headerKey = SessionKey.PublicKey.ToLower(); Metadata.Entry headerEntry = context.RequestHeaders.Get(headerKey); string publicKey = headerEntry?.Value; if (string.IsNullOrWhiteSpace(publicKey)) { string message = "身份认证消息头不存在,请检查程序!"; NoPermissionException innerException = new NoPermissionException(message); Status status = new Status(StatusCode.Unauthenticated, message, innerException); throw new RpcException(status); } LoginInfo loginInfo = CacheMediator.Get <LoginInfo>(publicKey); if (loginInfo == null) { string message = "身份过期,请重新登录!"; NoPermissionException innerException = new NoPermissionException(message); Status status = new Status(StatusCode.Unauthenticated, message, innerException); throw new RpcException(status); } //通过后,重新设置缓存过期时间 CacheMediator.Set(publicKey, loginInfo, DateTime.Now.AddMinutes(GlobalSetting.AuthenticationTimeout)); } return(await continuation.Invoke(request, context)); }
public void KeysAreNormalized_UppercaseKey() { var uppercaseKey = "ABC"; var entry = new Metadata.Entry(uppercaseKey, "XYZ"); Assert.AreEqual("abc", entry.Key); }
public static Metadata ProcessHeaders(Metadata headers) { if (headers == null) { throw new ArgumentNullException(nameof(headers)); } Metadata.Entry trackingEntry = headers.FirstOrDefault(x => string.CompareOrdinal(x.Key, s_TrackingContextKeyName) == 0); // Retrieve the tracking context from the message header, if it exists. if (trackingEntry != null) { // If an tracking context exists in the message header, always use it to replace the ambient context. TrackingContext tc = TrackingContext.DeSerialize(trackingEntry.ValueBytes); tc.SetAsCurrent(); } else { // If no tracking context exists then create one. TrackingContext.NewCurrentIfEmpty(); Debug.Assert(TrackingContext.Current != null); // Copy the tracking context to the message header. byte[] byteArray = TrackingContext.Serialize(TrackingContext.Current); headers.Add(s_TrackingContextKeyName, byteArray); } return(headers); }
// call immediately after create. public async Task __ConnectAndSubscribeAsync(TReceiver receiver, CancellationToken cancellationToken) { var syncContext = SynchronizationContext.Current; // capture SynchronizationContext. var callResult = callInvoker.AsyncDuplexStreamingCall <byte[], byte[]>(DuplexStreamingAsyncMethod, host, option); var streamingResult = new DuplexStreamingResult <byte[], byte[]>( callResult, new MarshallingClientStreamWriter <byte[]>(callResult.RequestStream, serializerOptions), new MarshallingAsyncStreamReader <byte[]>(callResult.ResponseStream, serializerOptions), serializerOptions ); this.connection = streamingResult; this.receiver = receiver; // Establish StreamingHub connection between the client and the server. Metadata.Entry messageVersion = default; try { // The client can read the response headers before any StreamingHub's message. // MagicOnion.Server v4.0.x or before doesn't send any response headers. The client is incompatible with that versions. // NOTE: Grpc.Net: // If the channel can not be connected, ResponseHeadersAsync will throw an exception. // C-core: // If the channel can not be connected, ResponseHeadersAsync will **return** an empty metadata. var headers = await streamingResult.ResponseHeadersAsync.ConfigureAwait(false); messageVersion = headers.FirstOrDefault(x => x.Key == StreamingHubVersionHeaderKey); cancellationToken.ThrowIfCancellationRequested(); // Check message version of StreamingHub. if (messageVersion != null && messageVersion.Value != StreamingHubVersionHeaderValue) { throw new RpcException(new Status(StatusCode.Internal, $"The message version of StreamingHub mismatch between the client and the server. (ServerVersion={messageVersion?.Value}; Expected={StreamingHubVersionHeaderValue})")); } } catch (RpcException e) { throw new RpcException(e.Status, $"Failed to connect to StreamingHub '{DuplexStreamingAsyncMethod.ServiceName}'. ({e.Status})"); } var firstMoveNextTask = connection.RawStreamingCall.ResponseStream.MoveNext(CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cts.Token).Token); if (firstMoveNextTask.IsFaulted || messageVersion == null) { // NOTE: Grpc.Net: // If an error is returned from `StreamingHub.Connect` method on a server-side, // ResponseStream.MoveNext synchronously returns a task that is `IsFaulted = true`. // `ConnectAsync` method should throw an exception here immediately. // C-core: // `firstMoveNextTask` is incomplete task (`IsFaulted = false`) whether ResponseHeadersAsync is failed or not. // If the channel is disconnected or the server returns an error (StatusCode != OK), awaiting the Task will throw an exception. await firstMoveNextTask.ConfigureAwait(false); // NOTE: C-core: If the execution reaches here, Connect method returns without any error (StatusCode = OK). but MessageVersion isn't provided from the server. throw new RpcException(new Status(StatusCode.Internal, $"The message version of StreamingHub is not provided from the server.")); } this.subscription = StartSubscribe(syncContext, firstMoveNextTask); }
private ClientInterceptorContext <TRequest, TResponse> SetTraceIdHeader <TRequest, TResponse>(ClientInterceptorContext <TRequest, TResponse> context) where TRequest : class where TResponse : class { var header = context.Options.Headers?.Where(p => p.Key == Consts.TraceId).FirstOrDefault(); if (header == null) { var serverHeader = ServerCallContextAccessor.Current?.RequestHeaders.Where(p => p.Key == Consts.TraceId).FirstOrDefault(); var traceId = serverHeader == null?Guid.NewGuid().ToString() : serverHeader.Value; header = new Metadata.Entry(Consts.TraceId, traceId); if (context.Options.Headers == null) { var meta = new Metadata(); meta.Add(header); var callOptions = context.Options.WithHeaders(meta); context = new ClientInterceptorContext <TRequest, TResponse>(context.Method, context.Host, callOptions); } else { context.Options.Headers.Add(header); } } return(context); }
public static bool Validate(ServerCallContext context) { Metadata.Entry metadataEntry = context.RequestHeaders.FirstOrDefault(m => String.Equals(m.Key, ActiveDirectoryCredentialsFactory.AuthorizationHeader, StringComparison.Ordinal)); if (metadataEntry.Equals(default(Metadata.Entry)) || metadataEntry.Value == null) { return(false); } string authorizationHeaderValue = Encoding.UTF8.GetString(Convert.FromBase64String(metadataEntry.Value)); if (String.IsNullOrWhiteSpace(authorizationHeaderValue)) { return(false); } var splitedString = authorizationHeaderValue.Split(':'); if (splitedString.Length < 3) { return(false); } string userName = splitedString[0]; string password = splitedString[1]; string domain = splitedString[2]; return(ValidateLdapCredentials(userName, password, domain)); }
public override Task <HelloResponse> Hello1(HelloRequest request, ServerCallContext context) { //check the accessToken Metadata.Entry accessToken = null; foreach (var entry in context.RequestHeaders) { if (entry.Key.Equals("accessToken", System.StringComparison.OrdinalIgnoreCase)) { accessToken = entry; break; } } if (accessToken == null) { context.Status = new Status(StatusCode.Unauthenticated, "没有权限访问此接口,请检查是否有传递有效的访问令牌"); return(Task.FromResult <HelloResponse>(null)); } var tokenValue = new JwtBuilder() .WithAlgorithm(new HMACSHA512Algorithm()) .WithSecret("*****@*****.**") .MustVerifySignature() .Decode(accessToken.Value); Console.WriteLine($"访问令牌:{tokenValue}"); //say hello return(Task.FromResult(new HelloResponse { Message = $"hello1 {request.Name} from service1" })); }
public void KeysAreNormalized_LowercaseKey() { var lowercaseKey = "abc"; var entry = new Metadata.Entry(lowercaseKey, "XYZ"); // no allocation if key already lowercase Assert.AreSame(lowercaseKey, entry.Key); }
public void Indexer_Set() { var metadata = CreateMetadata(); var entry = new Metadata.Entry("new-key", "new-value"); metadata[1] = entry; Assert.AreEqual(entry, metadata[1]); }
public void CopyTo() { var metadata = CreateMetadata(); var array = new Metadata.Entry[metadata.Count + 1]; metadata.CopyTo(array, 1); Assert.AreEqual(default(Metadata.Entry), array[0]); Assert.AreEqual(metadata[0], array[1]); }
static bool Match(Metadata.Entry currentEntry, string headerName, bool isBinary, ref Metadata.Entry?entry) { if (!headerName.Equals(currentEntry.Key, StringComparison.OrdinalIgnoreCase) || currentEntry.IsBinary != isBinary) { return(false); } entry ??= currentEntry; return(true); }
private bool HasResourcePrefixHeader(CallSettings callSettings) { var expectedDatabaseName = DatabaseName.FromProjectInstanceDatabase( SpannerClientHelpers.ProjectId, SpannerClientHelpers.Instance, SpannerClientHelpers.Database); var metadata = new Metadata(); callSettings.HeaderMutation?.Invoke(metadata); Metadata.Entry entry = Assert.Single(metadata, e => e.Key == SpannerClientImpl.ResourcePrefixHeader); return expectedDatabaseName.ToString() == entry.Value; }
public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(TRequest request, ClientInterceptorContext <TRequest, TResponse> context, AsyncUnaryCallContinuation <TRequest, TResponse> continuation) { var retryCount = 0; Metadata.Entry timeoutInMilliSecondsMetadataEntry = null; if (context.Options.Headers != null && context.Options.Headers.Any()) { timeoutInMilliSecondsMetadataEntry = context.Options.Headers.FirstOrDefault(m => string.Equals(m.Key, GrpcConstants.TimeoutMetadataKey, StringComparison.Ordinal)); } var timeoutSpan = timeoutInMilliSecondsMetadataEntry == null ? TimeSpan.FromMilliseconds(GrpcConstants.DefaultRequestTimeoutInMilliSeconds) : TimeSpan.FromMilliseconds(int.Parse(timeoutInMilliSecondsMetadataEntry.Value)); async Task <TResponse> RetryCallback(Task <TResponse> responseTask) { var response = responseTask; // if no problem occured return if (!response.IsFaulted) { return(response.Result); } // if a problem occured but reached the max retries if (retryCount == _retryCount) { return(response.Result); } retryCount++; // try again var retryContext = BuildNewContext(context, timeoutSpan); var result = continuation(request, retryContext).ResponseAsync.ContinueWith(RetryCallback).Unwrap(); return(await result); } var newContext = BuildNewContext(context, timeoutSpan); var responseContinuation = continuation(request, newContext); var responseAsync = responseContinuation.ResponseAsync.ContinueWith(RetryCallback).Unwrap(); return(new AsyncUnaryCall <TResponse>( responseAsync, responseContinuation.ResponseHeadersAsync, responseContinuation.GetStatus, responseContinuation.GetTrailers, responseContinuation.Dispose)); }
private DistributedTracingData getDistributedTracingData(ServerCallContext context) { Metadata.Entry metadataEntry = context.RequestHeaders.FirstOrDefault(m => String.Equals(m.Key.ToLower(), "elastic-apm-traceparent", StringComparison.Ordinal)); DistributedTracingData distributedTracingData = null; if (metadataEntry != null && !metadataEntry.Equals(default(Metadata.Entry)) && metadataEntry.Value != null) { distributedTracingData = DistributedTracingData.TryDeserializeFromString(metadataEntry.Value); } return(distributedTracingData); }
public void AsciiEntry() { var entry = new Metadata.Entry("ABC", "XYZ"); Assert.IsFalse(entry.IsBinary); Assert.AreEqual("abc", entry.Key); // key is in lowercase. Assert.AreEqual("XYZ", entry.Value); CollectionAssert.AreEqual(new[] { (byte)'X', (byte)'Y', (byte)'Z' }, entry.ValueBytes); Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc-bin", "xyz")); Assert.AreEqual("[Entry: key=abc, value=XYZ]", entry.ToString()); }
public void Entry_Immutable() { var origBytes = new byte[] { 1, 2, 3 }; var bytes = new byte[] { 1, 2, 3 }; var entry = new Metadata.Entry("ABC-BIN", bytes); bytes[0] = 255; // changing the array passed to constructor should have any effect. CollectionAssert.AreEqual(origBytes, entry.ValueBytes); entry.ValueBytes[0] = 255; CollectionAssert.AreEqual(origBytes, entry.ValueBytes); }
public static bool ContainsHeader(this Metadata metadata, Metadata.Entry entry) { for (var i = 0; i < metadata.Count; i++) { if (HeadersAreEqual(metadata[i], entry)) { return(true); } } return(false); }
public override async Task <TResponse> UnaryServerHandler <TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod <TRequest, TResponse> continuation) { var trace = context.RequestHeaders.FirstOrDefault(q => q.Key == Consts.TraceId); if (trace == null) { trace = new Metadata.Entry(Consts.TraceId, Guid.NewGuid().ToString()); context.RequestHeaders.Add(trace); } var model = new MonitorModel { ClientIp = context.Peer, RequestUrl = context.Method, RequestData = request?.ToJson(), TraceId = trace.Value }; try { var result = await continuation(request, context); model.Status = "ok"; model.ResponseData = MonitorManager.Instance.SaveResponseMethodEnable(context.Method) ? result?.ToJson() : Consts.NotResponseMsg; return(result); } catch (Exception ex) { if (ex is AggregateException aex) { foreach (var e in aex.Flatten().InnerExceptions) { model.Exception += e?.ToString() + Environment.NewLine; } } else { model.Exception = ex?.ToString(); } model.Status = "error"; LoggerAccessor.Instance.LoggerError?.Invoke(new Exception(model.Exception)); throw CommonError.BuildRpcException(ex); } finally { model.ResponseTime = DateTime.Now; LoggerAccessor.Instance.LoggerMonitor?.Invoke(model.ToJson()); } }
public void SetsHeaderOnPartitionQuery() { var invoker = new FakeCallInvoker(); var client = new SpannerClientBuilder { CallInvoker = invoker }.Build(); client.PartitionQuery(new PartitionQueryRequest { Session = SampleSessionName }); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleDatabaseName, entry.Value); }
public void SetsHeaderOnGetDatabaseDdl() { var invoker = new FakeCallInvoker(); var client = new DatabaseAdminClientBuilder { CallInvoker = invoker }.Build(); client.GetDatabaseDdl(new GetDatabaseDdlRequest { Database = SampleDatabaseName }); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleDatabaseName, entry.Value); }
public void SetsHeaderOnRestoreDatabase() { var invoker = new FakeCallInvoker(); var client = new DatabaseAdminClientBuilder { CallInvoker = invoker }.Build(); client.RestoreDatabase(new RestoreDatabaseRequest { Parent = SampleInstanceName }); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleInstanceName, entry.Value); }
public void SetsHeaderOnListBackupOperations() { var invoker = new FakeCallInvoker(); var client = new DatabaseAdminClientBuilder { CallInvoker = invoker }.Build(); client.ListBackupOperations(new ListBackupOperationsRequest { Parent = SampleInstanceName }).AsRawResponses().First(); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleInstanceName, entry.Value); }
public void SetsHeaderOnBatchCreateSessions() { var invoker = new FakeCallInvoker(); var client = new SpannerClientBuilder { CallInvoker = invoker }.Build(); client.BatchCreateSessions(new BatchCreateSessionsRequest { Database = SampleDatabaseName }); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleDatabaseName, entry.Value); }
public void SetsHeaderOnGetInstanceConfig() { var invoker = new FakeCallInvoker(); var client = new InstanceAdminClientBuilder { CallInvoker = invoker }.Build(); client.GetInstanceConfig(new GetInstanceConfigRequest { Name = SampleInstanceConfigName }); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleProjectName, entry.Value); }
public void BinaryEntry() { var bytes = new byte[] { 1, 2, 3 }; var entry = new Metadata.Entry("ABC-BIN", bytes); Assert.IsTrue(entry.IsBinary); Assert.AreEqual("abc-bin", entry.Key); // key is in lowercase. Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; }); CollectionAssert.AreEqual(bytes, entry.ValueBytes); Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc", bytes)); Assert.AreEqual("[Entry: key=abc-bin, valueBytes=System.Byte[]]", entry.ToString()); }
/// <summary> /// Gets blockID from list of metadata /// </summary> /// <param name="metaData">List of metadata</param> /// <returns>BlockID</returns> public static Guid GetBlockID(List <Metadata.Entry> metaData) { Guid id = new Guid(); try { Metadata.Entry blckId = metaData.Find(m => { return(m.Key == "blockid"); }); id = Guid.Parse(blckId.Value); return(id); } catch { return(id); } }
/// <summary> /// Gets block size from list of metadata /// </summary> /// <param name="metaData">List of metadata</param> /// <returns>Size of block</returns> public static int GetBlockSize(List <Metadata.Entry> metaData) { int blockSize = 0; try { Metadata.Entry size = metaData.Find(m => { return(m.Key == "blocksize"); }); blockSize = Convert.ToInt32(size.Value); return(blockSize); } catch { return(blockSize); } }
public void FreezeMakesReadOnly() { var entry = new Metadata.Entry("new-key", "new-value"); var metadata = CreateMetadata().Freeze(); Assert.IsTrue(metadata.IsReadOnly); Assert.Throws <InvalidOperationException>(() => metadata.Insert(0, entry)); Assert.Throws <InvalidOperationException>(() => metadata.RemoveAt(0)); Assert.Throws <InvalidOperationException>(() => metadata[0] = entry); Assert.Throws <InvalidOperationException>(() => metadata.Add(entry)); Assert.Throws <InvalidOperationException>(() => metadata.Add("new-key", "new-value")); Assert.Throws <InvalidOperationException>(() => metadata.Add("new-key-bin", new byte[] { 0xaa })); Assert.Throws <InvalidOperationException>(() => metadata.Clear()); Assert.Throws <InvalidOperationException>(() => metadata.Remove(metadata[0])); }
private static bool HeadersAreEqual(Metadata.Entry x, Metadata.Entry y) { if (!string.Equals(x.Key, y.Key, StringComparison.OrdinalIgnoreCase) || x.IsBinary != y.IsBinary) { return(false); } if (x.IsBinary) { return(SequenceEqual(x.ValueBytes, y.ValueBytes)); } return(string.Equals(x.Value, y.Value, StringComparison.Ordinal)); }
public void SetsHeaderOnUpdateBackup() { var invoker = new FakeCallInvoker(); var client = new DatabaseAdminClientBuilder { CallInvoker = invoker }.Build(); client.UpdateBackup(new UpdateBackupRequest { Backup = new Backup { Name = SampleBackupName } }); Metadata.Entry entry = Assert.Single(invoker.Metadata, e => e.Key == ResourcePrefixHeader); Assert.Equal(SampleInstanceName, entry.Value); }
public void FreezeMakesReadOnly() { var entry = new Metadata.Entry("new-key", "new-value"); var metadata = CreateMetadata().Freeze(); Assert.IsTrue(metadata.IsReadOnly); Assert.Throws<InvalidOperationException>(() => metadata.Insert(0, entry)); Assert.Throws<InvalidOperationException>(() => metadata.RemoveAt(0)); Assert.Throws<InvalidOperationException>(() => metadata[0] = entry); Assert.Throws<InvalidOperationException>(() => metadata.Add(entry)); Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key", "new-value")); Assert.Throws<InvalidOperationException>(() => metadata.Add("new-key-bin", new byte[] { 0xaa })); Assert.Throws<InvalidOperationException>(() => metadata.Clear()); Assert.Throws<InvalidOperationException>(() => metadata.Remove(metadata[0])); }