public IActionResult Bootstrap([FromBody] BootstrapDTO serviceDto) { if (!this.ModelState.IsValid) { this.logger.LogWarning($"Received a request for {nameof(this.Bootstrap)} with an invalid DTO. {this.ModelState.ErrorCount} errors."); return(this.BadRequest(this.ModelState)); } if (!this.protocolNegotiator.TryChooseProtocol(serviceDto.SupportedProtocols, out uint chosenProtocol)) { return(new StatusCodeResult((int)HttpStatusCode.Conflict)); } var session = this.serviceManager.RegisterService(serviceDto.Hostname, serviceDto.NAMEEndpoint, serviceDto.NAMEPort, serviceDto.AppName, serviceDto.AppVersion, serviceDto.NAMEVersion); return(this.Ok(new BootstrapResultDto { Protocol = chosenProtocol, SessionId = session.CurrentSession.Id })); }
private async Task Bootstrap() { // safeguard if (this.settings.RunningMode >= SupportedNAMEBehaviours.BootstrapDisabled) { return; } var announceInfo = new BootstrapDTO { AppName = this.ApiName, AppVersion = this.ApiVersion, Hostname = this.Hostname, SupportedProtocols = this.SupportedProtocols, NAMEVersion = this.NameVersion, NAMEEndpoint = this.NameEndpoint, NAMEPort = this.Port }; do { foreach (var registryEndpoint in this.settings.RegistryEndpoints) { BootstrapResultDto bootstrapData = null; Func <CancellationToken, Task <BootstrapResultDto> > bootstrapTaskFunction = async(token) => { try { HttpWebRequest request = GetWebRequest(registryEndpoint + "/registrar"); var serializer = new DataContractJsonSerializer(typeof(BootstrapDTO)); var deserializer = new DataContractJsonSerializer(typeof(BootstrapResultDto)); using (Stream stream = await request.GetRequestStreamAsync().ConfigureAwait(false)) { serializer.WriteObject(stream, announceInfo); } token.ThrowIfCancellationRequested(); using (HttpWebResponse response = await request.GetResponseAsync().ConfigureAwait(false) as HttpWebResponse) { token.ThrowIfCancellationRequested(); if (response == null) { LogWarning("Cannot register with " + registryEndpoint, true); return(null); } if (response.StatusCode == HttpStatusCode.Conflict) { LogWarning($"Cannot register with {registryEndpoint}. The server did not accept any protocol.", true); return(null); } var result = deserializer.ReadObject(response.GetResponseStream()) as BootstrapResultDto; if (result == null) { LogWarning("Could not deserialize the Boostrap Result.", true); } return(result); } } catch (Exception ex) { LogWarning($"Could not register with {registryEndpoint}: {ex.Message}", true); return(null); } }; var cancellationTokenSource = new CancellationTokenSource(); Task <BootstrapResultDto> bootstrapTask = bootstrapTaskFunction(cancellationTokenSource.Token); if (await Task.WhenAny(bootstrapTask, Task.Delay(this.settings.RegistryBootstrapTimeout)) == bootstrapTask) { // The bootstrap task finished before the timeout. cancellationTokenSource.Cancel(); bootstrapData = await bootstrapTask; } else { // The bootstrap task took longer then the timeout cancellationTokenSource.Cancel(); LogInfo($"The bootstrap timedout for registry {registryEndpoint}.", true); continue; } if (bootstrapData == null) { continue; } this.Protocol = bootstrapData.Protocol; this.SessionId = bootstrapData.SessionId; this.RegistryEndpoint = registryEndpoint; if (this.SupportedProtocols.Contains(this.Protocol) == false) { LogWarning("Given protocol is not supported", true); continue; } if (bootstrapData.Overrides == null) { break; } // process overrides var overrides = bootstrapData.Overrides; if (overrides.RunningMode > this.settings.RunningMode) { this.settings.RunningMode = overrides.RunningMode; } if (overrides.RegistryEndpoints.Length > 0) { this.settings.RegistryEndpoints = overrides.RegistryEndpoints; } if (overrides.ConnectedDependencyShowConnectionString) { this.settings.ConnectedDependencyShowConnectionString = true; } if (overrides.DependencyConnectTimeout > 0) { this.settings.DependencyConnectTimeout = overrides.DependencyConnectTimeout; } if (overrides.DependencyReadWriteTimeout > 0) { this.settings.DependencyReadWriteTimeout = overrides.DependencyReadWriteTimeout; } if (overrides.RegistryPingFrequency != null && overrides.RegistryPingFrequency != TimeSpan.Zero) { this.settings.RegistryPingFrequency = overrides.RegistryPingFrequency; } if (overrides.RegistryReAnnounceFrequency != null && overrides.RegistryReAnnounceFrequency != TimeSpan.Zero) { this.settings.RegistryReAnnounceFrequency = overrides.RegistryReAnnounceFrequency; } if (overrides.ServiceDependencyMaxHops > 0) { this.settings.ServiceDependencyMaxHops = overrides.ServiceDependencyMaxHops; } //all done break; } if (this.RegistryEndpoint == null) { var msg = $"Could not register with any registry. Waiting { this.settings.RegistryBootstrapRetryFrequency } to try again."; LogWarning(msg, true); await Task.Delay(this.settings.RegistryBootstrapRetryFrequency).ConfigureAwait(false); } else { LogInfo($"Bootstrapped in the registry with endpoint {this.RegistryEndpoint}.", true); } }while (this.RegistryEndpoint == null); }