public async void SendHeartBeatAsync_InvokesServer_ReturnsStatusCodeAndHeaders() { var startup = new TestConfigServerStartup("", 200); var server = TestServer.Create(startup.Configure); var uri = "http://localhost:8888/"; server.BaseAddress = new Uri(uri); EurekaInstanceConfig config = new EurekaInstanceConfig() { AppName = "foo", InstanceId = "id1" }; InstanceInfo info = InstanceInfo.FromInstanceConfig(config); var cconfig = new EurekaClientConfig() { EurekaServerServiceUrls = uri }; var client = new EurekaHttpClient(cconfig, server.CreateClient()); EurekaHttpResponse <InstanceInfo> resp = await client.SendHeartBeatAsync("foo", "id1", info, InstanceStatus.UNKNOWN); Assert.NotNull(resp); Assert.Equal(HttpStatusCode.OK, resp.StatusCode); Assert.NotNull(resp.Headers); Assert.Equal("PUT", startup.LastRequest.Method); Assert.Equal("localhost:8888", startup.LastRequest.Host.Value); Assert.Equal("/apps/FOO/id1", startup.LastRequest.Path.Value); var time = DateTimeConversions.ToJavaMillis(new DateTime(info.LastDirtyTimestamp, DateTimeKind.Utc)); Assert.Equal("?status=STARTING&lastDirtyTimestamp=" + time, startup.LastRequest.QueryString.Value); }
public async void StatusUpdateAsync_InvokesServer_ReturnsStatusCodeAndHeaders() { var startup = new TestConfigServerStartup("", 200); var server = TestServer.Create(startup.Configure); var uri = "http://localhost:8888/"; server.BaseAddress = new Uri(uri); var cconfig = new EurekaClientConfig() { EurekaServerServiceUrls = uri }; var client = new EurekaHttpClient(cconfig, server.CreateClient()); var now = DateTime.UtcNow.Ticks; var javaTime = DateTimeConversions.ToJavaMillis(new DateTime(now, DateTimeKind.Utc)); EurekaHttpResponse resp = await client.StatusUpdateAsync("foo", "bar", InstanceStatus.DOWN, new InstanceInfo() { LastDirtyTimestamp = now }); Assert.NotNull(resp); Assert.Equal(HttpStatusCode.OK, resp.StatusCode); Assert.NotNull(resp.Headers); Assert.Equal("PUT", startup.LastRequest.Method); Assert.Equal("localhost:8888", startup.LastRequest.Host.Value); Assert.Equal("/apps/foo/bar/status", startup.LastRequest.Path.Value); Assert.Equal("?value=DOWN&lastDirtyTimestamp=" + javaTime, startup.LastRequest.QueryString.Value); }
private static AgentServiceCheck CreateCheck(ConsulDiscoveryOptions options, HeartbeatOptions heartbeatOptions) { if (!options.RegisterHealthCheck) { return(null); } TimeSpan?deregisterCriticalServiceAfter = null; TimeSpan?timeout = null; if (!string.IsNullOrWhiteSpace(options.HealthCheckTimeout)) { timeout = DateTimeConversions.ToTimeSpan(options.HealthCheckTimeout); } if (!string.IsNullOrWhiteSpace(options.HealthCheckCriticalTimeout)) { deregisterCriticalServiceAfter = DateTimeConversions.ToTimeSpan(options.HealthCheckCriticalTimeout); } var check = new AgentServiceCheck { Timeout = timeout, DeregisterCriticalServiceAfter = deregisterCriticalServiceAfter }; if (heartbeatOptions.Enable) { return(SetHeartbeat(check, heartbeatOptions) ? check : null); } return(SetHttpCheck(check, options) ? check : null); }
private static void AddConsulServices(IServiceCollection services, IDiscoveryLifecycle lifecycle) { services.AddSingleton(s => { var consulOptions = s.GetRequiredService <IOptions <ConsulOptions> >().Value; return(new ConsulClient(options => { options.Address = new Uri($"{consulOptions.Scheme}://{consulOptions.Host}:{consulOptions.Port}"); options.Datacenter = consulOptions.Datacenter; options.Token = consulOptions.Token; if (!string.IsNullOrWhiteSpace(consulOptions.WaitTime)) { options.WaitTime = DateTimeConversions.ToTimeSpan(consulOptions.WaitTime); } })); }); services.AddSingleton <TtlScheduler>(); services.AddSingleton <ConsulDiscoveryClient>(); services.AddSingleton <ConsulServiceRegistry>(); if (lifecycle == null) { services.AddSingleton <IDiscoveryLifecycle, ApplicationLifecycle>(); } else { services.AddSingleton(lifecycle); } services.AddSingleton <IDiscoveryClient>(p => p.GetService <ConsulDiscoveryClient>()); }
/// <summary> /// Create a Consul client using the provided configuration options /// </summary> /// <param name="options">the configuration options</param> /// <returns>a Consul client</returns> public static IConsulClient CreateClient(ConsulOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } var client = new ConsulClient(s => { s.Address = new Uri($"{options.Scheme}://{options.Host}:{options.Port}"); s.Token = options.Token; s.Datacenter = options.Datacenter; if (!string.IsNullOrEmpty(options.WaitTime)) { s.WaitTime = DateTimeConversions.ToTimeSpan(options.WaitTime); } if (!string.IsNullOrEmpty(options.Password) || !string.IsNullOrEmpty(options.Username)) { #pragma warning disable CS0618 // Type or member is obsolete s.HttpAuth = new NetworkCredential(options.Username, options.Password); #pragma warning restore CS0618 // Type or member is obsolete } }); return(client); }
internal JsonInstanceInfo ToJsonInstance() { JsonInstanceInfo jinfo = new JsonInstanceInfo(); jinfo.InstanceId = this.InstanceId; jinfo.Sid = (this.Sid == null) ? "na" : this.Sid; jinfo.AppName = this.AppName; jinfo.AppGroupName = this.AppGroupName; jinfo.IpAddr = this.IpAddr; jinfo.Port = new JsonInstanceInfo.JsonPortWrapper(this.IsUnsecurePortEnabled, this.Port); jinfo.SecurePort = new JsonInstanceInfo.JsonPortWrapper(this.IsSecurePortEnabled, this.SecurePort); jinfo.HomePageUrl = this.HomePageUrl; jinfo.StatusPageUrl = this.StatusPageUrl; jinfo.HealthCheckUrl = this.HealthCheckUrl; jinfo.SecureHealthCheckUrl = this.SecureHealthCheckUrl; jinfo.VipAddress = this.VipAddress; jinfo.SecureVipAddress = this.SecureVipAddress; jinfo.CountryId = this.CountryId; jinfo.DataCenterInfo = (this.DataCenterInfo == null) ? null : ((AppInfo.DataCenterInfo)DataCenterInfo).ToJson(); jinfo.HostName = this.HostName; jinfo.Status = this.Status; jinfo.OverriddenStatus = this.OverriddenStatus; jinfo.LeaseInfo = (this.LeaseInfo == null) ? null : this.LeaseInfo.ToJson(); jinfo.IsCoordinatingDiscoveryServer = this.IsCoordinatingDiscoveryServer; jinfo.LastUpdatedTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(this.LastUpdatedTimestamp, DateTimeKind.Utc)); jinfo.LastDirtyTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(this.LastDirtyTimestamp, DateTimeKind.Utc)); jinfo.Actiontype = this.Actiontype; jinfo.AsgName = this.AsgName; jinfo.Metadata = (this.Metadata.Count == 0) ? new Dictionary <string, string>() { { "@class", "java.util.Collections$EmptyMap" } } : this.Metadata; return(jinfo); }
public async System.Threading.Tasks.Task StatusUpdateAsync_InvokesServer_ReturnsStatusCodeAndHeaders() { var envir = HostingHelpers.GetHostingEnvironment(); TestConfigServerStartup.Response = string.Empty; TestConfigServerStartup.ReturnStatus = 200; var builder = new WebHostBuilder().UseStartup <TestConfigServerStartup>().UseEnvironment(envir.EnvironmentName); var server = new TestServer(builder); var uri = "http://localhost:8888/"; server.BaseAddress = new Uri(uri); var cconfig = new EurekaClientConfig() { EurekaServerServiceUrls = uri }; var client = new EurekaHttpClient(cconfig, server.CreateClient()); var now = DateTime.UtcNow.Ticks; var javaTime = DateTimeConversions.ToJavaMillis(new DateTime(now, DateTimeKind.Utc)); var resp = await client.StatusUpdateAsync("foo", "bar", InstanceStatus.DOWN, new InstanceInfo() { LastDirtyTimestamp = now }); Assert.NotNull(resp); Assert.Equal(HttpStatusCode.OK, resp.StatusCode); Assert.NotNull(resp.Headers); Assert.Equal("PUT", TestConfigServerStartup.LastRequest.Method); Assert.Equal("localhost:8888", TestConfigServerStartup.LastRequest.Host.Value); Assert.Equal("/apps/foo/bar/status", TestConfigServerStartup.LastRequest.Path.Value); Assert.Equal("?value=DOWN&lastDirtyTimestamp=" + javaTime, TestConfigServerStartup.LastRequest.QueryString.Value); Assert.Equal("http://localhost:8888/", client._serviceUrl); }
public virtual async Task <EurekaHttpResponse> StatusUpdateAsync(string appName, string id, InstanceStatus newStatus, InstanceInfo info) { if (string.IsNullOrEmpty(appName)) { throw new ArgumentException(nameof(appName)); } if (string.IsNullOrEmpty(id)) { throw new ArgumentException(nameof(id)); } if (info == null) { throw new ArgumentNullException(nameof(info)); } var queryArgs = new Dictionary <string, string>() { { "value", newStatus.ToString() }, { "lastDirtyTimestamp", DateTimeConversions.ToJavaMillis(new DateTime(info.LastDirtyTimestamp, DateTimeKind.Utc)).ToString() } }; HttpClient client = GetHttpClient(_config); var requestUri = GetRequestUri(_serviceUrl + "apps/" + appName + "/" + id + "/status", queryArgs); var request = GetRequestMessage(HttpMethod.Put, requestUri); #if NET452 // If certificate validation is disabled, inject a callback to handle properly RemoteCertificateValidationCallback prevValidator = null; if (!_config.ValidateCertificates) { prevValidator = ServicePointManager.ServerCertificateValidationCallback; ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; } #endif try { using (HttpResponseMessage response = await client.SendAsync(request)) { _logger?.LogDebug("StatusUpdateAsync {0}, status: {1}", requestUri.ToString(), response.StatusCode); EurekaHttpResponse resp = new EurekaHttpResponse(response.StatusCode); resp.Headers = response.Headers; return(resp); } } catch (Exception e) { _logger?.LogError("StatusUpdateAsync Exception: {0}", e); throw; } finally { DisposeHttpClient(client); #if NET452 ServicePointManager.ServerCertificateValidationCallback = prevValidator; #endif } }
public async void DeleteStatusOverrideAsync_InvokesServer_ReturnsStatusCodeAndHeaders() { IHostingEnvironment envir = new HostingEnvironment(); TestConfigServerStartup.Response = ""; TestConfigServerStartup.ReturnStatus = 200; var builder = new WebHostBuilder().UseStartup <TestConfigServerStartup>().UseEnvironment(envir.EnvironmentName); var server = new TestServer(builder); var uri = "http://localhost:8888/"; server.BaseAddress = new Uri(uri); var cconfig = new EurekaClientConfig() { EurekaServerServiceUrls = uri }; var client = new EurekaHttpClient(cconfig, server.CreateClient()); var now = DateTime.UtcNow.Ticks; var javaTime = DateTimeConversions.ToJavaMillis(new DateTime(now, DateTimeKind.Utc)); EurekaHttpResponse resp = await client.DeleteStatusOverrideAsync("foo", "bar", new InstanceInfo() { LastDirtyTimestamp = now }); Assert.NotNull(resp); Assert.Equal(HttpStatusCode.OK, resp.StatusCode); Assert.NotNull(resp.Headers); Assert.Equal("DELETE", TestConfigServerStartup.LastRequest.Method); Assert.Equal("localhost:8888", TestConfigServerStartup.LastRequest.Host.Value); Assert.Equal("/apps/foo/bar/status", TestConfigServerStartup.LastRequest.Path.Value); Assert.Equal("?lastDirtyTimestamp=" + javaTime, TestConfigServerStartup.LastRequest.QueryString.Value); }
public void ToJavaMillis_Throws_IfNotUTC() { DateTime dt = new DateTime(2016, 3, 14, 16, 42, 21, DateTimeKind.Local).AddMilliseconds(708); var ex = Assert.Throws <ArgumentException>(() => DateTimeConversions.ToJavaMillis(dt)); Assert.Contains("Kind != UTC", ex.Message); }
public void ToJavaMillis() { DateTime dt = new DateTime(2016, 3, 14, 16, 42, 21, DateTimeKind.Utc).AddMilliseconds(708); long millis = DateTimeConversions.ToJavaMillis(dt); Assert.Equal(1457973741708, millis); }
// "/eureka/apps/{appName}/{instanceID}/status?value={status}&lastDirtyTimestamp=1568746948343" public ActionResult <string> ChangeInstanceStatus([FromRoute] string appName, [FromRoute] string instanceID, [FromQuery] string value, [FromQuery] long lastDirtyTimestamp, [FromServices] IPublishChangesService publishService, [FromServices] IMemoryDiscoveryClientRepository clientRepo, [FromServices] IPublishClientsService clientPublishService) { var tenantId = this.GetTenantIdFromRouteData(); var clientHostname = Request.HttpContext.Connection.RemoteIpAddress.ToString(); clientRepo.Add(new DiscoveryClient(clientHostname)); clientPublishService.PublishClientDiscoveryActivity(tenantId, clientHostname); MemoryServicesRepository repo = new MemoryServicesRepository(tenantId, Program.InstanceConfig.EvictionInSecs); if (lastDirtyTimestamp == 0) { lastDirtyTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); } var instance = repo.ChangeStatus(appName, instanceID, value, lastDirtyTimestamp); if (instance != null) { publishService.PublishInstanceStatusChange(instance.TenantId, appName, instanceID, value, lastDirtyTimestamp); this.HttpContext.Response.StatusCode = 200; } else { this.HttpContext.Response.StatusCode = 500; } return(string.Empty); }
public void ToJson_Correct() { JsonLeaseInfo jinfo = new JsonLeaseInfo() { RenewalIntervalInSecs = 100, DurationInSecs = 200, RegistrationTimestamp = 1457973741708, LastRenewalTimestamp = 1457973741708, LastRenewalTimestampLegacy = 1457973741708, EvictionTimestamp = 1457973741708, ServiceUpTimestamp = 1457973741708 }; LeaseInfo result = LeaseInfo.FromJson(jinfo); jinfo = result.ToJson(); Assert.Equal(100, result.RenewalIntervalInSecs); Assert.Equal(200, result.DurationInSecs); Assert.Equal(1457973741708, DateTimeConversions.ToJavaMillis(new DateTime(result.RegistrationTimestamp, DateTimeKind.Utc))); Assert.Equal(1457973741708, DateTimeConversions.ToJavaMillis(new DateTime(result.LastRenewalTimestamp, DateTimeKind.Utc))); Assert.Equal(1457973741708, DateTimeConversions.ToJavaMillis(new DateTime(result.LastRenewalTimestampLegacy, DateTimeKind.Utc))); Assert.Equal(1457973741708, DateTimeConversions.ToJavaMillis(new DateTime(result.EvictionTimestamp, DateTimeKind.Utc))); Assert.Equal(1457973741708, DateTimeConversions.ToJavaMillis(new DateTime(result.ServiceUpTimestamp, DateTimeKind.Utc))); }
public virtual async Task <EurekaHttpResponse> DeleteStatusOverrideAsync(string appName, string id, InstanceInfo info) { if (string.IsNullOrEmpty(appName)) { throw new ArgumentException(nameof(appName)); } if (string.IsNullOrEmpty(id)) { throw new ArgumentException(nameof(id)); } if (info == null) { throw new ArgumentNullException(nameof(info)); } var queryArgs = new Dictionary <string, string>() { { "lastDirtyTimestamp", DateTimeConversions.ToJavaMillis(new DateTime(info.LastDirtyTimestamp, DateTimeKind.Utc)).ToString() } }; HttpClient client = GetHttpClient(_config); var requestUri = GetRequestUri(_serviceUrl + "apps/" + appName + "/" + id + "/status", queryArgs); var request = GetRequestMessage(HttpMethod.Delete, requestUri); #if NET452 // If certificate validation is disabled, inject a callback to handle properly RemoteCertificateValidationCallback prevValidator = null; SecurityProtocolType prevProtocols = (SecurityProtocolType)0; ConfigureCertificateValidatation(out prevProtocols, out prevValidator); #endif try { using (HttpResponseMessage response = await client.SendAsync(request)) { _logger?.LogDebug("DeleteStatusOverrideAsync {0}, status: {1}", requestUri.ToString(), response.StatusCode); EurekaHttpResponse resp = new EurekaHttpResponse(response.StatusCode); resp.Headers = response.Headers; return(resp); } } catch (Exception e) { _logger?.LogError("DeleteStatusOverrideAsync Exception: {0}", e); throw; } finally { DisposeHttpClient(client); #if NET452 RestoreCertificateValidation(prevProtocols, prevValidator); #endif } }
public void ToTimeSpan_ReturnsExpected() { Assert.Throws <ArgumentNullException>(() => DateTimeConversions.ToTimeSpan(string.Empty)); Assert.Throws <InvalidOperationException>(() => DateTimeConversions.ToTimeSpan("foobar")); Assert.Equal(TimeSpan.FromMilliseconds(1000), DateTimeConversions.ToTimeSpan("1000ms")); Assert.Equal(TimeSpan.FromSeconds(1000), DateTimeConversions.ToTimeSpan("1000s")); Assert.Equal(TimeSpan.FromHours(1), DateTimeConversions.ToTimeSpan("1h")); Assert.Equal(TimeSpan.FromMinutes(1), DateTimeConversions.ToTimeSpan("1m")); Assert.Equal(TimeSpan.FromMilliseconds(1000), DateTimeConversions.ToTimeSpan("1000Ms")); Assert.Equal(TimeSpan.FromSeconds(1000), DateTimeConversions.ToTimeSpan("1000S")); Assert.Equal(TimeSpan.FromHours(1), DateTimeConversions.ToTimeSpan("1H")); Assert.Equal(TimeSpan.FromMinutes(1), DateTimeConversions.ToTimeSpan("1M")); }
public void FromJavaMillis() { long millis = 1457973741708; DateTime dt = DateTimeConversions.FromJavaMillis(millis); Assert.Equal(3, dt.Month); Assert.Equal(14, dt.Day); Assert.Equal(2016, dt.Year); Assert.Equal(16, dt.Hour); Assert.Equal(42, dt.Minute); Assert.Equal(21, dt.Second); Assert.Equal(708, dt.Millisecond); }
// "/eureka/apps/{appName}/{instanceID}?status=UP&lastDirtyTimestamp=1568804226113" public ActionResult <string> ReceiveInstanceHeartbeat([FromRoute] string appName, [FromRoute] string instanceID, [FromQuery] long lastDirtyTimestamp, [FromServices] IPublishChangesService publishService, [FromServices] IMemoryDiscoveryClientRepository clientRepo, [FromServices] IPublishClientsService clientPublishService) { var tenantId = this.GetTenantIdFromRouteData(); var clientHostname = Request.HttpContext.Connection.RemoteIpAddress.ToString(); clientRepo.Add(new DiscoveryClient(clientHostname)); clientPublishService.PublishClientDiscoveryActivity(tenantId, clientHostname); MemoryServicesRepository repo = new MemoryServicesRepository(this.GetTenantIdFromRouteData(), Program.InstanceConfig.EvictionInSecs); var status = string.Empty; if (lastDirtyTimestamp == 0) { lastDirtyTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); } if (Request.QueryString.Value.ToString().IndexOf("status") >= 0) { // status change request var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(Request.QueryString.Value.ToString()); var items = queryDictionary.SelectMany(x => x.Value, (col, value) => new KeyValuePair <string, string>(col.Key, value)).ToList(); var statusItem = items.SingleOrDefault(q => q.Key.CompareTo("status") == 0); if (statusItem.Key != null) { status = statusItem.Value; } var dirtyItem = items.SingleOrDefault(q => q.Key.CompareTo("lastDirtyTimestamp") == 0); if (dirtyItem.Key != null) { lastDirtyTimestamp = Convert.ToInt64(dirtyItem.Value); } } var instance = repo.SaveInstanceHearbeat(appName, instanceID, status, lastDirtyTimestamp); if (instance != null) { publishService.PublishAddedOrUpdatedInstance(instance, "UPDATE_INSTANCE"); this.HttpContext.Response.StatusCode = 200; } else { this.HttpContext.Response.StatusCode = 404; } return(string.Empty); }
internal TimeSpan ComputeHearbeatInterval() { var second = TimeSpan.FromSeconds(1); var ttl = DateTimeConversions.ToTimeSpan(TtlValue, TtlUnit); // heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser priority), // no sooner than 1s from now var interval = ttl * IntervalRatio; var max = interval > second ? interval : second; var ttlMinus1sec = ttl - second; var min = ttlMinus1sec < max ? ttlMinus1sec : max; return(min); }
public async Task <EurekaHttpResponse> StatusUpdateAsync(string appName, string id, InstanceStatus newStatus, InstanceInfo info) { if (string.IsNullOrEmpty(appName)) { throw new ArgumentException(nameof(appName)); } if (string.IsNullOrEmpty(id)) { throw new ArgumentException(nameof(id)); } if (info == null) { throw new ArgumentNullException(nameof(info)); } var queryArgs = new Dictionary <string, string>() { { "value", newStatus.ToString() }, { "lastDirtyTimestamp", DateTimeConversions.ToJavaMillis(new DateTime(info.LastDirtyTimestamp, DateTimeKind.Utc)).ToString() } }; HttpClient client = GetHttpClient(_config); var requestUri = GetRequestUri(_serviceUrl + "apps/" + Uri.EscapeDataString(appName) + "/" + Uri.EscapeDataString(id) + "/status", queryArgs); var request = GetRequestMessage(HttpMethod.Put, requestUri); try { using (HttpResponseMessage response = await client.SendAsync(request)) { Trace.TraceInformation("StatusUpdateAsync {0}, status: {1}", requestUri.ToString(), response.StatusCode); EurekaHttpResponse resp = new EurekaHttpResponse(response.StatusCode) { Headers = response.Headers }; return(resp); } } catch (Exception e) { Trace.TraceError("StatusUpdateAsync Exception: {0}", e); throw; } finally { DisposeHttpClient(client); } }
public JsonLeaseInfo ToJson() { JsonLeaseInfo jinfo = new JsonLeaseInfo() { RenewalIntervalInSecs = this.RenewalIntervalInSecs, DurationInSecs = this.DurationInSecs, RegistrationTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(this.RegistrationTimestamp, DateTimeKind.Utc)), LastRenewalTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(this.LastRenewalTimestamp, DateTimeKind.Utc)), LastRenewalTimestampLegacy = DateTimeConversions.ToJavaMillis(new DateTime(this.LastRenewalTimestampLegacy, DateTimeKind.Utc)), EvictionTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(this.EvictionTimestamp, DateTimeKind.Utc)), ServiceUpTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(this.ServiceUpTimestamp, DateTimeKind.Utc)) }; return(jinfo); }
internal JsonLeaseInfo ToJson() { var jinfo = new JsonLeaseInfo() { RenewalIntervalInSecs = RenewalIntervalInSecs, DurationInSecs = DurationInSecs, RegistrationTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(RegistrationTimestamp, DateTimeKind.Utc)), LastRenewalTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(LastRenewalTimestamp, DateTimeKind.Utc)), LastRenewalTimestampLegacy = DateTimeConversions.ToJavaMillis(new DateTime(LastRenewalTimestampLegacy, DateTimeKind.Utc)), EvictionTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(EvictionTimestamp, DateTimeKind.Utc)), ServiceUpTimestamp = DateTimeConversions.ToJavaMillis(new DateTime(ServiceUpTimestamp, DateTimeKind.Utc)) }; return(jinfo); }
private static void OnTimedEvent(Object source, ElapsedEventArgs e) { //Console.WriteLine("Eviction Service cleans at {0:HH:mm:ss.fff}", e.SignalTime); // evict outdated peers var peersEvicted = _memoryDiscoveryPeerRepository.EvictPeers(Program.InstanceConfig.PeerEvictionInSecs); //Console.WriteLine("Peers evicted {0}", peersEvicted); // evict outdated instances for all tenants lock (ServicesRuntime.AllApplications.Applications) { foreach (var app in ServicesRuntime.AllApplications.Applications) { List <Instance> instancesToRemove = new List <Instance>(); foreach (var instance in app.Instances) { var instanceLastUpdate = DateTimeConversions.FromJavaMillis(instance.LastUpdatedTimestamp); // if no heartbeat first take down instance if (instanceLastUpdate.AddSeconds(Program.InstanceConfig.EvictionInSecs) < DateTime.UtcNow) { ServicesRuntime.AllApplications.VersionsDelta += 1; instance.Status = "DOWN"; } // if no heartbeat after the DOWN Duration then avict the instance if (instanceLastUpdate.AddSeconds(Program.InstanceConfig.EvictionInSecs + Program.InstanceConfig.DurationInSecs) < DateTime.UtcNow) { instancesToRemove.Add(instance); } } if (instancesToRemove.Count > 0) { foreach (var inst in instancesToRemove) { app.Instances.Remove(inst); } // increase version after eviction ServicesRuntime.AllApplications.VersionsDelta += 1; } //Console.WriteLine("For app '{0}' instances evicted {1}", app.Name, instancesToRemove.Count); } } }
public Instance Add(Instance instance) { var appId = instance.AppName; var appFound = ServicesRuntime.AllApplications.Applications.SingleOrDefault(a => a.TenantId.CompareTo(repoTenantId) == 0 && a.Name.CompareTo(appId) == 0); if (appFound == null) { appFound = new Application() { TenantId = repoTenantId, Name = appId, Instances = new List <Instance>() }; ServicesRuntime.AllApplications.Applications.Add(appFound); } instance.TenantId = repoTenantId; instance.Status = "STARTING"; instance.ActionType = "ADDED"; if (string.IsNullOrEmpty(instance.InstanceId)) { instance.InstanceId = instance.HostName; } instance.LastDirtyTimestamp = instance.LastUpdatedTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); instance.LeaseInfo.RegistrationTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); instance.LeaseInfo.LastRenewalTimestamp = instance.LeaseInfo.RegistrationTimestamp; instance.LeaseInfo.EvictionTimestamp = instance.LeaseInfo.LastRenewalTimestamp + this._evictionInSeconds * DateTimeConversions.TicksPerSecond; instance.LeaseInfo.ServiceUpTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); var existingInstance = appFound.Instances.SingleOrDefault(i => i.TenantId.CompareTo(repoTenantId) == 0 && i.InstanceId.CompareTo(instance.InstanceId) == 0); if (existingInstance != null) { Delete(existingInstance.AppName, existingInstance.InstanceId); } appFound.Instances.Add(instance); IncreaseVersion(); return(instance); }
internal static LeaseInfo FromJson(JsonLeaseInfo jinfo) { LeaseInfo info = new LeaseInfo(); if (jinfo != null) { info.RenewalIntervalInSecs = jinfo.RenewalIntervalInSecs; info.DurationInSecs = jinfo.DurationInSecs; info.RegistrationTimestamp = DateTimeConversions.FromJavaMillis(jinfo.RegistrationTimestamp).Ticks; info.LastRenewalTimestamp = DateTimeConversions.FromJavaMillis(jinfo.LastRenewalTimestamp).Ticks; info.LastRenewalTimestampLegacy = DateTimeConversions.FromJavaMillis(jinfo.LastRenewalTimestampLegacy).Ticks; info.EvictionTimestamp = DateTimeConversions.FromJavaMillis(jinfo.EvictionTimestamp).Ticks; info.ServiceUpTimestamp = DateTimeConversions.FromJavaMillis(jinfo.ServiceUpTimestamp).Ticks; } return(info); }
private static bool SetHeartbeat(AgentServiceCheck check, HeartbeatOptions heartbeatOptions) { if (!heartbeatOptions.Enable || heartbeatOptions.TtlValue <= 0 || string.IsNullOrEmpty(heartbeatOptions.TtlUnit)) { return(false); } check.Interval = null; check.HTTP = null; TimeSpan?ttl = DateTimeConversions.ToTimeSpan(heartbeatOptions.TtlValue + heartbeatOptions.TtlUnit); check.TTL = ttl; return(true); }
internal static AgentServiceCheck CreateCheck(int port, ConsulDiscoveryOptions options) { AgentServiceCheck check = new AgentServiceCheck(); if (options.IsHeartBeatEnabled) { check.TTL = DateTimeConversions.ToTimeSpan(options.Heartbeat.Ttl); return(check); } if (port <= 0) { throw new ArgumentException("CreateCheck port must be greater than 0"); } if (!string.IsNullOrEmpty(options.HealthCheckUrl)) { check.HTTP = options.HealthCheckUrl; } else { var uri = new Uri($"{options.Scheme}://{options.HostName}:{port}{options.HealthCheckPath}"); check.HTTP = uri.ToString(); } // check.setHeader(properties.getHealthCheckHeaders()); if (!string.IsNullOrEmpty(options.HealthCheckInterval)) { check.Interval = DateTimeConversions.ToTimeSpan(options.HealthCheckInterval); } if (!string.IsNullOrEmpty(options.HealthCheckTimeout)) { check.Timeout = DateTimeConversions.ToTimeSpan(options.HealthCheckTimeout); } if (!string.IsNullOrEmpty(options.HealthCheckCriticalTimeout)) { check.DeregisterCriticalServiceAfter = DateTimeConversions.ToTimeSpan(options.HealthCheckCriticalTimeout); } check.TLSSkipVerify = options.HealthCheckTlsSkipVerify; return(check); }
public Instance SaveInstanceHearbeat(string appName, string instanceId, string status, long lastDirtyTimestamp) { var app = ServicesRuntime.AllApplications.Applications.SingleOrDefault(a => a.TenantId.CompareTo(repoTenantId) == 0 && a.Name.CompareTo(appName) == 0); int idx = -1; if (app != null) { for (var i = 0; i < app.Instances.Count; i++) { if (app.Instances[i].TenantId.CompareTo(repoTenantId) == 0 && app.Instances[i].InstanceId.CompareTo(instanceId) == 0) { idx = i; app.Instances[i].ActionType = "MODIFIED"; app.Instances[i].Status = status; app.Instances[i].LastDirtyTimestamp = lastDirtyTimestamp; app.Instances[i].LastUpdatedTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); app.Instances[i].LeaseInfo.LastRenewalTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); app.Instances[i].LeaseInfo.EvictionTimestamp = app.Instances[i].LeaseInfo.LastRenewalTimestamp + this._evictionInSeconds * DateTimeConversions.TicksPerSecond; if (status.CompareTo("UP") == 0) { app.Instances[i].LeaseInfo.ServiceUpTimestamp = DateTimeConversions.ToJavaMillis(DateTime.UtcNow); } break; } } if (idx >= 0) { IncreaseVersion(); return(app.Instances[idx]); } } return(null); }
public void CreateCheck_ReturnsExpected() { ConsulDiscoveryOptions options = new ConsulDiscoveryOptions(); var result = ConsulRegistration.CreateCheck(1234, options); Assert.NotNull(result); Assert.Equal(DateTimeConversions.ToTimeSpan(options.Heartbeat.Ttl), result.TTL); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckCriticalTimeout), result.DeregisterCriticalServiceAfter); options.Heartbeat = null; Assert.Throws <ArgumentException>(() => ConsulRegistration.CreateCheck(0, options)); int port = 1234; result = ConsulRegistration.CreateCheck(port, options); var uri = new Uri($"{options.Scheme}://{options.HostName}:{port}{options.HealthCheckPath}"); Assert.Equal(uri.ToString(), result.HTTP); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckInterval), result.Interval); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckTimeout), result.Timeout); Assert.Equal(DateTimeConversions.ToTimeSpan(options.HealthCheckCriticalTimeout), result.DeregisterCriticalServiceAfter); Assert.Equal(options.HealthCheckTlsSkipVerify, result.TLSSkipVerify); }
public async System.Threading.Tasks.Task SendHeartBeatAsync_InvokesServer_ReturnsStatusCodeAndHeaders() { var envir = HostingHelpers.GetHostingEnvironment(); TestConfigServerStartup.Response = string.Empty; TestConfigServerStartup.ReturnStatus = 200; var builder = new WebHostBuilder().UseStartup <TestConfigServerStartup>().UseEnvironment(envir.EnvironmentName); var server = new TestServer(builder); var uri = "http://localhost:8888/"; server.BaseAddress = new Uri(uri); var config = new EurekaInstanceConfig() { AppName = "foo", InstanceId = "id1" }; var info = InstanceInfo.FromInstanceConfig(config); var cconfig = new EurekaClientConfig() { EurekaServerServiceUrls = uri }; var client = new EurekaHttpClient(cconfig, server.CreateClient()); var resp = await client.SendHeartBeatAsync("foo", "id1", info, InstanceStatus.UNKNOWN); Assert.NotNull(resp); Assert.Equal(HttpStatusCode.OK, resp.StatusCode); Assert.NotNull(resp.Headers); Assert.Equal("PUT", TestConfigServerStartup.LastRequest.Method); Assert.Equal("localhost:8888", TestConfigServerStartup.LastRequest.Host.Value); Assert.Equal("/apps/FOO/id1", TestConfigServerStartup.LastRequest.Path.Value); var time = DateTimeConversions.ToJavaMillis(new DateTime(info.LastDirtyTimestamp, DateTimeKind.Utc)); Assert.Equal("?status=STARTING&lastDirtyTimestamp=" + time, TestConfigServerStartup.LastRequest.QueryString.Value); }
internal static InstanceInfo FromJsonInstance(JsonInstanceInfo json) { var info = new InstanceInfo(); if (json != null) { info._sid = json.Sid ?? "na"; info.AppName = json.AppName; info.AppGroupName = json.AppGroupName; info.IpAddr = json.IpAddr; info.Port = (json.Port == null) ? 0 : json.Port.Port; info.IsUnsecurePortEnabled = json.Port != null && json.Port.Enabled; info.SecurePort = (json.SecurePort == null) ? 0 : json.SecurePort.Port; info.IsSecurePortEnabled = json.SecurePort != null && json.SecurePort.Enabled; info.HomePageUrl = json.HomePageUrl; info.StatusPageUrl = json.StatusPageUrl; info.HealthCheckUrl = json.HealthCheckUrl; info.SecureHealthCheckUrl = json.SecureHealthCheckUrl; info.VipAddress = json.VipAddress; info.SecureVipAddress = json.SecureVipAddress; info.CountryId = json.CountryId; info.DataCenterInfo = (json.DataCenterInfo == null) ? null : AppInfo.DataCenterInfo.FromJson(json.DataCenterInfo); info.HostName = json.HostName; info.Status = json.Status; info.OverriddenStatus = json.OverriddenStatus; info.LeaseInfo = LeaseInfo.FromJson(json.LeaseInfo); info.IsCoordinatingDiscoveryServer = json.IsCoordinatingDiscoveryServer; info.LastUpdatedTimestamp = DateTimeConversions.FromJavaMillis(json.LastUpdatedTimestamp).Ticks; info.LastDirtyTimestamp = DateTimeConversions.FromJavaMillis(json.LastDirtyTimestamp).Ticks; info.Actiontype = json.Actiontype; info.AsgName = json.AsgName; info._metaData = GetMetaDataFromJson(json.Metadata); info.InstanceId = GetInstanceIdFromJson(json, info._metaData); } return(info); }