Beispiel #1
0
        public async Task Put()
        {
            using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context))
            {
                var input = await context.ReadForMemoryAsync(RequestBodyStream(), "Sorters");

                if (input.TryGet("Sorters", out BlittableJsonReaderArray analyzers) == false)
                {
                    ThrowRequiredPropertyNameInRequest("Sorters");
                }

                var commands = new List <PutServerWideSorterCommand>();
                foreach (var sorterToAdd in analyzers)
                {
                    var sorterDefinition = JsonDeserializationServer.SorterDefinition((BlittableJsonReaderObject)sorterToAdd);
                    sorterDefinition.Name = sorterDefinition.Name?.Trim();

                    if (LoggingSource.AuditLog.IsInfoEnabled)
                    {
                        var clientCert = GetCurrentCertificate();

                        var auditLog = LoggingSource.AuditLog.GetLogger("Server", "Audit");
                        auditLog.Info($"Sorter {sorterDefinition.Name} PUT by {clientCert?.Subject} {clientCert?.Thumbprint} with definition: {sorterToAdd}");
                    }

                    sorterDefinition.Validate();

                    // check if sorter is compilable
                    SorterCompiler.Compile(sorterDefinition.Name, sorterDefinition.Code);

                    var command = new PutServerWideSorterCommand(sorterDefinition, GetRaftRequestIdFromQuery());

                    commands.Add(command);
                }

                var index = 0L;
                foreach (var command in commands)
                {
                    index = (await ServerStore.SendToLeaderAsync(command)).Index;
                }

                await ServerStore.WaitForCommitIndexChange(RachisConsensus.CommitIndexModification.GreaterOrEqual, index);

                NoContentStatus(HttpStatusCode.Created);
            }
        }
Beispiel #2
0
        public async Task Get()
        {
            using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context))
                using (context.OpenReadTransaction())
                {
                    var sorters = new Dictionary <string, SorterDefinition>();

                    foreach (var item in ServerStore.Cluster.ItemsStartingWith(context, PutServerWideSorterCommand.Prefix, 0, long.MaxValue))
                    {
                        var sorterDefinition = JsonDeserializationServer.SorterDefinition(item.Value);

                        sorters.Add(PutServerWideSorterCommand.ExtractName(item.ItemName), sorterDefinition);
                    }

                    await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        writer.WriteStartObject();

                        writer.WriteArray(context, "Sorters", sorters.Values, (w, c, analyzer) =>
                        {
                            w.WriteStartObject();

                            w.WritePropertyName(nameof(SorterDefinition.Name));
                            w.WriteString(analyzer.Name);

                            w.WriteComma();
                            w.WritePropertyName(nameof(SorterDefinition.Code));
                            w.WriteString(analyzer.Code);

                            w.WriteEndObject();
                        });

                        writer.WriteEndObject();
                    }
                }
        }
Beispiel #3
0
        public void CanUseCustomSorter_Restart_Faulty()
        {
            var serverPath   = NewDataPath();
            var databasePath = NewDataPath();

            IOExtensions.DeleteDirectory(serverPath);
            IOExtensions.DeleteDirectory(databasePath);

            var sorterName = GetDatabaseName();

            using (var server = GetNewServer(new ServerCreationOptions
            {
                DataDirectory = serverPath,
                RunInMemory = false
            }))
                using (var store = GetDocumentStore(new Options
                {
                    ModifyDatabaseName = _ => sorterName,
                    Path = databasePath,
                    RunInMemory = false,
                    Server = server,
                    DeleteDatabaseOnDispose = false
                }))
                {
                    using (var session = store.OpenSession())
                    {
                        session.Store(new Company {
                            Name = "C1"
                        });
                        session.Store(new Company {
                            Name = "C2"
                        });

                        session.SaveChanges();
                    }

                    CanUseSorterInternal <SorterDoesNotExistException>(store, $"There is no sorter with '{sorterName}' name", $"There is no sorter with '{sorterName}' name", sorterName);

                    var sorterCode = GetSorter("RavenDB_8355.MySorter.cs", "MySorter", sorterName);

                    store.Maintenance.Server.Send(new PutServerWideSortersOperation(new SorterDefinition
                    {
                        Name = sorterName,
                        Code = sorterCode
                    }));

                    CanUseSorterInternal <RavenException>(store, "Catch me: Name:2:0:False", "Catch me: Name:2:0:True", sorterName);

                    server.ServerStore.DatabasesLandlord.UnloadDirectly(store.Database);

                    // skipping compilation on purpose
                    using (server.ServerStore.Engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                        using (var tx = context.OpenWriteTransaction())
                        {
                            var command = new PutServerWideSorterCommand(
                                new SorterDefinition {
                                Name = sorterName, Code = sorterCode.Replace(sorterCode, "MySorter")
                            },
                                RaftIdGenerator.NewId());

                            using (var json = context.ReadObject(command.ValueToJson(), command.Name))
                            {
                                ClusterStateMachine.PutValueDirectly(context, command.Name, json, 1);
                            }

                            tx.Commit();
                        }
                }

            SorterCompilationCache.Instance.RemoveServerWideItem(sorterName);

            using (var server = GetNewServer(new ServerCreationOptions
            {
                DataDirectory = serverPath,
                RunInMemory = false,
                DeletePrevious = false
            }))
                using (var store = GetDocumentStore(new Options
                {
                    ModifyDatabaseName = _ => sorterName,
                    Path = databasePath,
                    RunInMemory = false,
                    Server = server,
                    CreateDatabase = false
                }))
                {
                    CanUseSorterInternal <RavenException>(store, "is an implementation of a faulty sorter", "is an implementation of a faulty sorter", sorterName);

                    // can override with database sorter
                    store.Maintenance.Send(new PutSortersOperation(new SorterDefinition
                    {
                        Name = sorterName,
                        Code = GetSorter("RavenDB_8355.MySorter.cs", "MySorter", sorterName)
                    }));

                    CanUseSorterInternal <RavenException>(store, "Catch me: Name:2:0:False", "Catch me: Name:2:0:True", sorterName);

                    // can go back to server analyzer

                    store.Maintenance.Send(new DeleteSorterOperation(sorterName));

                    CanUseSorterInternal <RavenException>(store, "is an implementation of a faulty sorter", "is an implementation of a faulty sorter", sorterName);

                    // can fix server sorter
                    store.Maintenance.Server.Send(new PutServerWideSortersOperation(new SorterDefinition
                    {
                        Name = sorterName,
                        Code = GetSorter("RavenDB_8355.MySorter.cs", "MySorter", sorterName)
                    }));

                    CanUseSorterInternal <RavenException>(store, "Catch me: Name:2:0:False", "Catch me: Name:2:0:True", sorterName);
                }
        }