Ejemplo n.º 1
0
            public void Dispose()
            {
                if (ParsedCommands.Count == 0)
                {
                    return;
                }

                foreach (var cmd in ParsedCommands)
                {
                    cmd.Document?.Dispose();
                    if (cmd.PatchCommand != null)
                    {
                        cmd.PatchCommand.Dispose();
                    }
                }
                BatchRequestParser.ReturnBuffer(ParsedCommands);
                AttachmentStreamsTempFile?.Dispose();
                AttachmentStreamsTempFile = null;
            }
Ejemplo n.º 2
0
        private async Task ParseMultipart(DocumentsOperationContext context, MergedBatchCommand command)
        {
            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                MultipartRequestHelper.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, RequestBodyStream());

            for (var i = 0; i < int.MaxValue; i++)
            {
                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);

                if (section == null)
                {
                    break;
                }

                var bodyStream = GetBodyStream(section);
                if (i == 0)
                {
                    command.ParsedCommands = await BatchRequestParser.BuildCommandsAsync(context, bodyStream, Database, ServerStore);

                    continue;
                }

                if (command.AttachmentStreams == null)
                {
                    command.AttachmentStreams         = new Queue <MergedBatchCommand.AttachmentStream>();
                    command.AttachmentStreamsTempFile = Database.DocumentsStorage.AttachmentsStorage.GetTempFile("batch");
                }

                var attachmentStream = new MergedBatchCommand.AttachmentStream
                {
                    Stream = command.AttachmentStreamsTempFile.StartNewStream()
                };
                attachmentStream.Hash = await AttachmentsStorageHelper.CopyStreamToFileAndCalculateHash(context, bodyStream, attachmentStream.Stream, Database.DatabaseShutdown);

                attachmentStream.Stream.Flush();
                command.AttachmentStreams.Enqueue(attachmentStream);
            }
        }
Ejemplo n.º 3
0
        public async Task BulkDocs()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                using (var command = new MergedBatchCommand {
                    Database = Database
                })
                {
                    var contentType = HttpContext.Request.ContentType;
                    if (contentType == null ||
                        contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                    {
                        command.ParsedCommands = await BatchRequestParser.BuildCommandsAsync(context, RequestBodyStream(), Database, ServerStore);
                    }
                    else if (contentType.StartsWith("multipart/mixed", StringComparison.OrdinalIgnoreCase))
                    {
                        await ParseMultipart(context, command);
                    }
                    else
                    {
                        ThrowNotSupportedType(contentType);
                    }

                    var waitForIndexesTimeout = GetTimeSpanQueryString("waitForIndexesTimeout", required: false);
                    if (waitForIndexesTimeout != null)
                    {
                        command.ModifiedCollections = new HashSet <string>();
                    }
                    try
                    {
                        await Database.TxMerger.Enqueue(command);

                        command?.ExceptionDispatchInfo?.Throw();
                    }
                    catch (ConcurrencyException)
                    {
                        HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
                        throw;
                    }

                    var waitForReplicasTimeout = GetTimeSpanQueryString("waitForReplicasTimeout", required: false);
                    if (waitForReplicasTimeout != null)
                    {
                        await WaitForReplicationAsync(waitForReplicasTimeout.Value, command);
                    }

                    if (waitForIndexesTimeout != null)
                    {
                        await
                        WaitForIndexesAsync(waitForIndexesTimeout.Value, command.LastChangeVector, command.LastTombstoneEtag,
                                            command.ModifiedCollections);
                    }

                    HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;

                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Results"] = command.Reply
                        });
                    }
                }
        }
Ejemplo n.º 4
0
        public async Task BulkDocs()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                using (var command = new MergedBatchCommand(Database))
                {
                    var contentType = HttpContext.Request.ContentType;
                    if (contentType == null ||
                        contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                    {
                        await BatchRequestParser.BuildCommandsAsync(context, command, RequestBodyStream(), Database, ServerStore);
                    }
                    else if (contentType.StartsWith("multipart/mixed", StringComparison.OrdinalIgnoreCase) ||
                             contentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase))
                    {
                        await ParseMultipart(context, command);
                    }
                    else
                    {
                        ThrowNotSupportedType(contentType);
                    }

                    var waitForIndexesTimeout       = GetTimeSpanQueryString("waitForIndexesTimeout", required: false);
                    var waitForIndexThrow           = GetBoolValueQueryString("waitForIndexThrow", required: false) ?? true;
                    var specifiedIndexesQueryString = HttpContext.Request.Query["waitForSpecificIndex"];

                    if (command.IsClusterTransaction)
                    {
                        if (Server.Configuration.Core.FeaturesAvailability == FeaturesAvailability.Stable)
                        {
                            FeaturesAvailabilityException.Throw("Cluster Transactions");
                        }

                        using (Database.ClusterTransactionWaiter.CreateTask(out var taskId))
                        {
                            // Since this is a cluster transaction we are not going to wait for the write assurance of the replication.
                            // Because in any case the user will get a raft index to wait upon on his next request.
                            var options = new ClusterTransactionCommand.ClusterTransactionOptions(taskId)
                            {
                                WaitForIndexesTimeout       = waitForIndexesTimeout,
                                WaitForIndexThrow           = waitForIndexThrow,
                                SpecifiedIndexesQueryString = specifiedIndexesQueryString.Count > 0 ? specifiedIndexesQueryString.ToList() : null
                            };
                            await HandleClusterTransaction(context, command, options);
                        }
                        return;
                    }

                    if (waitForIndexesTimeout != null)
                    {
                        command.ModifiedCollections = new HashSet <string>();
                    }

                    try
                    {
                        await Database.TxMerger.Enqueue(command);

                        command.ExceptionDispatchInfo?.Throw();
                    }
                    catch (ConcurrencyException)
                    {
                        HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
                        throw;
                    }

                    var waitForReplicasTimeout = GetTimeSpanQueryString("waitForReplicasTimeout", required: false);
                    if (waitForReplicasTimeout != null)
                    {
                        var numberOfReplicasStr             = GetStringQueryString("numberOfReplicasToWaitFor", required: false) ?? "1";
                        var throwOnTimeoutInWaitForReplicas = GetBoolValueQueryString("throwOnTimeoutInWaitForReplicas", required: false) ?? true;

                        await WaitForReplicationAsync(Database, waitForReplicasTimeout.Value, numberOfReplicasStr, throwOnTimeoutInWaitForReplicas, command.LastChangeVector);
                    }

                    if (waitForIndexesTimeout != null)
                    {
                        await WaitForIndexesAsync(ContextPool, Database, waitForIndexesTimeout.Value, specifiedIndexesQueryString.ToList(), waitForIndexThrow,
                                                  command.LastChangeVector, command.LastTombstoneEtag, command.ModifiedCollections);
                    }

                    HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            [nameof(BatchCommandResult.Results)] = command.Reply
                        });
                    }
                }
        }