Ejemplo n.º 1
0
        public async Task PostValidateOptions()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            using (context.OpenReadTransaction())
            {
                var blittableJson = await context.ReadForMemoryAsync(RequestBodyStream(), "");
                var options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);

                if (!string.IsNullOrEmpty(options.FileName) && options.FileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
                    throw new InvalidOperationException($"{options.FileName} is invalid file name");

                if (string.IsNullOrEmpty(options.TransformScript))
                {
                    NoContentStatus();
                    return;
                }

                try
                {
                    var scriptRunner = new ScriptRunner(Database, Database.Configuration, false);
                    scriptRunner.TryCompileScript(string.Format(@"
                    function execute(){{
                        {0}
                    }};", options.TransformScript));
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Incorrect transform script", e);
                }

                NoContentStatus();
            }
        }
Ejemplo n.º 2
0
        public async Task PostExport()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var operationId       = GetLongQueryString("operationId", false) ?? Database.Operations.GetNextOperationId();
                var startDocumentEtag = GetLongQueryString("startEtag", false) ?? 0;

                var stream = TryGetRequestFromStream("DownloadOptions") ?? RequestBodyStream();


                DatabaseSmugglerOptionsServerSide options;
                using (context.GetManagedBuffer(out var buffer))
                {
                    var firstRead = await stream.ReadAsync(buffer.Buffer.Array, buffer.Buffer.Offset, buffer.Buffer.Count);

                    buffer.Used  = 0;
                    buffer.Valid = firstRead;
                    if (firstRead != 0)
                    {
                        var blittableJson = await context.ParseToMemoryAsync(stream, "DownloadOptions", BlittableJsonDocumentBuilder.UsageMode.None, buffer);

                        options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                    }
                    else
                    {
                        // no content, we'll use defaults
                        options = new DatabaseSmugglerOptionsServerSide();
                    }
                }

                ApplyBackwardCompatibility(options);

                var token = CreateOperationToken();

                var fileName = options.FileName;
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = $"Dump of {context.DocumentDatabase.Name} {SystemTime.UtcNow.ToString("yyyy-MM-dd HH-mm", CultureInfo.InvariantCulture)}";
                }

                var contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName) + ".ravendbdump";
                HttpContext.Response.Headers["Content-Disposition"] = contentDisposition;

                try
                {
                    await Database.Operations.AddOperation(
                        Database,
                        "Export database: " + Database.Name,
                        Operations.OperationType.DatabaseExport,
                        onProgress => Task.Run(() => ExportDatabaseInternal(options, startDocumentEtag, onProgress, context, token), token.Token), operationId, token : token);
                }
                catch (Exception)
                {
                    HttpContext.Abort();
                }
            }
        }
Ejemplo n.º 3
0
        public async Task PostExport()
        {
            DocumentsOperationContext context;

            using (ContextPool.AllocateOperationContext(out context))
                using (context.OpenReadTransaction())
                {
                    var operationId = GetIntValueQueryString("operationId", required: false);

                    var stream = TryGetRequestFormStream("DownloadOptions") ?? RequestBodyStream();

                    var blittableJson = await context.ReadForMemoryAsync(stream, "DownloadOptions");

                    var options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);

                    var exporter = new SmugglerExporter(Database, options);
                    var token    = CreateOperationToken();

                    var fileName = exporter.Options.FileName;
                    if (string.IsNullOrEmpty(fileName))
                    {
                        fileName = $"Dump of {context.DocumentDatabase.Name} {SystemTime.UtcNow.ToString("yyyy-MM-dd HH-mm", CultureInfo.InvariantCulture)}";
                    }

                    var contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName) + ".ravendbdump";
                    HttpContext.Response.Headers["Content-Disposition"] = contentDisposition;

                    if (operationId.HasValue)
                    {
                        try
                        {
                            await
                            Database.Operations.AddOperation("Export database: " + Database.Name,
                                                             DatabaseOperations.PendingOperationType.DatabaseExport,
                                                             onProgress =>
                                                             Task.Run(() => ExportDatabaseInternal(context, exporter, onProgress, token),
                                                                      token.Token), operationId.Value, token);
                        }
                        catch (Exception)
                        {
                            HttpContext.Abort();
                        }
                    }
                    else
                    {
                        ExportDatabaseInternal(context, exporter, null, token);
                    }
                }
        }
Ejemplo n.º 4
0
        public async Task PostValidateOptions()
        {
            DocumentsOperationContext context;

            using (ContextPool.AllocateOperationContext(out context))
                using (context.OpenReadTransaction())
                {
                    var blittableJson = await context.ReadForMemoryAsync(RequestBodyStream(), "");

                    var options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);

                    if (!string.IsNullOrEmpty(options.FileName) && options.FileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
                    {
                        throw new InvalidOperationException($"{options.FileName} is Invalid File Name");
                    }

                    if (string.IsNullOrEmpty(options?.TransformScript))
                    {
                        return;
                    }

                    try
                    {
                        var jint = new Engine(cfg =>
                        {
                            cfg.AllowDebuggerStatement(false);
                            cfg.MaxStatements(options.MaxStepsForTransformScript);
                            cfg.NullPropagation();
                        });

                        jint.Execute(string.Format(@"
                    function Transform(docInner){{
                        return ({0}).apply(this, [docInner]);
                    }};", options.TransformScript));
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException("Incorrect transform script", e);
                    }
                }
        }
Ejemplo n.º 5
0
        public async Task PostExport()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var operationId       = GetLongQueryString("operationId", true);
                var startDocumentEtag = GetLongQueryString("startEtag", false) ?? 0;

                var stream = TryGetRequestFormStream("DownloadOptions") ?? RequestBodyStream();

                var blittableJson = await context.ReadForMemoryAsync(stream, "DownloadOptions");

                var options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);

                var token = CreateOperationToken();

                var fileName = options.FileName;
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = $"Dump of {context.DocumentDatabase.Name} {SystemTime.UtcNow.ToString("yyyy-MM-dd HH-mm", CultureInfo.InvariantCulture)}";
                }

                var contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName) + ".ravendbdump";
                HttpContext.Response.Headers["Content-Disposition"] = contentDisposition;

                try
                {
                    await
                    Database.Operations.AddOperation(
                        Database,
                        "Export database: " + Database.Name,
                        Operations.OperationType.DatabaseExport,
                        onProgress => Task.Run(() => ExportDatabaseInternal(options, startDocumentEtag, onProgress, context, token), token.Token), operationId.Value, token);
                }
                catch (Exception)
                {
                    HttpContext.Abort();
                }
            }
        }
Ejemplo n.º 6
0
        public async Task PostImportAsync()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                if (HttpContext.Request.HasFormContentType == false)
                {
                    HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; // Bad request
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Type"]  = "Error",
                            ["Error"] = "This endpoint requires form content type"
                        });
                        return;
                    }
                }

                var operationId = GetLongQueryString("operationId");
                var token       = CreateOperationToken();

                var result = new SmugglerResult();
                await Database.Operations.AddOperation(Database, "Import to: " + Database.Name,
                                                       Operations.OperationType.DatabaseImport,
                                                       onProgress =>
                {
                    return(Task.Run(async() =>
                    {
                        try
                        {
                            var boundary = MultipartRequestHelper.GetBoundary(
                                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                                MultipartRequestHelper.MultipartBoundaryLengthLimit);
                            var reader = new MultipartReader(boundary, HttpContext.Request.Body);
                            DatabaseSmugglerOptionsServerSide options = null;

                            while (true)
                            {
                                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
                                if (section == null)
                                {
                                    break;
                                }

                                if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition) == false)
                                {
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                                {
                                    var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                                    if (key != "importOptions")
                                    {
                                        continue;
                                    }

                                    BlittableJsonReaderObject blittableJson;
                                    if (section.Headers.ContainsKey("Content-Encoding") && section.Headers["Content-Encoding"] == "gzip")
                                    {
                                        using (var gzipStream = new GZipStream(section.Body, CompressionMode.Decompress))
                                        {
                                            blittableJson = await context.ReadForMemoryAsync(gzipStream, "importOptions");
                                        }
                                    }
                                    else
                                    {
                                        blittableJson = await context.ReadForMemoryAsync(section.Body, "importOptions");
                                    }

                                    options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition) == false)
                                {
                                    continue;
                                }

                                var stream = new GZipStream(section.Body, CompressionMode.Decompress);
                                DoImportInternal(context, stream, options, result, onProgress, token);
                            }
                        }
                        catch (Exception e)
                        {
                            result.AddError($"Error occurred during export. Exception: {e.Message}");
                            throw;
                        }

                        return (IOperationResult)result;
                    }));
                }, operationId, token).ConfigureAwait(false);

                WriteImportResult(context, result, ResponseBodyStream());
            }
Ejemplo n.º 7
0
        public async Task PostExport()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var operationId       = GetLongQueryString("operationId", false) ?? Database.Operations.GetNextOperationId();
                var startDocumentEtag = GetLongQueryString("startEtag", false) ?? 0;
                var startRaftIndex    = GetLongQueryString("startRaftIndex", false) ?? 0;

                var stream = TryGetRequestFromStream("DownloadOptions") ?? RequestBodyStream();


                DatabaseSmugglerOptionsServerSide options;
                using (context.GetMemoryBuffer(out var buffer))
                {
                    var firstRead = await stream.ReadAsync(buffer.Memory);

                    buffer.Used  = 0;
                    buffer.Valid = firstRead;
                    if (firstRead != 0)
                    {
                        var blittableJson = await context.ParseToMemoryAsync(stream, "DownloadOptions", BlittableJsonDocumentBuilder.UsageMode.None, buffer);

                        options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                    }
                    else
                    {
                        // no content, we'll use defaults
                        options = new DatabaseSmugglerOptionsServerSide();
                    }
                }

                if (string.IsNullOrWhiteSpace(options.EncryptionKey) == false)
                {
                    ServerStore.LicenseManager.AssertCanCreateEncryptedDatabase();
                }

                var feature = HttpContext.Features.Get <IHttpAuthenticationFeature>() as RavenServer.AuthenticateConnection;

                if (feature == null)
                {
                    options.AuthorizationStatus = AuthorizationStatus.DatabaseAdmin;
                }
                else
                {
                    options.AuthorizationStatus = feature.CanAccess(Database.Name, requireAdmin: true) ? AuthorizationStatus.DatabaseAdmin : AuthorizationStatus.ValidUser;
                }

                ApplyBackwardCompatibility(options);

                var token = CreateOperationToken();

                var fileName = options.FileName;
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = $"Dump of {context.DocumentDatabase.Name} {SystemTime.UtcNow.ToString("yyyy-MM-dd HH-mm", CultureInfo.InvariantCulture)}";
                }

                var contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName) + ".ravendbdump";
                HttpContext.Response.Headers["Content-Disposition"] = contentDisposition;

                try
                {
                    await Database.Operations.AddOperation(
                        Database,
                        "Export database: " + Database.Name,
                        Operations.OperationType.DatabaseExport,
                        onProgress => Task.Run(() => ExportDatabaseInternal(options, startDocumentEtag, startRaftIndex, onProgress, context, token), token.Token), operationId, token : token);
                }
                catch (Exception)
                {
                    HttpContext.Abort();
                }
            }
        }
Ejemplo n.º 8
0
        public async Task PostImportAsync()
        {
            DocumentsOperationContext context;

            using (ContextPool.AllocateOperationContext(out context))
            {
                if (HttpContext.Request.HasFormContentType == false)
                {
                    HttpContext.Response.StatusCode = 400; // Bad request
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Type"]  = "Error",
                            ["Error"] = "This endpoint requires form content type"
                        });
                        return;
                    }
                }

                var operationId = GetLongQueryString("operationId", required: true) ?? -1;
                var token       = CreateOperationToken();
                var sp          = Stopwatch.StartNew();

                var result = new ImportResult();
                await Database.Operations.AddOperation("Import to: " + Database.Name,
                                                       DatabaseOperations.PendingOperationType.DatabaseImport,
                                                       onProgress =>
                {
                    return(Task.Run(async() =>
                    {
                        try
                        {
                            var boundary = MultipartRequestHelper.GetBoundary(
                                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                                MultipartRequestHelper.MultipartBoundaryLengthLimit);
                            var reader = new MultipartReader(boundary, HttpContext.Request.Body);
                            DatabaseSmugglerOptions smugglerOptions = null;

                            while (true)
                            {
                                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
                                if (section == null)
                                {
                                    break;
                                }

                                ContentDispositionHeaderValue contentDisposition;
                                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                                                                                                         out contentDisposition);

                                if (hasContentDispositionHeader == false)
                                {
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                                {
                                    var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                                    if (key != "importOptions")
                                    {
                                        continue;
                                    }

                                    var blittableJson = await context.ReadForMemoryAsync(section.Body, "importOptions");
                                    smugglerOptions = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition) == false)
                                {
                                    continue;
                                }

                                var stream = new GZipStream(section.Body, CompressionMode.Decompress);
                                var fileImport =
                                    await DoImportInternal(context, stream, smugglerOptions, onProgress).ConfigureAwait(false);
                                result.DocumentsCount += fileImport.DocumentsCount;
                                result.Warnings.AddRange(fileImport.Warnings);
                                result.IdentitiesCount += fileImport.IdentitiesCount;
                                result.Message = fileImport.Message;
                                result.RevisionDocumentsCount += fileImport.RevisionDocumentsCount;
                                result.IndexesCount += fileImport.IndexesCount;
                                result.TransformersCount += fileImport.TransformersCount;
                            }
                        }
                        catch (Exception e)
                        {
                            result.Message = $"Error occured during export. Exception: {e.Message}";
                            result.Exception = e.ToString();
                        }

                        return (IOperationResult)result;
                    }));
                }, operationId, token).ConfigureAwait(false);

                WriteImportResult(context, sp, result, ResponseBodyStream());
            }
        }