Ejemplo n.º 1
0
        public void TestUpdateOnceAndDispatch()
        {
            EventBean[] oldData = MakeEvents("old");
            EventBean[] newData = MakeEvents("new");
            _updateDispatchView.NewResult(new UniformPair <EventBean[]>(newData, oldData));

            Assert.IsFalse(_listenerOne.IsInvoked || _listenerTwo.IsInvoked);
            _dispatchService.Dispatch();
            Assert.IsTrue(_listenerOne.IsInvoked && _listenerTwo.IsInvoked);
            Assert.IsTrue(_listenerOne.LastNewData[0] == newData[0]);
            Assert.IsTrue(_listenerTwo.LastOldData[0] == oldData[0]);
        }
Ejemplo n.º 2
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            var log = new LogEntry();

            log.ProjectKey = _options.ProjectKey;
            log.Date       = DateTime.UtcNow;
            log.Context    = _name;

            log.Tags = new Dictionary <string, object>()
            {
                { "EventId", eventId }
            };

            if (exception == null)
            {
                log.Tags.Add("Message", formatter(state, exception));
            }
            else
            {
                log.Tags.Add("Exception", exception.ToString());
            }

            log.LogLevel = logLevel;

            _dispatchService.Dispatch(log, _options.RabbitMQ.Queue);
        }
Ejemplo n.º 3
0
        public void CalculationValueHaveToChangeTest()
        {
            var databaseFactory = new NPocoDataBaseFactory();
            var database        = databaseFactory.GetDatabase();
            var databaseTimer   = databaseFactory.GetDatabase();

            var stateDepot            = new TestStateDepot(database);
            var calculationDepot      = new TestCalculationDepot(database);
            var calculationDepotTimer = new TestCalculationDepot(databaseTimer);
            var circleDepot           = new TestSealingSlabDepot(database);
            var estimationDepot       = new TestEstimationDepot(database);
            var calculationViewDepot  = new TestCalculationViewDepot(database);

            var stateEnqueued = stateDepot.GetByName("Enqueued");

            var calculation = new Calculation
            {
                Id                                 = 1,
                StateId                            = stateEnqueued.Id,
                PixelsPerMeter                     = 1,
                Height                             = 500,
                Width                              = 500,
                BorderX                            = 20,
                BorderY                            = 20,
                Depth                              = 100,
                DrillingPointDistanceX             = 50,
                DrillingPointDistanceY             = 50,
                SealingSlabDiameter                = 80,
                Iterations                         = 1,
                StandardDerivationOffset           = 0.8m,
                StandardDerivationDrillingPoint    = 0,
                StandardDerivationRadius           = 0,
                SealingSlabThickness               = 10,
                PermeabilityOfSoleAtUnsetArea      = 15,
                PermeabilityOfSoleWithoutUnsetArea = 12,
                WaterLevelDifference               = 11,
            };

            calculationDepot.Save(calculation);

            var calculationService = new Services.TestCalculationService(stateDepot, calculationDepot, circleDepot, calculationViewDepot, databaseFactory);
            var estimationService  = new Services.TestEstimationService(estimationDepot);

            var dispatchService = new DispatchService(stateDepot, calculationDepot, calculationDepotTimer, circleDepot, calculationService, estimationService, database);

            dispatchService.Dispatch(400);

            Assert.IsNotNull(calculation.UnsetAreaResult, "UnsetAreaResult may not be null after dispatching");
            Assert.IsNotNull(calculation.ResidualWaterResult, "ResidualWaterResult may not be null after dispatching");

            var stateDone = stateDepot.GetByName("Done");

            Assert.AreEqual(stateDone.Id, calculation.StateId, "State has to be \"done\" after dispatching");
        }
        public async Task InvokeAsync(HttpContext context, IUser user)
        {
            // TODO
            // aqui irá logar somente entradas (requests) e saídas (responses) da API
            // está pegando o length do body tanto do request, quanto do response
            // o user iniciará nulo e apenas estará preenchido na volta após executar todos os outros middlewares
            // comunicacao com o rabbit foi abstraida de forma simples no dispatch service
            // caso de excessão irá logar o body da requisição
            // os logs de negócio do dominio serão logados pelo log provider

            var stopwatch = Stopwatch.StartNew();

            var log = new LogEntry();

            log.ProjectKey = _options.ProjectKey;
            log.Date       = DateTime.UtcNow;
            log.Context    = "Request";

            PreExecutionLog(context, log);

            if (context.Request.Method != "GET")
            {
                context.Request.EnableBuffering();
            }

            try
            {
                await _next(context);

                log.LogLevel = LogLevel.Debug;
            }
            catch (Exception ex)
            {
                log.LogLevel = LogLevel.Error;
                AddOrUpdateTag(log, $"Exception", ex.ToString());
                await RegisterContent(context, log);

                throw;
            }
            finally
            {
                PostExecutionLog(context, log, user, stopwatch);
                _dispatchService.Dispatch(log, _options.RabbitMQ.Queue);
            }
        }
Ejemplo n.º 5
0
            public bool Call()
            {
                Log.Info(".call Thread " + Thread.CurrentThread.ManagedThreadId + " starting");
                for (int i = 0; i < _numActions; i++)
                {
                    if (i % 10000 == 1)
                    {
                        Log.Info(".call Thread " + Thread.CurrentThread.ManagedThreadId + " at " + i);
                    }

                    int nominal = _sharedProducer.Next();
                    if (i % _ratioDoubleAdd == 1)
                    {
                        _updateDispatchView.Add(new[] { nominal, 1 });
                    }
                    _dispatchService.Dispatch();
                }
                Log.Info(".call Thread " + Thread.CurrentThread.ManagedThreadId + " done");
                return(true);
            }
Ejemplo n.º 6
0
    public async Task NewMember(Context ctx)
    {
        if (ctx.System == null)
        {
            throw Errors.NoSystemError;
        }
        var memberName = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a member name.");

        // Hard name length cap
        if (memberName.Length > Limits.MaxMemberNameLength)
        {
            throw Errors.StringTooLongError("Member name", memberName.Length, Limits.MaxMemberNameLength);
        }

        // Warn if there's already a member by this name
        var existingMember = await ctx.Repository.GetMemberByName(ctx.System.Id, memberName);

        if (existingMember != null)
        {
            var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?";
            if (!await ctx.PromptYesNo(msg, "Create"))
            {
                throw new PKError("Member creation cancelled.");
            }
        }

        await using var conn = await ctx.Database.Obtain();

        // Enforce per-system member limit
        var memberCount = await ctx.Repository.GetSystemMemberCount(ctx.System.Id);

        var memberLimit = ctx.Config.MemberLimitOverride ?? Limits.MaxMemberCount;

        if (memberCount >= memberLimit)
        {
            throw Errors.MemberLimitReachedError(memberLimit);
        }

        // Create the member
        var member = await ctx.Repository.CreateMember(ctx.System.Id, memberName, conn);

        memberCount++;

        JObject dispatchData = new JObject();

        dispatchData.Add("name", memberName);

        if (ctx.Config.MemberDefaultPrivate)
        {
            var patch = new MemberPatch().WithAllPrivacy(PrivacyLevel.Private);
            await ctx.Repository.UpdateMember(member.Id, patch, conn);

            dispatchData.Merge(patch.ToJson());
        }

        // Try to match an image attached to the message
        var       avatarArg       = ctx.Message.Attachments.FirstOrDefault();
        Exception imageMatchError = null;

        if (avatarArg != null)
        {
            try
            {
                await AvatarUtils.VerifyAvatarOrThrow(_client, avatarArg.Url);

                await ctx.Repository.UpdateMember(member.Id, new MemberPatch { AvatarUrl = avatarArg.Url }, conn);

                dispatchData.Add("avatar_url", avatarArg.Url);
            }
            catch (Exception e)
            {
                imageMatchError = e;
            }
        }

        _ = _dispatch.Dispatch(member.Id, new UpdateDispatchData
        {
            Event     = DispatchEvent.CREATE_MEMBER,
            EventData = dispatchData,
        });

        // Send confirmation and space hint
        await ctx.Reply(
            $"{Emojis.Success} Member \"{memberName}\" (`{member.Hid}`) registered! Check out the getting started page for how to get a member up and running: https://pluralkit.me/start#create-a-member");

        // todo: move this to ModelRepository
        if (await ctx.Database.Execute(conn => conn.QuerySingleAsync <bool>("select has_private_members(@System)",
                                                                            new { System = ctx.System.Id })) && !ctx.Config.MemberDefaultPrivate) //if has private members
        {
            await ctx.Reply(
                $"{Emojis.Warn} This member is currently **public**. To change this, use `pk;member {member.Hid} private`.");
        }
        if (avatarArg != null)
        {
            if (imageMatchError == null)
            {
                await ctx.Reply(
                    $"{Emojis.Success} Member avatar set to attached image.\n{Emojis.Warn} If you delete the message containing the attachment, the avatar will stop working.");
            }
            else
            {
                await ctx.Reply($"{Emojis.Error} Couldn't set avatar: {imageMatchError.Message}");
            }
        }
        if (memberName.Contains(" "))
        {
            await ctx.Reply(
                $"{Emojis.Note} Note that this member's name contains spaces. You will need to surround it with \"double quotes\" when using commands referring to it, or just use the member's 5-character ID (which is `{member.Hid}`).");
        }
        if (memberCount >= memberLimit)
        {
            await ctx.Reply(
                $"{Emojis.Warn} You have reached the per-system member limit ({memberLimit}). You will be unable to create additional members until existing members are deleted.");
        }
        else if (memberCount >= Limits.WarnThreshold(memberLimit))
        {
            await ctx.Reply(
                $"{Emojis.Warn} You are approaching the per-system member limit ({memberCount} / {memberLimit} members). Please review your member list for unused or duplicate members.");
        }
    }
Ejemplo n.º 7
0
        public void CalculationValuesMayNotChangeTest()
        {
            var databaseFactory = new NPocoDataBaseFactory();
            var database        = databaseFactory.GetDatabase();
            var databaseTimer   = databaseFactory.GetDatabase();

            var stateDepot            = new TestStateDepot(database);
            var calculationDepot      = new TestCalculationDepot(database);
            var calculationDepotTimer = new TestCalculationDepot(databaseTimer);
            var circleDepot           = new TestSealingSlabDepot(database);
            var estimationDepot       = new TestEstimationDepot(database);
            var calculationViewDepot  = new TestCalculationViewDepot(database);

            var calculation = new Calculation
            {
                Id                                 = 1,
                StateId                            = 1,
                PixelsPerMeter                     = 1,
                Height                             = 500,
                Width                              = 500,
                BorderX                            = 20,
                BorderY                            = 20,
                Depth                              = 100,
                DrillingPointDistanceX             = 50,
                DrillingPointDistanceY             = 50,
                SealingSlabDiameter                = 80,
                Iterations                         = 1,
                StandardDerivationOffset           = 0.8m,
                StandardDerivationDrillingPoint    = 0,
                StandardDerivationRadius           = 0,
                SealingSlabThickness               = 10,
                PermeabilityOfSoleAtUnsetArea      = 15,
                PermeabilityOfSoleWithoutUnsetArea = 12,
                WaterLevelDifference               = 11,
            };

            calculationDepot.Save(calculation);

            var calculationService = new Services.TestCalculationService(stateDepot, calculationDepot, circleDepot, calculationViewDepot, databaseFactory);
            var estimationService  = new Services.TestEstimationService(estimationDepot);

            var dispatchService = new DispatchService(stateDepot, calculationDepot, calculationDepotTimer, circleDepot, calculationService, estimationService, database);

            dispatchService.Dispatch(400);

            Assert.AreEqual(1, calculation.Id);
            Assert.AreEqual(1, calculation.PixelsPerMeter);
            Assert.AreEqual(500, calculation.Height);
            Assert.AreEqual(500, calculation.Width);
            Assert.AreEqual(20, calculation.BorderX);
            Assert.AreEqual(20, calculation.BorderY);
            Assert.AreEqual(100, calculation.Depth);
            Assert.AreEqual(50, calculation.DrillingPointDistanceX);
            Assert.AreEqual(50, calculation.DrillingPointDistanceY);
            Assert.AreEqual(80, calculation.SealingSlabDiameter);
            Assert.AreEqual(1, calculation.Iterations);
            Assert.AreEqual(0.8m, calculation.StandardDerivationOffset);
            Assert.AreEqual(0, calculation.StandardDerivationDrillingPoint);
            Assert.AreEqual(0, calculation.StandardDerivationRadius);
            Assert.AreEqual(10, calculation.SealingSlabThickness);
            Assert.AreEqual(15, calculation.PermeabilityOfSoleAtUnsetArea);
            Assert.AreEqual(12, calculation.PermeabilityOfSoleWithoutUnsetArea);
            Assert.AreEqual(11, calculation.WaterLevelDifference);
        }
Ejemplo n.º 8
0
        public void EstimationTest()
        {
            var databaseFactory = new NPocoDataBaseFactory();
            var database        = databaseFactory.GetDatabase();
            var databaseTimer   = databaseFactory.GetDatabase();

            var stateDepot            = new TestStateDepot(database);
            var calculationDepot      = new TestCalculationDepot(database);
            var calculationDepotTimer = new TestCalculationDepot(databaseTimer);
            var circleDepot           = new TestSealingSlabDepot(database);
            var estimationDepot       = new TestEstimationDepot(database);
            var calculationViewDepot  = new TestCalculationViewDepot(database);

            var calculation = new Calculation
            {
                Id                                 = 1,
                StateId                            = 1,
                PixelsPerMeter                     = 10,
                Height                             = 500,
                Width                              = 500,
                BorderX                            = 20,
                BorderY                            = 20,
                Depth                              = 100,
                DrillingPointDistanceX             = 50,
                DrillingPointDistanceY             = 50,
                SealingSlabDiameter                = 80,
                Iterations                         = 1,
                StandardDerivationOffset           = 0.8m,
                StandardDerivationDrillingPoint    = 0,
                StandardDerivationRadius           = 0,
                SealingSlabThickness               = 10,
                PermeabilityOfSoleAtUnsetArea      = 15,
                PermeabilityOfSoleWithoutUnsetArea = 12,
                WaterLevelDifference               = 11,
            };

            calculationDepot.Save(calculation);

            var calculationService = new Services.TestCalculationService(stateDepot, calculationDepot, circleDepot, calculationViewDepot, databaseFactory);
            var estimationService  = new Services.TestEstimationService(estimationDepot);

            var dispatchService = new DispatchService(stateDepot, calculationDepot, calculationDepotTimer, circleDepot, calculationService, estimationService, database);

            dispatchService.Dispatch(400);


            var calculation2 = new Calculation
            {
                Id                                 = 2,
                StateId                            = 1,
                PixelsPerMeter                     = 10,
                Height                             = 500,
                Width                              = 500,
                BorderX                            = 20,
                BorderY                            = 20,
                Depth                              = 100,
                DrillingPointDistanceX             = 50,
                DrillingPointDistanceY             = 50,
                SealingSlabDiameter                = 80,
                Iterations                         = 1,
                StandardDerivationOffset           = 0.8m,
                StandardDerivationDrillingPoint    = 0,
                StandardDerivationRadius           = 0,
                SealingSlabThickness               = 10,
                PermeabilityOfSoleAtUnsetArea      = 15,
                PermeabilityOfSoleWithoutUnsetArea = 12,
                WaterLevelDifference               = 11,
            };

            calculationDepot.Save(calculation2);

            var stopWatch = System.Diagnostics.Stopwatch.StartNew();

            dispatchService.Dispatch(400);

            stopWatch.Stop();

            var measuredTimeSpan = stopWatch.Elapsed;

            var estimatedTimeSpan = calculation2.EstimatedEndDate - calculation2.StartDate;
        }
Ejemplo n.º 9
0
    public async Task CreateGroup(Context ctx)
    {
        ctx.CheckSystem();

        // Check group name length
        var groupName = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a group name.");

        if (groupName.Length > Limits.MaxGroupNameLength)
        {
            throw new PKError($"Group name too long ({groupName.Length}/{Limits.MaxGroupNameLength} characters).");
        }

        // Check group cap
        var existingGroupCount = await ctx.Repository.GetSystemGroupCount(ctx.System.Id);

        var groupLimit = ctx.Config.GroupLimitOverride ?? Limits.MaxGroupCount;

        if (existingGroupCount >= groupLimit)
        {
            throw new PKError(
                      $"System has reached the maximum number of groups ({groupLimit}). Please delete unused groups first in order to create new ones.");
        }

        // Warn if there's already a group by this name
        var existingGroup = await ctx.Repository.GetGroupByName(ctx.System.Id, groupName);

        if (existingGroup != null)
        {
            var msg =
                $"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.Hid}`). Do you want to create another group with the same name?";
            if (!await ctx.PromptYesNo(msg, "Create"))
            {
                throw new PKError("Group creation cancelled.");
            }
        }

        // todo: this is supposed to be a transaction, but it's not used in any useful way
        // consider removing it?
        using var conn = await ctx.Database.Obtain();

        var newGroup = await ctx.Repository.CreateGroup(ctx.System.Id, groupName);

        var dispatchData = new JObject();

        dispatchData.Add("name", groupName);

        if (ctx.Config.GroupDefaultPrivate)
        {
            var patch = new GroupPatch().WithAllPrivacy(PrivacyLevel.Private);
            await ctx.Repository.UpdateGroup(newGroup.Id, patch, conn);

            dispatchData.Merge(patch.ToJson());
        }

        _ = _dispatch.Dispatch(newGroup.Id, new UpdateDispatchData
        {
            Event     = DispatchEvent.CREATE_GROUP,
            EventData = dispatchData
        });

        var reference = newGroup.Reference(ctx);

        var eb = new EmbedBuilder()
                 .Description(
            $"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:")
                 .Field(new Embed.Field("View the group card", $"> pk;group **{reference}**"))
                 .Field(new Embed.Field("Add members to the group",
                                        $"> pk;group **{reference}** add **MemberName**\n> pk;group **{reference}** add **Member1** **Member2** **Member3** (and so on...)"))
                 .Field(new Embed.Field("Set the description",
                                        $"> pk;group **{reference}** description **This is my new group, and here is the description!**"))
                 .Field(new Embed.Field("Set the group icon",
                                        $"> pk;group **{reference}** icon\n*(with an image attached)*"));
        await ctx.Reply($"{Emojis.Success} Group created!", eb.Build());

        if (existingGroupCount >= Limits.WarnThreshold(groupLimit))
        {
            await ctx.Reply(
                $"{Emojis.Warn} You are approaching the per-system group limit ({existingGroupCount} / {groupLimit} groups). Please review your group list for unused or duplicate groups.");
        }
    }