public ElasticLease( Guid leasedResourceId, DateTime expires, ElasticLeaseOwner owner, long version = -1) { if (owner == null) { throw new ArgumentNullException("owner"); } this._id = leasedResourceId; this._expires = expires; this._owner = owner; this.versioning = new VersioningMixin(version); }
public void TryLoadAndLockById_ContactExistsAndNotLockedWithNoSuccessors_ReturnsContact( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, us, true, ctx) .Should().Be(true); var res = contactService.TryLoadAndLock(contact.Id, us, TimeSpan.FromMinutes(1), ctx); res.Status.Should().Be(LockAttemptStatus.Success); res.LockedObject.ShouldBeEquivalentToContact(contact, l => l.Expires > DateTime.UtcNow && l.IsOwnedBy(us) && l.Version == 3); } }
public virtual LockAttemptResult<ElasticContact> TryLoadAndLock( Guid id, ElasticLeaseOwner targetLeaseOwner, TimeSpan leaseDuration, ISystemContext ctx) { if (targetLeaseOwner == null) { throw new ArgumentNullException("targetLeaseOwner", "A lease owner must be specified."); } var contact = this.GetLatest(id, ctx); if (contact == null) { return new LockAttemptResult<ElasticContact>(LockAttemptStatus.NotFound, null, null); } if (this.TryLockContact( contact, targetLeaseOwner, leaseDuration, ctx) == LockAttemptStatus.Success) { return new LockAttemptResult<ElasticContact>( LockAttemptStatus.Success, contact, targetLeaseOwner); } else { return new LockAttemptResult<ElasticContact>( LockAttemptStatus.AlreadyLocked, contact, contact.Lease.Owner); } // LockAttemptResult.DatabaseUnavailable - I'm letting any exceptions bubble up for now }
public void DeleteContact_ContactExistsWithExpiredLeaseByDifferentOwner_ContactDeleted( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner them, ISystemContext ctx, IDateTimeController dateTime, TestIndexUtils contactIndex) { using (contactIndex) { // arrange contact with expired lease from another owner... var timeTraveller = (DateTimeTimeTraveller)dateTime; using (timeTraveller.NewJourney(-24)) { contactService.Save(contact, them, false, ctx).Should().BeTrue(); } // deletes don't have an owner, at this level at least. contactService.Delete(contact.Id, ctx); contactService .LoadForReadOnly(contact.Id, ctx) .Should() .BeNull(); } }
public void DeleteContact_ContactExistsWithActiveLeaseBySameOwner_ContactDeleted( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, us, false, ctx).Should().BeTrue(); // deletes seem to be brutal - they don't care about locks contactService.Delete(contact.Id, ctx); contactService .LoadForReadOnly(contact.Id, ctx) .Should() .BeNull(); } }
public void TryLoadContact_ContactExistsAlreadyLockedByDifferentOwner_NotLocked( IElasticAnalyticsContactService contactService, ElasticLeaseOwner us, ElasticContact eContact, ISystemContext ctx) { var res = contactService.TryLoadAndLock(eContact.Id, us, TimeSpan.FromMinutes(1), ctx); res.Should().NotBeNull(); res.LockedObject.Id.Should().Be(eContact.Id); res.Status.Should().Be(LockAttemptStatus.AlreadyLocked); }
public void TryLoadAndLockByIdentity_ContactObsolete_NullReturned( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticContact successor, ElasticLeaseOwner owner, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, owner, true, ctx) .Should().Be(true); contactService.Obsolete(contact.Id, successor.Id, owner, ctx); contactService.Save(successor, owner, true, ctx); var res = contactService.TryLoadAndLock(contact.Identification.Identity, owner, TimeSpan.FromMinutes(1), ctx); res.Status.Should().Be(LockAttemptStatus.NotFound); res.LockedObject.Should().BeNull(); } }
public void ObsoleteContact_ContactExistsAndLockedByDifferentOwner_ReturnsFalse( IElasticAnalyticsContactService contactService, IRepository<ElasticContact> contactRepo, ElasticContact contact, Guid successor, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { // contact exists and currently locked. contactService .Save(contact, them, false, ctx) .Should() .Be(true); contactService.Obsolete(contact.Id, successor, us, ctx).Should().BeFalse(); } }
public void ReleaseContact_ContactDoesntExist_NothingHappens( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { AssertionExtensions.ShouldNotThrow(() => contactService.Release(contact.Id, us, ctx)); } }
public void DeleteContact_ContactDoesntExist_ReturnsSuccessfully( IElasticAnalyticsContactService contactService, ILeaseService leaseService, ElasticContact contact, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { AssertionExtensions.ShouldNotThrow(() => contactService.Delete(contact.Id, ctx)); } }
public void LoadForReadOnlyById_ContactObsolete_SuccessorReturned( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticContact successor, ElasticLeaseOwner owner, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, owner, true, ctx) .Should().Be(true); contactService.Obsolete(contact.Id, successor.Id, owner, ctx); contactService.Save(successor, owner, true, ctx); contactService.LoadForReadOnly(contact.Id, ctx) .ShouldBeEquivalentToContact(successor, l => l == null); } }
public void SaveContact_ContactDoesntExistShouldNotBeReleased_ContactCreatedWithLock( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, them, false, ctx) .Should().Be(true); var res = contactService.TryLoadAndLock(contact.Id, us, TimeSpan.FromMinutes(1), ctx); res.Status.Should().Be(LockAttemptStatus.AlreadyLocked); res.LockedObject.ShouldBeEquivalentToContact(contact); contactService.LoadForReadOnly(contact.Identification.Identity, ctx) .ShouldBeEquivalentToContact(contact, l => l == null); } }
public void SaveContact_ContactLockedbyDifferentOwner_ContactNotAdded( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, them, false, ctx) .Should().Be(true); contactService.Save(contact, us, false, ctx) .Should().Be(false); } }
public void SaveContact_ContactDoesntExistShouldBeReleased_ContactCreatedLockFree( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner them, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, them, true, ctx) .Should().Be(true); var res = contactService.TryLoadAndLock(contact.Id, us, TimeSpan.FromMinutes(1), ctx); res.Status.Should().Be(LockAttemptStatus.Success); res.LockedObject.ShouldBeEquivalentToContact(contact, l => l.Expires > DateTime.UtcNow && l.IsOwnedBy(us) && l.Version == 3); contactService.LoadForReadOnly(contact.Identification.Identity, ctx) .ShouldBeEquivalentToContact(contact); } }
public void LoadForReadOnlyByIdentity_ContactObsolete_NullReturned( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticContact successor, ElasticLeaseOwner owner, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, owner, true, ctx) .Should().Be(true); contactService.Obsolete(contact.Id, successor.Id, owner, ctx); contactService.Save(successor, owner, true, ctx); contactService.LoadForReadOnly(contact.Identification.Identity, ctx) .Should().BeNull(); } }
public void LoadForReadOnlyByIdentity_ContactExistsLockedByDifferentOwner_ContactReturned( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, them, false, ctx) .Should().Be(true); contact.Lease = null; contactService.LoadForReadOnly(contact.Identification.Identity, ctx) .ShouldBeEquivalentToContact(contact); } }
public void DeleteContact_ContactExistsWithActiveLeaseByDifferentOwner_DeleteStillHonoured( IElasticAnalyticsContactService contactService, ILeaseService leaseService, ElasticContact contact, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, them, false, ctx).Should().BeTrue(); // deletes seem to be brutal contactService.Delete(contact.Id, ctx); contactService .LoadForReadOnly(contact.Id, ctx) .Should() .BeNull(); // lease is deleted so if we wanted, we can just go and create another contact with the // same id straight away... contact.Lease = null; contactService.Save(contact, us, false, ctx).Should().BeTrue(); } }
public void ObsoleteContact_ContactDoesntExist_NothingHappens( IElasticAnalyticsContactService contactService, ElasticContact contact, Guid successor, ElasticLeaseOwner owner, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { AssertionExtensions.ShouldNotThrow(() => contactService.Obsolete(contact.Id, successor, owner, ctx)); } }
public void SaveContact_ContactExistsWithIdentityNotLocked_ContactUpdated( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contact.Identification.IdentityLevel.Should().Be(IdentificationLevel.Known); contactService.Save(contact, them, true, ctx) .Should().Be(true); //contact.SystemInfo.VisitCount = 999; // make a change contactService.Save(contact, us, false, ctx) .Should().Be(true); // Assert var res = contactService.TryLoadAndLock(contact.Id, us, TimeSpan.FromMinutes(1), ctx); res.Status.Should().Be(LockAttemptStatus.Success); res.LockedObject.ShouldBeEquivalentToContact(contact, l => l.Expires > DateTime.UtcNow && l.IsOwnedBy(us) && l.Version == 4); contactService.LoadForReadOnly(contact.Identification.Identity, ctx) .ShouldBeEquivalentToContact(contact, l => l == null); } }
public void LoadForReadOnlyById_ContactExistsNotLocked_ContactReturned( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner them, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, them, true, ctx) .Should().Be(true); contactService.LoadForReadOnly(contact.Id, ctx) .ShouldBeEquivalentToContact(contact, l => l == null); } }
public void ObsoleteContact_ContactExistsWithSuccessorNotLocked_ContactObsoleted( IElasticAnalyticsContactService contactService, IRepository<ElasticContact> contactRepo, ElasticContact contact, Guid successor, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { // andes doesn't care if a contact has successors or not apart from when loading a contact. using (contactIndex) { contact.Successor = Guid.NewGuid(); contactService.Save(contact, us, true, ctx).Should().BeTrue(); contactService.Obsolete(contact.Id, successor, us, ctx).Should().BeTrue(); var obsoletedContact = contactRepo.Get(contact.Id, ctx); obsoletedContact.Id.Should().Be(contact.Id); obsoletedContact.Successor.Should().Be(successor); obsoletedContact.Should().BeObsolete(); } }
public void SaveContact_ContactExistsWithIdentityAndIdentityInUse_ThrowsException( IElasticAnalyticsContactService contactService, ElasticContact contact1, ElasticContact contact2, ElasticLeaseOwner owner, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact1, owner, true, ctx).Should().Be(true); // set the identity to be the same contact2.Identification.SetIdentity( contact1.Identification.Identity, contact1.Identification.IdentityLevel); AssertionExtensions.ShouldThrow<InvalidOperationException>( () => contactService.Save(contact2, owner, true, ctx)); } }
public void ObsoleteContact_ContactExistsAndLockedBySameOwner_ContactObsoleted( IElasticAnalyticsContactService contactService, IRepository<ElasticContact> contactRepo, ElasticContact contact, Guid successor, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, us, false, ctx).Should().BeTrue(); contactService.Obsolete(contact.Id, successor, us, ctx).Should().BeTrue(); var obsoletedContact = contactRepo.Get(contact.Id, ctx); obsoletedContact.Id.Should().Be(contact.Id); obsoletedContact.Successor.Should().Be(successor); obsoletedContact.Should().BeObsolete(); } }
public void SaveContact_ContactExistsWithIdentityAndContactSaveFailed_ExistingIdentityRestored( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner owner, ISystemContext ctx, TestIndexUtils contactIndex) { // ? how would a save contact fail, but first an identity save succeeds? (i.e. ES isn't down) }
public void ObsoleteContact_ContactExistsAndExpiredLockedByDifferentOwner_ContactObsoleted( IElasticAnalyticsContactService contactService, IRepository<ElasticContact> contactRepo, ElasticContact contact, Guid successor, ElasticLeaseOwner us, ElasticLeaseOwner them, ISystemContext ctx, IDateTimeController dateTime, TestIndexUtils contactIndex) { using (contactIndex) { // arrange contact with expired lease from another owner... var timeTraveller = (DateTimeTimeTraveller)dateTime; using (timeTraveller.NewJourney(-24)) { contactService.Save(contact, them, false, ctx).Should().BeTrue(); } contactService.Obsolete(contact.Id, successor, us, ctx).Should().BeTrue(); var obsoletedContact = contactRepo.Get(contact.Id, ctx); obsoletedContact.Id.Should().Be(contact.Id); obsoletedContact.Successor.Should().Be(successor); obsoletedContact.Should().BeObsolete(); } }
public void TryExtendLock_ContactExistsLockedBySameOwner_LeaseExtended( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService.Save(contact, us, false, ctx) .Should().Be(true); var res = contactService.TryExtendLock(contact, TimeSpan.FromHours(1), ctx); res.Should().BeTrue(); contact.Lease.IsOwnedBy(us); } }
public void ReleaseContact_NoLockExistsForContact_ContactReleased( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { // contact exists, no lock contactService.Save(contact, us, true, ctx).Should().BeTrue(); // release contactService.Release(contact.Id, us, ctx); // should be able to lock it again contactService.TryLoadAndLock(contact.Id, us, TimeSpan.FromHours(1), ctx) .Status.Should() .Be(LockAttemptStatus.Success); } }
public void TryExtendLock_ContactExistsLockedByDifferentOwner_NotExtended( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner them, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { // lock by a different owner contactService.Save(contact, them, false, ctx) .Should().Be(true); // extend it contact.Lease = new ElasticLease(contact.Id, DateTime.UtcNow, us); // specify the lease we want var res = contactService.TryExtendLock(contact, TimeSpan.FromHours(1), ctx); res.Should().BeFalse(); contact.Lease.IsOwnedBy(us); // currently Andes does not update the lease reference in this scenario } }
public void TryLoadContact_ContactDoesntExist_ReturnsNull( ElasticLeaseOwner us, IElasticAnalyticsContactService contactService, ISystemContext ctx) { var res = contactService.TryLoadAndLock(Guid.NewGuid(), us, TimeSpan.FromMinutes(1), ctx); res.LockedObject.Should().BeNull(); res.Status.Should().Be(LockAttemptStatus.NotFound); }
public void DeleteContact_ContactExistsWithNoLease_ContactDeleted( IElasticAnalyticsContactService contactService, ElasticContact contact, ElasticLeaseOwner us, ISystemContext ctx, TestIndexUtils contactIndex) { using (contactIndex) { contactService .Save(contact, us, true, ctx) .Should().BeTrue(); contactService.Delete(contact.Id, ctx); contactService .LoadForReadOnly(contact.Id, ctx) .Should() .BeNull(); } }