/// <summary> /// Refreshes profile server's IPNS record. /// </summary> public async Task IpnsRecordRefreshAsync() { log.Trace("()"); if (canContactInformationHash == null) { log.Debug("No CAN contact information hash, can't refresh IPNS record, will try later."); log.Trace("(-)"); return; } canIpnsLastSequenceNumber++; canIpnsRecord = CanApi.CreateIpnsRecord(canContactInformationHash, canIpnsLastSequenceNumber, IpnsRecordExpirationTimeSeconds); CanRefreshIpnsResult cres = await api.RefreshIpnsRecord(canIpnsRecord, Config.Configuration.Keys.PublicKey); if (cres.Success) { using (UnitOfWork unitOfWork = new UnitOfWork()) { await unitOfWork.AcquireLockAsync(UnitOfWork.SettingsLock); try { Setting setting = new Setting("CanIpnsLastSequenceNumber", canIpnsLastSequenceNumber.ToString()); await unitOfWork.SettingsRepository.AddOrUpdate(setting); await unitOfWork.SaveThrowAsync(); log.Debug("CanIpnsLastSequenceNumber updated in database to new value {0}.", setting.Value); } catch (Exception e) { log.Error("Unable to update CanIpnsLastSequenceNumber in the database to new value {0}, exception: {1}", canIpnsLastSequenceNumber, e.ToString()); } unitOfWork.ReleaseLock(UnitOfWork.SettingsLock); } } else if (cres.Message != "Shutdown") { log.Error("Failed to refresh profile server's IPNS record."); } log.Trace("(-)"); }
/// <summary> /// Saves values related to the profile server contact information to the database. /// </summary> /// <returns>true if the function succeeds, false otherwise.</returns> public async Task <bool> SaveProfileServerContactInformation() { log.Trace("()"); bool res = false; using (UnitOfWork unitOfWork = new UnitOfWork()) { DatabaseLock lockObject = UnitOfWork.SettingsLock; await unitOfWork.AcquireLockAsync(lockObject); try { string addr = Config.Configuration.ExternalServerAddress.ToString(); string port = Config.Configuration.ServerRoles.GetRolePort((uint)ServerRole.Primary).ToString(); string hash = canContactInformationHash.ToBase58(); log.Debug("Saving contact information values to database: {0}:{1}, '{2}'", addr, port, hash); Setting primaryPort = new Setting("PrimaryPort", port); Setting externalServerAddress = new Setting("ExternalServerAddress", addr); Setting canProfileServerContactInformationHash = new Setting("CanProfileServerContactInformationHash", hash); await unitOfWork.SettingsRepository.AddOrUpdate(externalServerAddress); await unitOfWork.SettingsRepository.AddOrUpdate(primaryPort); await unitOfWork.SettingsRepository.AddOrUpdate(canProfileServerContactInformationHash); await unitOfWork.SaveThrowAsync(); res = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } unitOfWork.ReleaseLock(lockObject); } log.Trace("(-):{0}", res); return(res); }
/// <summary> /// Saves GPS location of the server to database settings. /// </summary> /// <returns>true if the function succeeds, false otherwise.</returns> private async Task <bool> SaveLocationToSettings() { log.Trace("()"); bool res = false; using (UnitOfWork unitOfWork = new UnitOfWork()) { DatabaseLock lockObject = UnitOfWork.SettingsLock; await unitOfWork.AcquireLockAsync(lockObject); try { Setting locLocationLatitude = new Setting("LocLocationLatitude", Location.Latitude.ToString(CultureInfo.InvariantCulture)); unitOfWork.SettingsRepository.Insert(locLocationLatitude); Setting locLocationLongitude = new Setting("LocLocationLongitude", Location.Longitude.ToString(CultureInfo.InvariantCulture)); unitOfWork.SettingsRepository.Insert(locLocationLongitude); log.Debug("Saving new GPS location [{0}] to database.", Location); await unitOfWork.SettingsRepository.AddOrUpdate(locLocationLatitude); await unitOfWork.SettingsRepository.AddOrUpdate(locLocationLongitude); await unitOfWork.SaveThrowAsync(); res = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } unitOfWork.ReleaseLock(lockObject); } log.Trace("(-):{0}", res); return(res); }
/// <summary> /// Deletes neighbor server, all its activities and all neighborhood actions for it from the database. /// </summary> /// <param name="UnitOfWork">Unit of work instance.</param> /// <param name="NeighborId">Identifier of the neighbor server to delete.</param> /// <param name="ActionId">If there is a neighborhood action that should NOT be deleted, this is its ID, otherwise it is -1.</param> /// <param name="HoldingLocks">true if the caller is holding NeighborLock and NeighborhoodActionLock.</param> /// <returns>true if the function succeeds, false otherwise.</returns> public async Task <bool> DeleteNeighbor(UnitOfWork UnitOfWork, byte[] NeighborId, int ActionId = -1, bool HoldingLocks = false) { log.Trace("(NeighborId:'{0}',ActionId:{1},HoldingLocks:{2})", NeighborId.ToHex(), ActionId, HoldingLocks); bool res = false; bool success = false; // Delete neighbor from the list of neighbors. DatabaseLock lockObject = UnitOfWork.NeighborLock; if (!HoldingLocks) { await UnitOfWork.AcquireLockAsync(lockObject); } try { Neighbor neighbor = (await GetAsync(n => n.NeighborId == NeighborId)).FirstOrDefault(); if (neighbor != null) { Delete(neighbor); await UnitOfWork.SaveThrowAsync(); log.Debug("Neighbor ID '{0}' deleted from database.", NeighborId.ToHex()); } else { // If the neighbor does not exist, we set success to true as the result of the operation is as we want it // and we gain nothing by trying to repeat the action later. log.Warn("Neighbor ID '{0}' not found.", NeighborId.ToHex()); } success = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } if (!HoldingLocks) { UnitOfWork.ReleaseLock(lockObject); } // Delete neighbor's activities from the database. if (success) { success = false; // Disable change tracking for faster multiple deletes. UnitOfWork.Context.ChangeTracker.AutoDetectChangesEnabled = false; lockObject = UnitOfWork.NeighborActivityLock; await UnitOfWork.AcquireLockAsync(lockObject); try { List <NeighborActivity> activities = (await UnitOfWork.NeighborActivityRepository.GetAsync(i => i.PrimaryServerId == NeighborId)).ToList(); if (activities.Count > 0) { log.Debug("There are {0} activities of removed neighbor ID '{1}'.", activities.Count, NeighborId.ToHex()); foreach (NeighborActivity activity in activities) { UnitOfWork.NeighborActivityRepository.Delete(activity); } await UnitOfWork.SaveThrowAsync(); log.Debug("{0} identities hosted on neighbor ID '{1}' deleted from database.", activities.Count, NeighborId.ToHex()); } else { log.Trace("No profiles hosted on neighbor ID '{0}' found.", NeighborId.ToHex()); } success = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } UnitOfWork.ReleaseLock(lockObject); UnitOfWork.Context.ChangeTracker.AutoDetectChangesEnabled = true; } if (success) { success = false; lockObject = UnitOfWork.NeighborhoodActionLock; if (!HoldingLocks) { await UnitOfWork.AcquireLockAsync(lockObject); } try { // Do not delete the current action, it will be deleted just after this method finishes. List <NeighborhoodAction> actions = UnitOfWork.NeighborhoodActionRepository.Get(a => (a.ServerId == NeighborId) && (a.Id != ActionId)).ToList(); if (actions.Count > 0) { foreach (NeighborhoodAction action in actions) { log.Debug("Action ID {0}, type {1}, serverId '{2}' will be removed from the database.", action.Id, action.Type, NeighborId.ToHex()); UnitOfWork.NeighborhoodActionRepository.Delete(action); } await UnitOfWork.SaveThrowAsync(); } else { log.Debug("No neighborhood actions for neighbor ID '{0}' found.", NeighborId.ToHex()); } success = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } if (!HoldingLocks) { UnitOfWork.ReleaseLock(lockObject); } } res = success; log.Trace("(-):{0}", res); return(res); }