public async Task MergedPutAttachmentCommand_WhenAttachmentAlreadyDeletedAndFailOnConcurrency_ShouldNotDeleteTombstone() { var store = GetDocumentStore(new Options { ModifyDocumentStore = s => s.Conventions.UseOptimisticConcurrency = true, ModifyDatabaseRecord = r => r.Settings["Tombstones.CleanupIntervalInMin"] = int.MaxValue.ToString() }); const string id = "TestObjs/1"; const string attachmentName = "attachmentName"; using (var session = store.OpenAsyncSession()) { var testObj = new TestObj(); await session.StoreAsync(testObj, id); session.Advanced.Attachments.Store(testObj, attachmentName, new MemoryStream(new byte[] { 1 })); await session.SaveChangesAsync(); session.Advanced.Attachments.Delete(id, attachmentName); await session.SaveChangesAsync(); } Assert.NotEqual(0, GetTombstones(store).Count); var operation = new PutAttachmentOperation(id, attachmentName, new MemoryStream(new byte[] { 1 }), changeVector: "someConflictedChangeVector"); await Assert.ThrowsAnyAsync <ConcurrencyException>(async() => await store.Operations.SendAsync(operation)); Assert.NotEqual(0, GetTombstones(store).Count); }
public async Task <FuelTrackingRecord> Post(IFormCollection form) { var now = DateTime.UtcNow; using var session = _store.OpenAsyncSession(); var userId = User.Identity.Name; if (false == await session.Advanced.ExistsAsync(userId)) { throw new UnauthorizedRequestException(); } var containsKey = form.ContainsKey("date"); var dateTime = containsKey ? DateTime.Parse(form["date"]) : now; var record = new FuelTrackingRecord { UserId = userId, DateTime = dateTime.ToUniversalTime() }; await session.StoreAsync(record); var metadata = session.Advanced.GetMetadataFor(record); metadata["CreatedAt"] = now; await session.SaveChangesAsync(); foreach (var file in form.Files) { await using var fileStream = file.OpenReadStream(); var operation = new PutAttachmentOperation( record.Id, file.Name, fileStream, file.ContentType); _store.Operations.Send( operation); } return(record); }
public async Task PutAttachmentsWithFailover_LowLevel() { const string hash = "BfKA8g/BJuHOTHYJ+A6sOt9jmFSVEDzCM3EcLLKCRMU="; const int size = 512 * 1024; UseNewLocalServer(); var leader = await CreateRaftClusterAndGetLeader(3); using (var store = GetDocumentStore(new Options { Server = leader, ModifyDatabaseRecord = record => { record.Topology = new DatabaseTopology { DynamicNodesDistribution = false, Members = { leader.ServerStore.NodeTag, Servers.First(x => x != leader).ServerStore.NodeTag } }; } })) { using (var session = (DocumentSession)store.OpenSession()) { session.Store(new User { Name = "Fitzchak" }, "users/1"); session.SaveChanges(); Assert.True(await WaitForDocumentInClusterAsync <User>( session, "users/1", u => u.Name.Equals("Fitzchak"), TimeSpan.FromSeconds(10))); } var requestExecutor = store.GetRequestExecutor(); using (requestExecutor.ContextPool.AllocateOperationContext(out JsonOperationContext context)) using (var stream = new BigDummyStream(size)) { var command = new PutAttachmentOperation("users/1", "File", stream, "application/pdf") .GetCommand(store, store.Conventions, context, requestExecutor.Cache); var(currentIndex, currentNode) = await requestExecutor.GetPreferredNode(); var currentServer = Servers.Single(x => x.ServerStore.NodeTag == currentNode.ClusterTag); Assert.Equal(currentNode.ClusterTag, leader.ServerStore.NodeTag); stream.Position++; // simulating that we already started to call this and we need to reset DisposeServerAndWaitForFinishOfDisposal(currentServer); var task = requestExecutor.ExecuteAsync(currentNode, currentIndex, context, command); await task; var attachment = command.Result; Assert.Equal("File", attachment.Name); Assert.Equal(size, stream.Position); Assert.Equal(size, attachment.Size); Assert.Equal("application/pdf", attachment.ContentType); Assert.Equal(hash, attachment.Hash); } using (var session = store.OpenSession()) using (var dummyStream = new BigDummyStream(size)) using (var attachment = session.Advanced.GetAttachment("users/1", "File")) { attachment.Stream.CopyTo(dummyStream); Assert.Equal("File", attachment.Details.Name); Assert.Equal(size, dummyStream.Position); Assert.Equal(size, attachment.Details.Size); Assert.Equal("application/pdf", attachment.Details.ContentType); Assert.Equal(hash, attachment.Details.Hash); var user = session.Load <User>("users/1"); var metadata = session.Advanced.GetMetadataFor(user); Assert.Contains(DocumentFlags.HasAttachments.ToString(), metadata.GetString(Constants.Documents.Metadata.Flags)); var attachments = metadata.GetObjects(Constants.Documents.Metadata.Attachments); var attachmentMetadata = attachments.Single(); Assert.Equal("File", attachmentMetadata.GetString(nameof(AttachmentName.Name))); Assert.Equal("application/pdf", attachmentMetadata.GetString(nameof(AttachmentName.ContentType))); Assert.Equal(hash, attachmentMetadata.GetString(nameof(AttachmentName.Hash))); Assert.Equal(size, attachmentMetadata.GetLong(nameof(AttachmentName.Size))); } } }