Example #1
0
        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
            }));
        }
Example #2
0
        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);
        }