private async Task WriteRunningModuleEntryAsync( ModuleIdentifier module, EndPointAddress endPoint, ICollection <ReadOnlyMemory <char> > prefixes, Session session, CancellationToken cancellation) { var path = GetRunningModulePath(module, session); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { writer.Write(endPoint); writer.Write(prefixes.Count()); foreach (var prefix in prefixes) { WritePrefix(writer, prefix); } } var payload = stream.ToArray(); await _coordinationManager.GetOrCreateAsync(path, payload, EntryCreationModes.Ephemeral, cancellation); } }
private static bool IsCategoryValidV2(string category) { //Test V2 API //It may take a while until the category is loaded on server bool returnvalue = true; for (int i = 0; i < 3; i++) { try { string headerValue = GetHeaderValue(); var bind = new BasicHttpBinding { Name = "BasicHttpBinding_LanguageService" }; var epa = new EndpointAddress(EndPointAddress.Replace("https", "http") + "/V2/soap.svc"); LanguageServiceClient client = new LanguageServiceClient(bind, epa); client.Translate(headerValue, "Test", "en", "fr", "text/plain", category, string.Empty); returnvalue = true; break; } catch (Exception e) { string error = e.Message; returnvalue = false; Thread.Sleep(1000); continue; } } return(returnvalue); }
public SerializedMessageHandlerProxy(ClientManager owner, EndPointAddress endPoint) { Assert(owner != null); Assert(endPoint != default); _owner = owner; _endPoint = endPoint; }
private async Task <(EndPointAddress endPoint, string securityToken)> AddClientCoreAsync(CancellationToken cancellation) { var now = _dateTimeProvider.GetCurrentTime(); var securityToken = Guid.NewGuid().ToString(); var leaseEnd = now + Timeout; var securityTokenBytesCount = Encoding.UTF8.GetByteCount(securityToken); using (ArrayPool <byte> .Shared.Rent(8 + 4 + securityTokenBytesCount, out var bytes)) { var payloadLength = EncodePayload(bytes, securityToken.AsSpan(), leaseEnd); var payload = bytes.AsMemory().Slice(start: 0, payloadLength); EndPointAddress endPoint; do { endPoint = AllocateEndPointAddress(); var path = GetPath(endPoint); try { await _coordinationManager.CreateAsync(path, payload, cancellation : cancellation); _logger?.LogDebug($"Assigning end-point '{endPoint.ToString()}' to recently connected client."); break; } catch (DuplicateEntryException) // TODO: Add a TryCreateAsync method to the coordination service. { continue; } }while (cancellation.ThrowOrContinue()); return(endPoint, securityToken); } }
public AckLookupEntry(int seqNum, EndPointAddress endPoint, ReadOnlyMemory <byte> bytes, TaskCompletionSource <object> ackSource) { SeqNum = seqNum; EndPoint = endPoint; Bytes = bytes; AckSource = ackSource; }
public async ValueTask <IMessage> RouteAsync( Route route, IMessage serializedMessage, bool publish, EndPointAddress endPoint, CancellationToken cancellation) { if (route == null) { throw new ArgumentNullException(nameof(route)); } if (serializedMessage == null) { throw new ArgumentNullException(nameof(serializedMessage)); } if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } var idx = serializedMessage.FrameIndex; using (CheckDisposal(ref cancellation, out var disposal)) { try { try { EncodeRouteRequest(serializedMessage, route, publish, endPoint); var response = await SendInternalAsync(serializedMessage, cancellation); return(response); } catch { Assert(serializedMessage.FrameIndex >= idx); while (serializedMessage.FrameIndex > idx) { serializedMessage.PopFrame(); } throw; } } catch (OperationCanceledException) when(disposal.IsCancellationRequested) { throw new ObjectDisposedException(GetType().FullName); } } }
private static DebugModuleProperties Decode(ReadOnlySpan <byte> memory) { var reader = new BinarySpanReader(memory, ByteOrder.LittleEndian); var endPoint = new EndPointAddress(reader.Read().ToArray()); // TODO: This copies var module = new ModuleIdentifier(reader.ReadString()); var major = reader.ReadInt32(); var minor = reader.ReadInt32(); var revision = reader.ReadInt32(); var isPreRelease = reader.ReadBool(); var version = new ModuleVersion(major, minor, revision, isPreRelease); return(new DebugModuleProperties(endPoint, module, version)); }
public async Task <bool> ValidateClientAsync(EndPointAddress endPoint, string securityToken, CancellationToken cancellation) { using (CheckDisposal(ref cancellation, out var disposal)) { try { return(await ValidateClientCoreAsync(endPoint, securityToken, cancellation)); } catch (OperationCanceledException) when(disposal.IsCancellationRequested) { throw new ObjectDisposedException(GetType().FullName); } } }
public DecodedMessage(MessageType messageType, bool handled, int seqNum, int corr, EndPointAddress txEndPoint, EndPointAddress rxEndPoint) { MessageType = messageType; Handled = handled; SeqNum = seqNum; Corr = corr; TxEndPoint = txEndPoint; RxEndPoint = rxEndPoint; }
public LogicalEndPointSkeleton(IEndPointManager endPointManager, EndPointAddress endPoint) { if (endPointManager == null) { throw new ArgumentNullException(nameof(endPointManager)); } if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } _endPointManager = endPointManager; _logicalEndPoint = _endPointManager.CreateLogicalEndPoint(endPoint); }
public async Task AddModuleAsync(ModuleIdentifier module, EndPointAddress endPoint, IEnumerable <ReadOnlyMemory <char> > prefixes, CancellationToken cancellation) { if (module == default) { throw new ArgumentDefaultException(nameof(module)); } if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } if (prefixes == null) { throw new ArgumentNullException(nameof(prefixes)); } if (!prefixes.Any()) { throw new ArgumentException("The collection must not be empty.", nameof(prefixes)); } if (prefixes.Any(prefix => prefix.Span.IsEmptyOrWhiteSpace())) { throw new ArgumentException("The collection must not contain null entries or entries that are empty or contain whitespace only.", nameof(prefixes)); } var prefixCollection = (prefixes as ICollection <ReadOnlyMemory <char> >) ?? prefixes.ToList(); var session = await _coordinationManager.GetSessionAsync(cancellation); var tasks = new List <Task>(capacity: prefixCollection.Count()); foreach (var prefix in prefixCollection) { tasks.Add(WriteModulePrefixEntryAsync(prefix, endPoint, session, cancellation)); } await Task.WhenAll(tasks); await WriteRunningModuleEntryAsync(module, endPoint, prefixCollection, session, cancellation); // TODO: When cancelled, alls completed operations should be reverted. // TODO: The RemoveModuleAsync alogrithm assumes that there are no prefix entries, if the running module entry is not present. We should reflect this assumtion here. }
/// <summary> /// Call once to initialize the static variables /// </summary> public static void Initialize() { LoadCredentials(); //Inspect the given Azure Key to see if this is host with appid auth string[] AuthComponents = _AzureKey.Split('?'); if (AuthComponents.Length > 1) { EndPointAddress = AuthComponents[0]; string[] appidComponents = AuthComponents[1].ToLowerInvariant().Split('='); if (appidComponents[0] == "appid") { authMode = AuthMode.AppId; appid = appidComponents[1]; } else { return; } } try { if (!IsTranslationServiceReady()) { return; } } catch { return; } var bind = new BasicHttpBinding { Name = "BasicHttpBinding_LanguageService" }; var epa = new EndpointAddress(EndPointAddress.Replace("https:", "http:") + "/V2/soap.svc"); //for some reason GetLanguagesForTranslate doesn't work with SSL. LanguageServiceClient client = new LanguageServiceClient(bind, epa); string headerValue = GetHeaderValue(); string[] languages = client.GetLanguagesForTranslate(headerValue); string[] languagenames = client.GetLanguageNames(headerValue, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName, languages, false); for (int i = 0; i < languages.Length; i++) { if (!AvailableLanguages.ContainsKey(languages[i])) { AvailableLanguages.Add(languages[i], languagenames[i]); } } client.Close(); }
//public async Task<bool> DisconnectAsync(EndPointAddress endPoint, string securityToken, CancellationToken cancellation) // TODO: WaitForDisconnectAsync must return a completed task, if the client is not connected at the time of call. public async Task WaitForDisconnectAsync(EndPointAddress endPoint, CancellationToken cancellation) { using (CheckDisposal(ref cancellation, out var disposal)) { try { async Task BuildClientDisconnectCacheEntry() { try { // Yields back the task, that represents the asnyc state machine immediately to leave the critical section as fast as possible. await Task.Yield(); await WaitForDisconnectCoreAsync(endPoint); } finally { lock (_lock) { _clientDisconnectCache.Remove(endPoint); } } } Task task; lock (_lock) { if (!_clientDisconnectCache.TryGetValue(endPoint, out task)) { task = BuildClientDisconnectCacheEntry(); _clientDisconnectCache.Add(endPoint, task); } } await task.WithCancellation(cancellation); } catch (OperationCanceledException) when(disposal.IsCancellationRequested) { throw new ObjectDisposedException(GetType().FullName); } } }
/// <summary> /// Check if the Translation service is ready to use, with a valid client ID and secret /// </summary> /// <returns>true if ready, false if not</returns> public static bool IsTranslationServiceReady() { switch (authMode) { case AuthMode.Azure: try { AzureAuthToken authTokenSource = new AzureAuthToken(_AzureKey); string headerValue = authTokenSource.GetAccessToken(); var bind = new BasicHttpBinding { Name = "BasicHttpBinding_LanguageService" }; var epa = new EndpointAddress(EndPointAddress.Replace("https:", "http:") + "/V2/soap.svc"); LanguageServiceClient client = new LanguageServiceClient(bind, epa); string[] languages = new string[1]; languages[0] = "en"; client.GetLanguageNames(GetHeaderValue(), Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName, languages, false); } catch { return(false); } break; case AuthMode.AppId: try { var bind = new BasicHttpBinding { Name = "BasicHttpBinding_LanguageService" }; var epa = new EndpointAddress(EndPointAddress.Replace("https:", "http:") + "/V2/soap.svc"); LanguageServiceClient client = new LanguageServiceClient(bind, epa); string[] languages = new string[1]; languages[0] = "en"; client.GetLanguageNames(GetHeaderValue(), Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName, languages, false); } catch { return(false); } break; default: return(false); } return(true); }
public DebugLogicalEndPoint(DebugConnection debugConnection, EndPointAddress endPoint, ILogger <DebugLogicalEndPoint> logger = null) { if (debugConnection == null) { throw new ArgumentNullException(nameof(debugConnection)); } if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } _debugConnection = debugConnection; EndPoint = endPoint; _logger = logger; _proxyLazy = new DisposableAsyncLazy <IProxy <LogicalEndPointSkeleton> >( factory: CreateProxyAsync, disposal: p => p.DisposeAsync(), options: DisposableAsyncLazyOptions.Autostart | DisposableAsyncLazyOptions.ExecuteOnCallingThread); }
public async Task <byte[]> SendAsync(byte[] messageBuffer, EndPointAddress remoteEndPoint, CancellationToken cancellation = default) { var message = new Message(); using (var stream = new MemoryStream(messageBuffer)) { await message.ReadAsync(stream, cancellation); } var(response, handled) = await _logicalEndPoint.SendAsync(message, remoteEndPoint, cancellation); response.Trim(); using (var stream = response.PushFrame().OpenStream()) using (var writer = new BinaryWriter(stream)) { writer.Write(handled); } return(response.ToArray()); }
private async Task WriteModulePrefixEntryAsync(ReadOnlyMemory <char> prefix, EndPointAddress endPoint, Session session, CancellationToken cancellation) { var normalizedPrefix = NormalizePrefix(prefix); if (normalizedPrefix.Span[0] == '_') { throw new ArgumentException("A prefix must not begin with an underscore."); } var path = GetPrefixPath(normalizedPrefix, endPoint, session, normalize: false); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { writer.Write(endPoint); } var payload = stream.ToArray(); var entry = await _coordinationManager.GetOrCreateAsync(path, payload, EntryCreationModes.Ephemeral, cancellation); } }
// This does not receive a cancellation token, as the result of this is cached and must not depend on a callers cancellation token. private async Task WaitForDisconnectCoreAsync(EndPointAddress endPoint) { var disposalSource = _disposalSource; // Volatile read op. if (disposalSource.IsCancellationRequested) { throw new ObjectDisposedException(GetType().FullName); } var disposal = disposalSource.Token; try { var path = GetPath(endPoint); var entry = await _coordinationManager.GetAsync(path, disposal); while (entry != null) { var now = _dateTimeProvider.GetCurrentTime(); var(_, leaseEnd) = DecodePayload(entry.Value.Span); if (now >= leaseEnd) { return; } var timeToWait = leaseEnd - now; await Task.Delay(timeToWait, disposal); entry = await _coordinationManager.GetAsync(path, disposal); } } catch (OperationCanceledException) { throw new ObjectDisposedException(GetType().FullName); } }
private static CoordinationEntryPath GetPrefixPath(ReadOnlyMemory <char> prefix, EndPointAddress endPoint, Session session, bool normalize = true) { if (normalize) { prefix = NormalizePrefix(prefix); } var uniqueEntryName = IdGenerator.GenerateId(endPoint.ToString(), session.ToString()); return(_rootPrefixesPath.GetChildPath(prefix, uniqueEntryName.AsMemory())); }
public async Task <(IMessage response, bool handled)> SendAsync(IMessage message, EndPointAddress remoteEndPoint, CancellationToken cancellation = default) { var proxy = await GetProxyAsync(cancellation); var buffer = new byte[message.Length]; using (var stream = new MemoryStream(buffer, writable: true)) { await message.WriteAsync(stream, cancellation); } var responseBuffer = await proxy.ExecuteAsync(p => p.SendAsync(buffer, remoteEndPoint, cancellation)); var response = new Message(); using (var stream = new MemoryStream(responseBuffer)) { await response.ReadAsync(stream, cancellation); } bool handled; using (var stream = response.PopFrame().OpenStream()) using (var reader = new BinaryReader(stream)) { handled = reader.ReadBoolean(); } response.Trim(); return(response, handled); }
private async Task <bool> ValidateClientCoreAsync(EndPointAddress endPoint, string securityToken, CancellationToken cancellation) { var now = _dateTimeProvider.GetCurrentTime(); var path = GetPath(endPoint); do { var entry = await _coordinationManager.GetAsync(path, cancellation : cancellation); if (entry == null) { _logger?.LogDebug($"Cannot update session for client with end-point '{endPoint.ToString()}'. Session is terminated."); return(false); } var(comparandSecurityToken, leaseEnd) = DecodePayload(entry.Value.Span); // We have to assume that the client is not connected anymore. // This is a race condition, that has to be prevented. if (now >= leaseEnd) { await _coordinationManager.DeleteAsync(entry.Path, cancellation : cancellation); _logger?.LogDebug($"Session for client with end-point '{endPoint.ToString()}' is terminated. Removing entry."); _logger?.LogDebug($"Cannot update session for client with end-point '{endPoint.ToString()}'. Session is terminated."); return(false); } if (securityToken != comparandSecurityToken) { _logger?.LogDebug($"Cannot update session for client with end-point '{endPoint.ToString()}'. Session is terminated."); return(false); } var newLeaseEnd = now + Timeout; if (newLeaseEnd > leaseEnd) { leaseEnd = newLeaseEnd; } var securityTokenBytesCount = Encoding.UTF8.GetByteCount(securityToken); using (ArrayPool <byte> .Shared.Rent(8 + 4 + securityTokenBytesCount, out var bytes)) { var payloadLength = EncodePayload(bytes, securityToken.AsSpan(), leaseEnd); var payload = bytes.AsMemory().Slice(start: 0, payloadLength); endPoint = new EndPointAddress("client/" + Guid.NewGuid().ToString()); var version = await _coordinationManager.SetValueAsync(path, payload, version : entry.Version, cancellation : cancellation); if (version == entry.Version) { _logger?.LogDebug($"Updated session for client with end-point '{endPoint.ToString()}'."); return(true); } } }while (true); }
private CoordinationEntryPath GetPath(EndPointAddress endPoint) { return(BasePath.GetChildPath(endPoint.ToString())); }
private async Task <IDispatchResult> DispatchToEndPointAsync(EndPointAddress endPoint, ModuleHttpRequest moduleHttpRequest, CancellationToken cancellation) { return(await _dispatcher.DispatchAsync(new DispatchDataDictionary <ModuleHttpRequest>(moduleHttpRequest), publish : false, endPoint, cancellation)); }
private static void EncodeRouteRequest(IMessage message, Route route, bool publish, EndPointAddress endPoint) { var routeBytes = Encoding.UTF8.GetBytes(route.ToString()); using (var stream = message.PushFrame().OpenStream()) using (var writer = new BinaryWriter(stream)) { writer.Write((short)MessageType.RouteToEndPoint); writer.Write((short)0); writer.Write(routeBytes.Length); writer.Write(routeBytes); writer.Write(endPoint); writer.Write(publish); } }
public EndPointDisconnected(EndPointAddress endPoint) { EndPoint = endPoint; }
public DebugModuleProperties(EndPointAddress endPoint, ModuleIdentifier module, ModuleVersion version) { EndPoint = endPoint; Module = module; Version = version; }
public Task <(IMessage message, bool handled)> SendAsync(IMessage message, EndPointAddress remoteEndPoint, CancellationToken cancellation = default) { return(_reqRplyEndPoint.SendAsync(new Packet <EndPointAddress>(message, remoteEndPoint), cancellation)); }