Esempio n. 1
0
        public async Task list_objects()
        {
            var file1 = "file1.txt";
            var file2 = "folder1/file2.txt";

            using (var client = new RavenGoogleCloudClient(GoogleCloudFact.GoogleCloudSettings))
            {
                try
                {
                    // Upload some files
                    var content = Encoding.UTF8.GetBytes("hello, world");
                    await client.UploadObjectAsync(file1, new MemoryStream(content));

                    await client.UploadObjectAsync(file2, new MemoryStream(content));

                    var objects = await client.ListObjectsAsync();

                    Assert.Contains(objects, o => o.Name == file1);
                    Assert.Contains(objects, o => o.Name == file2);
                }

                finally
                {
                    await client.DeleteObjectAsync(file1);

                    await client.DeleteObjectAsync(file2);
                }
            }
        }
Esempio n. 2
0
        public override void Dispose()
        {
            base.Dispose();

            var settings = GetGoogleCloudSettings();

            if (settings == null)
            {
                return;
            }

            try
            {
                using (var client = new RavenGoogleCloudClient(settings))
                {
                    var cloudObjects = client.ListObjectsAsync(settings.RemoteFolderName).GetAwaiter().GetResult();

                    foreach (var cloudObject in cloudObjects)
                    {
                        try
                        {
                            client.DeleteObjectAsync(cloudObject.Name).GetAwaiter().GetResult();
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
Esempio n. 3
0
        private async Task <bool> IsFileNameInCloudObjects(RavenGoogleCloudClient client, string fileName)
        {
            var cloudObjects = await client.ListObjectsAsync();

            var containsFileName = cloudObjects?.Any(x => x.Name == fileName) ?? false;

            return(containsFileName);
        }
Esempio n. 4
0
        protected override async Task <List <string> > GetFilesForRestore()
        {
            var prefix     = string.IsNullOrEmpty(_remoteFolderName) ? "" : _remoteFolderName.TrimEnd('/');
            var allObjects = await _client.ListObjectsAsync(prefix, delimiter : null);

            var result = new List <string>();

            foreach (var obj in allObjects)
            {
                result.Add(obj.Name);
            }

            return(result);
        }
Esempio n. 5
0
        public async Task delete_objects()
        {
            var fileName = Guid.NewGuid().ToString();

            using (var client = new RavenGoogleCloudClient(GoogleCloudFact.GoogleCloudSettings))
            {
                await client.UploadObjectAsync(
                    fileName,
                    new MemoryStream(Encoding.UTF8.GetBytes("123"))
                    );

                await client.DeleteObjectAsync(fileName);

                Assert.Empty(await client.ListObjectsAsync());
            }
        }
Esempio n. 6
0
        protected override async Task <List <FileInfoDetails> > GetFiles(string path)
        {
            var objects = await _client.ListObjectsAsync(path, delimiter : null);

            var filesInfo = new List <FileInfoDetails>();

            foreach (var obj in objects)
            {
                if (TryExtractDateFromFileName(obj.Name, out var lastModified) == false)
                {
                    lastModified = Convert.ToDateTime(obj.Updated);
                }

                var fullPath      = obj.Name;
                var directoryPath = GetDirectoryName(fullPath);
                filesInfo.Add(new FileInfoDetails(fullPath, directoryPath, lastModified));
            }

            return(filesInfo);
        }
Esempio n. 7
0
        protected override async Task <List <FileInfoDetails> > GetFiles(string path)
        {
            var objects = await _client.ListObjectsAsync(path, "/");

            var filesInfo = new List <FileInfoDetails>();

            foreach (var obj in objects)
            {
                if (TryExtractDateFromFileName(obj.Name, out var lastModified) == false)
                {
                    lastModified = Convert.ToDateTime(obj.Updated);
                }

                filesInfo.Add(new FileInfoDetails
                {
                    FullPath     = obj.Name,
                    LastModified = lastModified
                });
            }

            return(filesInfo);
        }
Esempio n. 8
0
        private static async Task DeleteObjects(GoogleCloudSettings settings)
        {
            if (settings == null)
            {
                return;
            }

            try
            {
                using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                {
                    var all = await client.ListObjectsAsync(prefix : settings.RemoteFolderName);

                    foreach (var obj in all)
                    {
                        await client.DeleteObjectAsync(obj.Name);
                    }
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
Esempio n. 9
0
        public async Task CanHandleSpecialCharsInFolderPath()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    using (var session = store.OpenAsyncSession())
                    {
                        var today = DateTime.Today;
                        await session.StoreAsync(new Order
                        {
                            OrderedAt = today,
                            Lines     = new List <OrderLine>
                            {
                                new OrderLine
                                {
                                    ProductName  = "Wimmers gute Semmelknödel",
                                    PricePerUnit = 12
                                },
                                new OrderLine
                                {
                                    ProductName  = "Guaraná Fantástica",
                                    PricePerUnit = 42
                                },

                                new OrderLine
                                {
                                    ProductName  = "Thüringer Rostbratwurst",
                                    PricePerUnit = 19
                                }
                            }
                        });

                        await session.StoreAsync(new Order
                        {
                            OrderedAt = today.AddYears(-1),
                            Lines     = new List <OrderLine>
                            {
                                new OrderLine
                                {
                                    ProductName  = "Uncle Bob's Cajon Sauce",
                                    PricePerUnit = 11
                                },
                                new OrderLine
                                {
                                    ProductName  = "Côte de Blaye",
                                    PricePerUnit = 25
                                }
                            }
                        });

                        await session.StoreAsync(new Order
                        {
                            OrderedAt = today.AddYears(-2),
                            Lines     = new List <OrderLine>
                            {
                                new OrderLine
                                {
                                    ProductName  = "גבינה צהובה",
                                    PricePerUnit = 20
                                },
                                new OrderLine
                                {
                                    ProductName  = "במבה",
                                    PricePerUnit = 7
                                }
                            }
                        });

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
for (var i = 0; i < this.Lines.length; i++){
    var line  = this.Lines[i];
    loadToOrders(partitionBy(['product-name', line.ProductName]), {
        PricePerUnit: line.PricePerUnit,
        OrderedAt: this.OrderedAt
})}";
                    SetupGoogleCloudOlapEtl(store, script, settings);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{CollectionName}";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(7, cloudObjects.Count);

                        Assert.Contains("Côte de Blaye", cloudObjects[0].Name);
                        Assert.Contains("Guaraná Fantástica", cloudObjects[1].Name);
                        Assert.Contains("Thüringer Rostbratwurst", cloudObjects[2].Name);
                        Assert.Contains("Uncle Bob's Cajon Sauce", cloudObjects[3].Name);
                        Assert.Contains("Wimmers gute Semmelknödel", cloudObjects[4].Name);
                        Assert.Contains("במבה", cloudObjects[5].Name);
                        Assert.Contains("גבינה צהובה", cloudObjects[6].Name);
                    }
                }
            }
            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 10
0
        public async Task SimpleTransformation_MultiplePartitions()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    var baseline = DateTime.SpecifyKind(new DateTime(2020, 1, 1), DateTimeKind.Utc);

                    using (var session = store.OpenAsyncSession())
                    {
                        const int total = 31 + 28; // days in January + days in February

                        for (int i = 0; i < total; i++)
                        {
                            var orderedAt = baseline.AddDays(i);
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = orderedAt,
                                RequireAt = orderedAt.AddDays(7),
                                ShipVia   = $"shippers/{i}",
                                Company   = $"companies/{i}"
                            });
                        }

                        for (int i = 1; i <= 37; i++)
                        {
                            var index     = i + total;
                            var orderedAt = baseline.AddYears(1).AddMonths(1).AddDays(i);
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{index}",
                                OrderedAt = orderedAt,
                                RequireAt = orderedAt.AddDays(7),
                                ShipVia   = $"shippers/{index}",
                                Company   = $"companies/{index}"
                            });
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
var orderDate = new Date(this.OrderedAt);

loadToOrders(partitionBy(
    ['year', orderDate.getFullYear()],
    ['month', orderDate.getMonth() + 1]
),
    {
        Company : this.Company,
        ShipVia : this.ShipVia,
        RequireAt : this.RequireAt
    });
";
                    SetupGoogleCloudOlapEtl(store, script, settings);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    var expectedFields = new[] { "RequireAt", "ShipVia", "Company", ParquetTransformedItems.DefaultIdColumn, ParquetTransformedItems.LastModifiedColumn };

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{CollectionName}/";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(4, cloudObjects.Count);
                        Assert.Contains("Orders/year=2020/month=1", cloudObjects[0].Name);
                        Assert.Contains("Orders/year=2020/month=2", cloudObjects[1].Name);
                        Assert.Contains("Orders/year=2021/month=2", cloudObjects[2].Name);
                        Assert.Contains("Orders/year=2021/month=3", cloudObjects[3].Name);
                    }
                }
            }
            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 11
0
        public async Task SimpleTransformation_NoPartition()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    var baseline = new DateTime(2020, 1, 1).ToUniversalTime();

                    using (var session = store.OpenAsyncSession())
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = baseline.AddDays(i),
                                ShipVia   = $"shippers/{i}",
                                Company   = $"companies/{i}"
                            });
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
loadToOrders(noPartition(),
    {
        OrderDate : this.OrderedAt
        Company : this.Company,
        ShipVia : this.ShipVia
    });
";
                    SetupGoogleCloudOlapEtl(store, script, settings);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix = $"{settings.RemoteFolderName}/{CollectionName}";

                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(1, cloudObjects.Count);

                        var stream = client.DownloadObject(cloudObjects[0].Name);
                        var ms     = new MemoryStream();
                        stream.CopyTo(ms);

                        using (var parquetReader = new ParquetReader(ms))
                        {
                            Assert.Equal(1, parquetReader.RowGroupCount);

                            var expectedFields = new[] { "OrderDate", "ShipVia", "Company", ParquetTransformedItems.DefaultIdColumn, ParquetTransformedItems.LastModifiedColumn };

                            Assert.Equal(expectedFields.Length, parquetReader.Schema.Fields.Count);

                            using var rowGroupReader = parquetReader.OpenRowGroupReader(0);
                            foreach (var field in parquetReader.Schema.Fields)
                            {
                                Assert.True(field.Name.In(expectedFields));

                                var data = rowGroupReader.ReadColumn((DataField)field).Data;
                                Assert.True(data.Length == 100);

                                if (field.Name == ParquetTransformedItems.LastModifiedColumn)
                                {
                                    continue;
                                }

                                var count = 0;
                                foreach (var val in data)
                                {
                                    if (field.Name == "OrderDate")
                                    {
                                        var expectedDto = new DateTimeOffset(DateTime.SpecifyKind(baseline.AddDays(count), DateTimeKind.Utc));
                                        Assert.Equal(expectedDto, val);
                                    }

                                    else
                                    {
                                        var expected = field.Name switch
                                        {
                                            ParquetTransformedItems.DefaultIdColumn => $"orders/{count}",
                                            "Company" => $"companies/{count}",
                                            "ShipVia" => $"shippers/{count}",
                                            _ => null
                                        };

                                        Assert.Equal(expected, val);
                                    }

                                    count++;
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 12
0
        public async Task CanModifyPartitionColumnName()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    const string partitionColumn = "order_date";

                    var baseline = new DateTime(2020, 1, 1);

                    using (var session = store.OpenAsyncSession())
                    {
                        for (int i = 0; i < 31; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = baseline.AddDays(i),
                                ShipVia   = $"shippers/{i}",
                                Company   = $"companies/{i}"
                            });
                        }

                        for (int i = 0; i < 28; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i + 31}",
                                OrderedAt = baseline.AddMonths(1).AddDays(i),
                                ShipVia   = $"shippers/{i + 31}",
                                Company   = $"companies/{i + 31}"
                            });
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
var orderDate = new Date(this.OrderedAt);
var year = orderDate.getFullYear();
var month = orderDate.getMonth();
var key = new Date(year, month);

loadToOrders(partitionBy(['order_date', key]),
    {
        Company : this.Company,
        ShipVia : this.ShipVia
    })
";
                    var connectionStringName = $"{store.Database} to GCP";

                    var configuration = new OlapEtlConfiguration
                    {
                        Name = "olap-gcp-test",
                        ConnectionStringName = connectionStringName,
                        RunFrequency         = LocalTests.DefaultFrequency,
                        Transforms           =
                        {
                            new Transformation
                            {
                                Name        = "MonthlyOrders",
                                Collections = new List <string>{
                                    "Orders"
                                },
                                Script = script
                            }
                        }
                    };

                    SetupGoogleCloudOlapEtl(store, settings, configuration);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{CollectionName}";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(2, cloudObjects.Count);

                        Assert.Contains($"{partitionColumn}=2020-01-01", cloudObjects[0].Name);
                        Assert.Contains($"{partitionColumn}=2020-02-01", cloudObjects[1].Name);
                    }
                }
            }

            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 13
0
        public async Task CanUploadToGoogleCloud()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    var baseline = new DateTime(2020, 1, 1);

                    using (var session = store.OpenAsyncSession())
                    {
                        for (int i = 0; i < 31; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = baseline.AddDays(i),
                                ShipVia   = $"shippers/{i}",
                                Company   = $"companies/{i}"
                            });
                        }

                        for (int i = 0; i < 28; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i + 31}",
                                OrderedAt = baseline.AddMonths(1).AddDays(i),
                                ShipVia   = $"shippers/{i + 31}",
                                Company   = $"companies/{i + 31}"
                            });
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
var orderDate = new Date(this.OrderedAt);
var year = orderDate.getFullYear();
var month = orderDate.getMonth();
var key = new Date(year, month);

loadToOrders(partitionBy(key),
    {
        Company : this.Company,
        ShipVia : this.ShipVia
    })
";
                    SetupGoogleCloudOlapEtl(store, script, settings);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{CollectionName}";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(2, cloudObjects.Count);
                        Assert.Contains("2020-01-01", cloudObjects[0].Name);
                        Assert.Contains("2020-02-01", cloudObjects[1].Name);
                    }
                }
            }

            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 14
0
        public async Task CanLoadToMultipleTables()
        {
            const string salesTableName = "Sales";
            var          settings       = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    var baseline = new DateTime(2020, 1, 1);

                    using (var session = store.OpenAsyncSession())
                    {
                        for (int i = 0; i < 31; i++)
                        {
                            var orderedAt = baseline.AddDays(i);
                            var lines     = new List <OrderLine>();

                            for (int j = 1; j <= 5; j++)
                            {
                                lines.Add(new OrderLine
                                {
                                    Quantity     = j * 10,
                                    PricePerUnit = i + j,
                                    Product      = $"Products/{j}"
                                });
                            }

                            var o = new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = orderedAt,
                                RequireAt = orderedAt.AddDays(7),
                                Company   = $"companies/{i}",
                                Lines     = lines
                            };

                            await session.StoreAsync(o);
                        }

                        baseline = baseline.AddMonths(1);

                        for (int i = 0; i < 28; i++)
                        {
                            var orderedAt = baseline.AddDays(i);
                            var lines     = new List <OrderLine>();

                            for (int j = 1; j <= 5; j++)
                            {
                                lines.Add(new OrderLine
                                {
                                    Quantity     = j * 10,
                                    PricePerUnit = i + j,
                                    Product      = $"Products/{j}"
                                });
                            }

                            var o = new Order
                            {
                                Id        = $"orders/{i + 31}",
                                OrderedAt = orderedAt,
                                RequireAt = orderedAt.AddDays(7),
                                Company   = $"companies/{i}",
                                Lines     = lines
                            };

                            await session.StoreAsync(o);
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
var orderData = {
    Company : this.Company,
    RequireAt : new Date(this.RequireAt),
    ItemsCount: this.Lines.length,
    TotalCost: 0
};

var orderDate = new Date(this.OrderedAt);
var year = orderDate.getFullYear();
var month = orderDate.getMonth();
var key = new Date(year, month);

for (var i = 0; i < this.Lines.length; i++) {
    var line = this.Lines[i];
    orderData.TotalCost += (line.PricePerUnit * line.Quantity);
    
    // load to 'sales' table

    loadToSales(partitionBy(key), {
        Qty: line.Quantity,
        Product: line.Product,
        Cost: line.PricePerUnit
    });
}

// load to 'orders' table
loadToOrders(partitionBy(key), orderData);
";

                    SetupGoogleCloudOlapEtl(store, script, settings);
                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{CollectionName}";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(2, cloudObjects.Count);
                        Assert.Contains("2020-01-01", cloudObjects[0].Name);
                        Assert.Contains("2020-02-01", cloudObjects[1].Name);

                        var fullPath = cloudObjects[0].Name;
                        var stream   = client.DownloadObject(fullPath);
                        var ms       = new MemoryStream();
                        await stream.CopyToAsync(ms);

                        using (var parquetReader = new ParquetReader(ms))
                        {
                            Assert.Equal(1, parquetReader.RowGroupCount);

                            var expectedFields = new[] { "Company", "RequireAt", "ItemsCount", "TotalCost", ParquetTransformedItems.DefaultIdColumn, ParquetTransformedItems.LastModifiedColumn };
                            Assert.Equal(expectedFields.Length, parquetReader.Schema.Fields.Count);

                            using var rowGroupReader = parquetReader.OpenRowGroupReader(0);
                            foreach (var field in parquetReader.Schema.Fields)
                            {
                                Assert.True(field.Name.In(expectedFields));

                                var data = rowGroupReader.ReadColumn((DataField)field).Data;
                                Assert.True(data.Length == 31);
                            }
                        }
                    }

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{salesTableName}";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(2, cloudObjects.Count);
                        Assert.Contains("2020-01-01", cloudObjects[0].Name);
                        Assert.Contains("2020-02-01", cloudObjects[1].Name);

                        var fullPath = cloudObjects[1].Name;
                        var stream   = client.DownloadObject(fullPath);
                        var ms       = new MemoryStream();
                        await stream.CopyToAsync(ms);

                        using (var parquetReader = new ParquetReader(ms))
                        {
                            Assert.Equal(1, parquetReader.RowGroupCount);

                            var expectedFields = new[] { "Qty", "Product", "Cost", ParquetTransformedItems.DefaultIdColumn, ParquetTransformedItems.LastModifiedColumn };
                            Assert.Equal(expectedFields.Length, parquetReader.Schema.Fields.Count);

                            using var rowGroupReader = parquetReader.OpenRowGroupReader(0);
                            foreach (var field in parquetReader.Schema.Fields)
                            {
                                Assert.True(field.Name.In(expectedFields));

                                var data = rowGroupReader.ReadColumn((DataField)field).Data;
                                Assert.True(data.Length == 28 * 5);
                            }
                        }
                    }
                }
            }
            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 15
0
        public async Task SimpleTransformation()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    var baseline = new DateTime(2020, 1, 1);

                    using (var session = store.OpenAsyncSession())
                    {
                        for (int i = 1; i <= 10; i++)
                        {
                            var o = new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = baseline.AddDays(i),
                                Company   = $"companies/{i}"
                            };

                            await session.StoreAsync(o);
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
var orderDate = new Date(this.OrderedAt);
var year = orderDate.getFullYear();
var month = orderDate.getMonth();
var key = new Date(year, month);

loadToOrders(partitionBy(key),
    {
        Company : this.Company,
        ShipVia : this.ShipVia
    })
";
                    SetupGoogleCloudOlapEtl(store, script, settings);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix = $"{settings.RemoteFolderName}/{CollectionName}";

                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(1, cloudObjects.Count);

                        var fullPath = cloudObjects[0].Name;
                        var stream   = client.DownloadObject(fullPath);
                        var ms       = new MemoryStream();
                        stream.CopyTo(ms);

                        using (var parquetReader = new ParquetReader(ms))
                        {
                            Assert.Equal(1, parquetReader.RowGroupCount);

                            var expectedFields = new[] { "Company", ParquetTransformedItems.DefaultIdColumn, ParquetTransformedItems.LastModifiedColumn };

                            Assert.Equal(expectedFields.Length, parquetReader.Schema.Fields.Count);

                            using var rowGroupReader = parquetReader.OpenRowGroupReader(0);
                            foreach (var field in parquetReader.Schema.Fields)
                            {
                                Assert.True(field.Name.In(expectedFields));

                                var data = rowGroupReader.ReadColumn((DataField)field).Data;
                                Assert.True(data.Length == 10);

                                if (field.Name == ParquetTransformedItems.LastModifiedColumn)
                                {
                                    continue;
                                }

                                var count = 1;
                                foreach (var val in data)
                                {
                                    switch (field.Name)
                                    {
                                    case ParquetTransformedItems.DefaultIdColumn:
                                        Assert.Equal($"orders/{count}", val);
                                        break;

                                    case "Company":
                                        Assert.Equal($"companies/{count}", val);
                                        break;
                                    }

                                    count++;
                                }
                            }
                        }
                    }
                }
            }

            finally
            {
                await DeleteObjects(settings);
            }
        }
Esempio n. 16
0
        public async Task GetFolderPathOptions()
        {
            PeriodicBackupConnectionType connectionType;
            var type = GetStringValuesQueryString("type", false).FirstOrDefault();

            if (type == null)
            {
                //Backward compatibility
                connectionType = PeriodicBackupConnectionType.Local;
            }
            else if (Enum.TryParse(type, out connectionType) == false)
            {
                throw new ArgumentException($"Query string '{type}' was not recognized as valid type");
            }

            using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
            {
                var folderPathOptions = new FolderPathOptions();
                ;
                switch (connectionType)
                {
                case PeriodicBackupConnectionType.Local:
                    var isBackupFolder = GetBoolValueQueryString("backupFolder", required: false) ?? false;
                    var path           = GetStringQueryString("path", required: false);
                    folderPathOptions = FolderPath.GetOptions(path, isBackupFolder, ServerStore.Configuration);
                    break;

                case PeriodicBackupConnectionType.S3:
                    var json = await context.ReadForMemoryAsync(RequestBodyStream(), "studio-tasks/format");

                    if (connectionType != PeriodicBackupConnectionType.Local && json == null)
                    {
                        throw new BadRequestException("No JSON was posted.");
                    }

                    var s3Settings = JsonDeserializationServer.S3Settings(json);
                    if (s3Settings == null)
                    {
                        throw new BadRequestException("No S3Settings were found.");
                    }

                    if (string.IsNullOrWhiteSpace(s3Settings.AwsAccessKey) ||
                        string.IsNullOrWhiteSpace(s3Settings.AwsSecretKey) ||
                        string.IsNullOrWhiteSpace(s3Settings.BucketName) ||
                        string.IsNullOrWhiteSpace(s3Settings.AwsRegionName))
                    {
                        break;
                    }

                    using (var client = new RavenAwsS3Client(s3Settings, ServerStore.Configuration.Backup))
                    {
                        // fetching only the first 64 results for the auto complete
                        var folders = await client.ListObjectsAsync(s3Settings.RemoteFolderName, "/", true, take : 64);

                        if (folders != null)
                        {
                            foreach (var folder in folders.FileInfoDetails)
                            {
                                var fullPath = folder.FullPath;
                                if (string.IsNullOrWhiteSpace(fullPath))
                                {
                                    continue;
                                }

                                folderPathOptions.List.Add(fullPath);
                            }
                        }
                    }
                    break;

                case PeriodicBackupConnectionType.Azure:
                    var azureJson = await context.ReadForMemoryAsync(RequestBodyStream(), "studio-tasks/format");

                    if (connectionType != PeriodicBackupConnectionType.Local && azureJson == null)
                    {
                        throw new BadRequestException("No JSON was posted.");
                    }

                    var azureSettings = JsonDeserializationServer.AzureSettings(azureJson);
                    if (azureSettings == null)
                    {
                        throw new BadRequestException("No AzureSettings were found.");
                    }

                    if (string.IsNullOrWhiteSpace(azureSettings.AccountName) ||
                        string.IsNullOrWhiteSpace(azureSettings.AccountKey) ||
                        string.IsNullOrWhiteSpace(azureSettings.StorageContainer))
                    {
                        break;
                    }

                    using (var client = RavenAzureClient.Create(azureSettings, ServerStore.Configuration.Backup))
                    {
                        var folders = (await client.ListBlobsAsync(azureSettings.RemoteFolderName, "/", true));

                        foreach (var folder in folders.List)
                        {
                            var fullPath = folder.Name;
                            if (string.IsNullOrWhiteSpace(fullPath))
                            {
                                continue;
                            }

                            folderPathOptions.List.Add(fullPath);
                        }
                    }
                    break;

                case PeriodicBackupConnectionType.GoogleCloud:
                    var googleCloudJson = await context.ReadForMemoryAsync(RequestBodyStream(), "studio-tasks/format");

                    if (connectionType != PeriodicBackupConnectionType.Local && googleCloudJson == null)
                    {
                        throw new BadRequestException("No JSON was posted.");
                    }

                    var googleCloudSettings = JsonDeserializationServer.GoogleCloudSettings(googleCloudJson);
                    if (googleCloudSettings == null)
                    {
                        throw new BadRequestException("No AzureSettings were found.");
                    }

                    if (string.IsNullOrWhiteSpace(googleCloudSettings.BucketName) ||
                        string.IsNullOrWhiteSpace(googleCloudSettings.GoogleCredentialsJson))
                    {
                        break;
                    }

                    using (var client = new RavenGoogleCloudClient(googleCloudSettings, ServerStore.Configuration.Backup))
                    {
                        var folders             = (await client.ListObjectsAsync(googleCloudSettings.RemoteFolderName));
                        var requestedPathLength = googleCloudSettings.RemoteFolderName.Split('/').Length;

                        foreach (var folder in folders)
                        {
                            const char separator = '/';
                            var        splitted  = folder.Name.Split(separator);
                            var        result    = string.Join(separator, splitted.Take(requestedPathLength)) + separator;

                            if (string.IsNullOrWhiteSpace(result))
                            {
                                continue;
                            }

                            folderPathOptions.List.Add(result);
                        }
                    }
                    break;

                case PeriodicBackupConnectionType.FTP:
                case PeriodicBackupConnectionType.Glacier:
                    throw new NotSupportedException();

                default:
                    throw new ArgumentOutOfRangeException();
                }

                await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    context.Write(writer, new DynamicJsonValue
                    {
                        [nameof(FolderPathOptions.List)] = TypeConverter.ToBlittableSupportedType(folderPathOptions.List)
                    });
                }
            }
        }
Esempio n. 17
0
        public async Task CanPartitionByCustomDataFieldViaScript()
        {
            var settings = GetGoogleCloudSettings();

            try
            {
                using (var store = GetDocumentStore())
                {
                    var baseline = new DateTime(2020, 1, 1);

                    using (var session = store.OpenAsyncSession())
                    {
                        for (int i = 0; i < 31; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i}",
                                OrderedAt = baseline.AddDays(i),
                                ShipVia   = $"shippers/{i}",
                                Company   = $"companies/{i}"
                            });
                        }

                        for (int i = 0; i < 28; i++)
                        {
                            await session.StoreAsync(new Order
                            {
                                Id        = $"orders/{i + 31}",
                                OrderedAt = baseline.AddMonths(1).AddDays(i),
                                ShipVia   = $"shippers/{i + 31}",
                                Company   = $"companies/{i + 31}"
                            });
                        }

                        await session.SaveChangesAsync();
                    }

                    var etlDone = WaitForEtl(store, (n, statistics) => statistics.LoadSuccesses != 0);

                    var script = @"
var orderDate = new Date(this.OrderedAt);
var year = orderDate.getFullYear();
var month = orderDate.getMonth() + 1;

loadToOrders(partitionBy(['year', year], ['month', month], ['source', $customPartitionValue]),
{
    Company : this.Company,
    ShipVia : this.ShipVia
});
";

                    const string customPartition = "shop-16";
                    SetupGoogleCloudOlapEtl(store, script, settings, customPartition: customPartition);

                    etlDone.Wait(TimeSpan.FromMinutes(1));

                    using (var client = new RavenGoogleCloudClient(settings, DefaultBackupConfiguration))
                    {
                        var prefix       = $"{settings.RemoteFolderName}/{CollectionName}/";
                        var cloudObjects = await client.ListObjectsAsync(prefix);

                        Assert.Equal(2, cloudObjects.Count);
                        Assert.Contains($"/Orders/year=2020/month=1/source={customPartition}/", cloudObjects[0].Name);
                        Assert.Contains($"/Orders/year=2020/month=2/source={customPartition}/", cloudObjects[1].Name);
                    }
                }
            }
            finally
            {
                await DeleteObjects(settings);
            }
        }