public ServerInfo InsertOrUpdate(ServerRegistration registration) { var currentTime = DateTimeOffset.Now; ServerInfo host; lock (this.serverTable) { if (!this.serverTable.TryGetValue(registration.Hostname, out host)) { Events.Write.AddedRemoteHost(registration.Hostname, registration.Port); host = new ServerInfo(registration); this.serverTable[registration.Hostname] = host; host.LatestCounterTimeUpdated += (server, counterName, timestamp) => { if (this.LatestCounterTimeUpdated != null) { this.LatestCounterTimeUpdated(server, counterName, timestamp); } }; } } host.LastUpdateTime = currentTime; return(host); }
/// <summary> /// Called to 'call home' to ensure the current server has an active record /// </summary> /// <param name="address"></param> public void EnsureActive(string address) { var uow = _uowProvider.GetUnitOfWork(); using (var repo = _repositoryFactory.CreateServerRegistrationRepository(uow)) { //NOTE: we cannot use Environment.MachineName as this does not work in medium trust // found this out in CDF a while back: http://clientdependency.codeplex.com/workitem/13191 var computerName = System.Net.Dns.GetHostName(); var query = Query <ServerRegistration> .Builder.Where(x => x.ComputerName.ToUpper() == computerName.ToUpper()); var found = repo.GetByQuery(query).ToArray(); ServerRegistration server; if (found.Any()) { server = found.First(); server.ServerAddress = address; //This should not really change but it might! server.UpdateDate = DateTime.UtcNow; //Stick with Utc dates since these might be globally distributed server.IsActive = true; } else { server = new ServerRegistration(address, computerName, DateTime.UtcNow); } repo.AddOrUpdate(server); uow.Commit(); } }
public async Task StartExecuteReturnsOkAndAddsHandlerIfPayloadIsValid() { var message = new ServerRegistration { Hostname = "testServer", Port = 867, }; ByteArrayContent payload; using (var ms = new MemoryStream()) using (var writerStream = new WriterStream(ms)) { writerStream.CreateCompactBinaryWriter().Write(message); payload = new ByteArrayContent(ms.GetBuffer()); } var response = await this.httpClient.PostAsync(TestUtils.GetUri(this.server, RegistrationClient.RegistrationEndpoint, string.Empty), payload); Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); Assert.IsNotNull(this.server.ServerList["testServer"]); }
public static ServerRegistration BuildEntity(ServerRegistrationDto dto) { var model = new ServerRegistration(dto.Id, dto.ServerAddress, dto.ServerIdentity, dto.DateRegistered, dto.DateAccessed, dto.IsActive, dto.IsSchedulingPublisher); // reset dirty initial properties (U4-1946) model.ResetDirtyProperties(false); return(model); }
private async void StartRegistration() { IPAddress[] addresses; try { addresses = await Task <IPAddress[]> .Factory.FromAsync(Dns.BeginGetHostAddresses, Dns.EndGetHostAddresses, this.destinationHostname, null); } catch (SocketException e) { Events.Write.RegistrationDestinationResolutionFailed(this.destinationHostname, e.Message); return; } var serverRegistration = new ServerRegistration { Hostname = this.sourceHostname, Port = this.sourcePort, MachineFunction = this.sourceMachineFunction, Datacenter = this.sourceDatacenter, }; foreach (var counter in this.dataManager.Counters) { serverRegistration.Counters.Add( new CounterInfo { Name = counter.Name, Type = counter.Type, Dimensions = counter.Dimensions.ToList(), StartTime = counter.StartTime.ToMillisecondTimestamp(), EndTime = counter.EndTime.ToMillisecondTimestamp(), }); } byte[] payload; using (var ms = new MemoryStream()) using (var writerStream = new WriterStream(ms, this.dataManager.MemoryStreamManager)) { var writer = writerStream.CreateCompactBinaryWriter(); writer.Write(serverRegistration); payload = ms.ToArray(); } foreach (var address in addresses) { this.RegisterWithAddress(address, payload); } lock (this) { if (this.registrationTimer != null) { this.registrationTimer.Change(this.registrationInterval, TimeSpan.Zero); } } }
public ServerRegistration BuildEntity(ServerRegistrationDto dto) { var model = new ServerRegistration(dto.Id, dto.ServerAddress, dto.ServerIdentity, dto.DateRegistered, dto.DateAccessed, dto.IsActive, dto.IsMaster); //on initial construction we don't want to have dirty properties tracked // http://issues.umbraco.org/issue/U4-1946 model.ResetDirtyProperties(false); return(model); }
public void Cannot_Add_Duplicate_Server_Identities() { // Arrange IScopeProvider provider = ScopeProvider; using (provider.CreateScope()) { ServerRegistrationRepository repository = CreateRepository(provider); var server = new ServerRegistration("http://shazwazza.com", "COMPUTER1", DateTime.Now); Assert.That(() => repository.Save(server), Throws.InstanceOf <DbException>()); } }
public void Cannot_Add_Duplicate_Server_Identities() { // Arrange var provider = TestObjects.GetScopeProvider(Logger); using (var scope = ScopeProvider.CreateScope()) { var repository = CreateRepository(provider); var server = new ServerRegistration("http://shazwazza.com", "COMPUTER1", DateTime.Now); Assert.Throws <SqlCeException>(() => repository.Save(server)); } }
public void ProcessRegistrationMessage(ServerRegistration message) { // These can change over time so go ahead and update. this.Port = message.Port; this.MachineFunction = message.MachineFunction; this.Datacenter = message.Datacenter; foreach (var counter in message.Counters) { var updated = false; var endTime = counter.EndTime.ToDateTimeOffset(); if (endTime == DateTimeOffset.MinValue) { continue; } this.CounterInfo.AddOrUpdate(counter, info => { updated = true; return(endTime); }, (info, current) => { if (endTime > current) { updated = true; return(endTime); } if (endTime < current) { Events.Write.ServerLatestDataNowEarlier(this.Hostname, info.Name, current.ToString("o"), endTime.ToString("o")); } return(current); }); if (updated) { if (this.LatestCounterTimeUpdated != null) { this.LatestCounterTimeUpdated(this, counter.Name, endTime); } Events.Write.ServerLatestDataUpdated(this.Hostname, counter.Name, endTime); } } }
public void ProcessRegistrationMessage(ServerRegistration message) { // These can change over time so go ahead and update. this.Port = message.Port; this.MachineFunction = message.MachineFunction; this.Datacenter = message.Datacenter; foreach (var counter in message.Counters) { var updated = false; var endTime = counter.EndTime.ToDateTimeOffset(); if (endTime == DateTimeOffset.MinValue) { continue; } this.CounterInfo.AddOrUpdate(counter, info => { updated = true; return endTime; }, (info, current) => { if (endTime > current) { updated = true; return endTime; } if (endTime < current) { Events.Write.ServerLatestDataNowEarlier(this.Hostname, info.Name, current.ToString("o"), endTime.ToString("o")); } return current; }); if (updated) { if (this.LatestCounterTimeUpdated != null) { this.LatestCounterTimeUpdated(this, counter.Name, endTime); } Events.Write.ServerLatestDataUpdated(this.Hostname, counter.Name, endTime); } } }
public void Cannot_Add_Duplicate_Computer_Names() { // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); // Act using (var repository = new ServerRegistrationRepository(unitOfWork)) { var server = new ServerRegistration("http://shazwazza.com", "COMPUTER1", DateTime.Now); repository.AddOrUpdate(server); Assert.Throws <SqlCeException>(unitOfWork.Commit); } }
/// <summary> /// Touches a server to mark it as active; deactivate stale servers. /// </summary> /// <param name="serverAddress">The server url.</param> /// <param name="serverIdentity">The server unique identity.</param> /// <param name="staleTimeout">The time after which a server is considered stale.</param> public void TouchServer(string serverAddress, string serverIdentity, TimeSpan staleTimeout) { using (var scope = ScopeProvider.CreateScope()) { scope.WriteLock(Constants.Locks.Servers); ((ServerRegistrationRepository)_serverRegistrationRepository).ClearCache(); // ensure we have up-to-date cache var regs = _serverRegistrationRepository.GetMany().ToArray(); var hasMaster = regs.Any(x => ((ServerRegistration)x).IsMaster); var server = regs.FirstOrDefault(x => x.ServerIdentity.InvariantEquals(serverIdentity)); if (server == null) { server = new ServerRegistration(serverAddress, serverIdentity, DateTime.Now); } else { server.ServerAddress = serverAddress; // should not really change but it might! server.UpdateDate = DateTime.Now; } server.IsActive = true; if (hasMaster == false) { server.IsMaster = true; } _serverRegistrationRepository.Save(server); _serverRegistrationRepository.DeactiveStaleServers(staleTimeout); // triggers a cache reload // reload - cheap, cached // reload - cheap, cached // default role is single server, but if registrations contain more // than one active server, then role is master or replica regs = _serverRegistrationRepository.GetMany().ToArray(); // default role is single server, but if registrations contain more // than one active server, then role is master or replica _currentServerRole = regs.Count(x => x.IsActive) > 1 ? (server.IsMaster ? ServerRole.Master : ServerRole.Replica) : ServerRole.Single; scope.Complete(); } }
/// <summary> /// Touches a server to mark it as active; deactivate stale servers. /// </summary> /// <param name="serverAddress">The server URL.</param> /// <param name="staleTimeout">The time after which a server is considered stale.</param> public void TouchServer(string serverAddress, TimeSpan staleTimeout) { var serverIdentity = GetCurrentServerIdentity(); using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { scope.WriteLock(Constants.Locks.Servers); _serverRegistrationRepository.ClearCache(); // ensure we have up-to-date cache IServerRegistration[]? regs = _serverRegistrationRepository.GetMany()?.ToArray(); var hasSchedulingPublisher = regs?.Any(x => ((ServerRegistration)x).IsSchedulingPublisher); IServerRegistration?server = regs?.FirstOrDefault(x => x.ServerIdentity?.InvariantEquals(serverIdentity) ?? false); if (server == null) { server = new ServerRegistration(serverAddress, serverIdentity, DateTime.Now); } else { server.ServerAddress = serverAddress; // should not really change but it might! server.UpdateDate = DateTime.Now; } server.IsActive = true; if (hasSchedulingPublisher == false) { server.IsSchedulingPublisher = true; } _serverRegistrationRepository.Save(server); _serverRegistrationRepository.DeactiveStaleServers(staleTimeout); // triggers a cache reload // reload - cheap, cached regs = _serverRegistrationRepository.GetMany().ToArray(); // default role is single server, but if registrations contain more // than one active server, then role is scheduling publisher or subscriber _currentServerRole = regs.Count(x => x.IsActive) > 1 ? server.IsSchedulingPublisher ? ServerRole.SchedulingPublisher : ServerRole.Subscriber : ServerRole.Single; scope.Complete(); } }
public void NoOuterScopeJustWorks() { var uowProvider = new PetaPocoUnitOfWorkProvider(Logger); var sqlSyntax = ApplicationContext.DatabaseContext.SqlSyntax; var lrepo = new LockingRepository <IServerRegistrationRepository>(uowProvider, x => CreateRepository(x, Logger, CacheHelper, sqlSyntax), new[] { Constants.Locks.Servers }, new[] { Constants.Locks.Servers }); IServerRegistration reg = null; lrepo.WithWriteLocked(xrepo => { xrepo.Repository.AddOrUpdate(reg = new ServerRegistration("a1234", "i1234", DateTime.Now)); // no need - autocommit by default //xrepo.UnitOfWork.Commit(); }); Assert.IsNull(((ScopeProvider)ApplicationContext.ScopeProvider).AmbientScope); Assert.AreNotEqual(0, reg.Id); // that's cheating somehow because it will not really hit the DB because of the cache var reg2 = lrepo.WithReadLocked(xrepo => { return(xrepo.Repository.Get(reg.Id)); }); Assert.IsNull(((ScopeProvider)ApplicationContext.ScopeProvider).AmbientScope); Assert.IsNotNull(reg2); Assert.AreEqual("a1234", reg2.ServerAddress); Assert.AreEqual("i1234", reg2.ServerIdentity); // this really makes sure there's something in database using (var scope = ApplicationContext.ScopeProvider.CreateScope()) { var reg3 = scope.Database.Fetch <dynamic>("SELECT * FROM umbracoServer WHERE id=@id", new { id = reg2.Id }).FirstOrDefault(); Assert.IsNotNull(reg3); Assert.AreEqual("a1234", reg3.address); Assert.AreEqual("i1234", reg3.computerName); } Assert.IsNull(((ScopeProvider)ApplicationContext.ScopeProvider).AmbientScope); }
public void Can_Perform_Add_On_Repository() { // Arrange var provider = new PetaPocoUnitOfWorkProvider(); var unitOfWork = provider.GetUnitOfWork(); using (var repository = new ServerRegistrationRepository(unitOfWork)) { // Act var server = new ServerRegistration("http://shazwazza.com", "COMPUTER4", DateTime.Now); repository.AddOrUpdate(server); unitOfWork.Commit(); // Assert Assert.That(server.HasIdentity, Is.True); Assert.That(server.Id, Is.EqualTo(4));//With 3 existing entries the Id should be 4 } }
public ServerInfo(ServerRegistration registration) { if (string.IsNullOrEmpty(registration.Hostname)) { throw new ArgumentException("No hostname provided.", "registration.Hostname"); } if (registration.Port == 0) { throw new ArgumentOutOfRangeException("registration.Port"); } this.Hostname = registration.Hostname; this.Port = registration.Port; this.MachineFunction = registration.MachineFunction; this.Datacenter = registration.Datacenter; this.lastUpdateTime = DateTimeOffset.MinValue; this.CounterInfo = new ConcurrentDictionary<CounterInfo, DateTimeOffset>(); }
public void Can_Perform_Add_On_Repository() { // Arrange IScopeProvider provider = ScopeProvider; using (provider.CreateScope()) { ServerRegistrationRepository repository = CreateRepository(provider); // Act var server = new ServerRegistration("http://shazwazza.com", "COMPUTER4", DateTime.Now); repository.Save(server); // Assert Assert.That(server.HasIdentity, Is.True); Assert.That(server.Id, Is.EqualTo(4)); // With 3 existing entries the Id should be 4 } }
public ServerInfo(ServerRegistration registration) { if (string.IsNullOrEmpty(registration.Hostname)) { throw new ArgumentException("No hostname provided.", "registration.Hostname"); } if (registration.Port == 0) { throw new ArgumentOutOfRangeException("registration.Port"); } this.Hostname = registration.Hostname; this.Port = registration.Port; this.MachineFunction = registration.MachineFunction; this.Datacenter = registration.Datacenter; this.lastUpdateTime = DateTimeOffset.MinValue; this.CounterInfo = new ConcurrentDictionary <CounterInfo, DateTimeOffset>(); }
/// <summary> /// Touches a server to mark it as active; deactivate stale servers. /// </summary> /// <param name="serverAddress">The server url.</param> /// <param name="serverIdentity">The server unique identity.</param> /// <param name="staleTimeout">The time after which a server is considered stale.</param> public void TouchServer(string serverAddress, string serverIdentity, TimeSpan staleTimeout) { _lrepo.WithWriteLocked(xr => { ((ServerRegistrationRepository)xr.Repository).ReloadCache(); // ensure we have up-to-date cache var regs = xr.Repository.GetAll().ToArray(); var hasMaster = regs.Any(x => ((ServerRegistration)x).IsMaster); var server = regs.FirstOrDefault(x => x.ServerIdentity.InvariantEquals(serverIdentity)); if (server == null) { server = new ServerRegistration(serverAddress, serverIdentity, DateTime.Now); } else { server.ServerAddress = serverAddress; // should not really change but it might! server.UpdateDate = DateTime.Now; } server.IsActive = true; if (hasMaster == false) { server.IsMaster = true; } xr.Repository.AddOrUpdate(server); xr.UnitOfWork.Commit(); // triggers a cache reload xr.Repository.DeactiveStaleServers(staleTimeout); // triggers a cache reload // reload - cheap, cached regs = xr.Repository.GetAll().ToArray(); // default role is single server, but if registrations contain more // than one active server, then role is master or replica _currentServerRole = regs.Count(x => x.IsActive) > 1 ? (server.IsMaster ? ServerRole.Master : ServerRole.Slave) : ServerRole.Single; }); }
private async void StartRegistration() { IPAddress[] addresses; try { addresses = await Task<IPAddress[]>.Factory.FromAsync(Dns.BeginGetHostAddresses, Dns.EndGetHostAddresses, this.destinationHostname, null); } catch (SocketException e) { Events.Write.RegistrationDestinationResolutionFailed(this.destinationHostname, e.Message); return; } var serverRegistration = new ServerRegistration { Hostname = this.sourceHostname, Port = this.sourcePort, MachineFunction = this.sourceMachineFunction, Datacenter = this.sourceDatacenter, }; foreach (var counter in this.dataManager.Counters) { serverRegistration.Counters.Add( new CounterInfo { Name = counter.Name, Type = counter.Type, Dimensions = counter.Dimensions.ToList(), StartTime = counter.StartTime.ToMillisecondTimestamp(), EndTime = counter.EndTime.ToMillisecondTimestamp(), }); } byte[] payload; using (var ms = new MemoryStream()) using (var writerStream = new WriterStream(ms, this.dataManager.MemoryStreamManager)) { var writer = writerStream.CreateCompactBinaryWriter(); writer.Write(serverRegistration); payload = ms.ToArray(); } foreach (var address in addresses) { this.RegisterWithAddress(address, payload); } lock (this) { if (this.registrationTimer != null) { this.registrationTimer.Change(this.registrationInterval, TimeSpan.Zero); } } }
public void LoadServerPlugins() { LoadGlobalPlugins(); ServerRegistration.GetInstance(); }