Exemple #1
0
        public void CommunicationMonitor_HearthBeat()
        {
            var testDp               = new TestDp(DatabaseStorage.CreateEmpty());
            var messageProvider      = new DefaultMessageProvider(new MessageSenderManager());
            var missingEntityHandler = new MissingEntityHandler();
            var messagingOptions     = Options.Create(new MessagingOptions()
            {
                CommunicationMonitorRunningPeriodInSeconds = 1
            });
            var securitySystem = new SecuritySystem(testDp, messageProvider, missingEntityHandler,
                                                    new SecurityConfiguration(), messagingOptions.Value);
            var dataHandler           = new DataHandler(testDp, messagingOptions);
            var communicationMonitor  = new CommunicationMonitor(dataHandler, messagingOptions);
            var activityHistory       = new SecurityActivityHistoryController();
            var securityActivityQueue = new SecurityActivityQueue(securitySystem, communicationMonitor, dataHandler, activityHistory);

            // ACTION
            var communicationMonitorAcc = new ObjectAccessor(communicationMonitor);

            communicationMonitorAcc.Invoke("Timer_Elapsed");

            // ASSERT
            Assert.IsTrue(testDp.IsCleanupSecurityActivitiesCalled);
            Assert.IsTrue(testDp.IsGetLastSecurityActivityIdCalled);
        }
        public void StartTest()
        {
            var dataProvider = GetDataProvider();

            dataProvider.DeleteEverything();
            SecurityActivityQueue._setCurrentExecutionState(new CompletionState());
            Context.StartTheSystem(dataProvider, new DefaultMessageProvider());
            __context = new Context(TestUser.User1);
        }
Exemple #3
0
        private Context GetContextAndStartTheSystem(LockRecursionUser currentUser)
        {
            SecurityActivityQueue._setCurrentExecutionState(new CompletionState());
            MemoryDataProvider.LastActivityId = 0;
            Context.StartTheSystem(new MemoryDataProvider(DatabaseStorage.CreateEmpty()), new DefaultMessageProvider(), null);
            var context = new Context(currentUser);

            CreatePlayground(context);
            return(context);
        }
Exemple #4
0
 /// <summary>
 /// Stops the security subsystem.
 /// </summary>
 public static void Shutdown()
 {
     if (_killed)
     {
         return;
     }
     _killed = true;
     _messageProvider.ShutDown();
     _messageProvider.MessageReceived -= MessageProvider_MessageReceived;
     CommunicationMonitor.Shutdown();
     SecurityActivityQueue.Shutdown();
 }
        /// <summary>
        /// Executes the activity by adding it to the activity queue.
        /// </summary>
        /// <param name="context">Current SecurityContext</param>
        /// <param name="waitForComplete">If the value is true (default),
        /// the current thread waits for the full execution on this computer.
        /// Otherwise the method returns immediatelly.</param>
        public void Execute(SecurityContext context, bool waitForComplete = true)
        {
            _context = context;
            SecurityActivityQueue.ExecuteActivity(this);

            if (waitForComplete)
            {
                WaitForComplete();
            }

            if (_executionException != null)
            {
                throw _executionException;
            }
        }
Exemple #6
0
        /// <summary>
        /// Starts the security subsystem using the passed configuration.
        /// Call this method only once in your application's startup sequence.
        /// The method prepares and memorizes the main components for
        /// creating SecurityContext instances in a fastest possible way.
        /// The main components are global objects:
        /// ISecurityDataProvider instance, IMessageProvider instance and SecurityCache instance.
        /// </summary>
        protected static void StartTheSystem(SecurityConfiguration configuration)
        {
            _generalContext = null;

            // The messageprovider provider must receive ongoing activities at this time.
            StartedAt = DateTime.UtcNow;

            int lastActivityIdFromDb;
            var uncompleted = DataHandler.LoadCompletionState(configuration.SecurityDataProvider, out lastActivityIdFromDb);

            _messageProvider = configuration.MessageProvider;
            _messageProvider.MessageReceived += MessageProvider_MessageReceived;

            Configuration.Identities.SystemUserId    = configuration.SystemUserId ?? -1;
            Configuration.Identities.VisitorUserId   = configuration.VisitorUserId ?? 6;
            Configuration.Identities.EveryoneGroupId = configuration.EveryoneGroupId ?? 8;
            Configuration.Identities.OwnerGroupId    = configuration.OwnerGroupId ?? 9;

            Configuration.Messaging.CommunicationMonitorRunningPeriodInSeconds = configuration.CommunicationMonitorRunningPeriodInSeconds ?? 30;
            Configuration.Messaging.SecuritActivityLifetimeInMinutes           = configuration.SecuritActivityLifetimeInMinutes ?? 42;
            Configuration.Messaging.SecuritActivityTimeoutInSeconds            = configuration.SecuritActivityTimeoutInSeconds ?? 120;

            _securityDataProviderPrototype = configuration.SecurityDataProvider;
            PermissionTypeBase.InferForcedRelations();

            using (var op = SnTrace.Security.StartOperation("Security initial loading."))
            {
                _cacheHolder  = SecurityCache.Initialize(configuration.SecurityDataProvider);
                op.Successful = true;
            }

            CommunicationMonitor.Initialize();

            _generalContext = new SecurityContext(SystemUser);
            SecurityActivityQueue.Startup(uncompleted, lastActivityIdFromDb);

            _killed = false;
        }
Exemple #7
0
        public void Start()
        {
            GeneralSecurityContext = null;

            // The message provider must receive ongoing activities at this time.
            StartedAt = DateTime.UtcNow;

            var uncompleted = DataHandler.LoadCompletionState(out var lastActivityIdFromDb);

            PermissionTypeBase.InferForcedRelations();

            using (var op = SnTrace.Security.StartOperation("Security initial loading."))
            {
                var cache = new SecurityCache(DataHandler);
                cache.Initialize();
                Cache         = cache;
                op.Successful = true;
            }

            EntityManager             = new SecurityEntityManager(Cache, DataHandler, MissingEntityHandler);
            Cache.EntityManager       = EntityManager; // Property injection
            DataHandler.EntityManager = EntityManager; // Property injection

            PermissionQuery        = new PermissionQuery(EntityManager, Cache);
            CommunicationMonitor   = new CommunicationMonitor(DataHandler, Options.Create(MessagingOptions));
            GeneralSecurityContext = new SecurityContext(SystemUser, this);

            SecurityActivityQueue = new SecurityActivityQueue(this, CommunicationMonitor, DataHandler, ActivityHistory);
            SecurityActivityQueue.Startup(uncompleted, lastActivityIdFromDb);
            ActivityHistory.SecurityActivityQueue = SecurityActivityQueue; // Property injection

            MessageProvider.MessageReceived += MessageProvider_MessageReceived;
            MessageProvider.Initialize();
            MessageProvider.Start(StartedAt);

            _killed = false;
        }
Exemple #8
0
        public void EF_LoadActivities_SmartGapResolution()
        {
            int             lastActivityIdFromDb;
            CompletionState uncompleted;

            var sb = new StringBuilder();

            context = Start();
            CommunicationMonitor.Stop();
            var sctx         = context.Security;
            var user1Id      = TestUser.User1.Id;
            var rootEntityId = Id("E01");

            // create some activities with gap
            sctx.CreateSecurityEntity(rootEntityId, default(int), user1Id);
            for (int entityId = rootEntityId + 1; entityId < rootEntityId + 11; entityId++)
            {
                sctx.CreateSecurityEntity(entityId, rootEntityId, user1Id);
                Db().ExecuteTestScript(@"
                    -- 2 gap
                    INSERT INTO EFMessages ([SavedBy], [SavedAt], [ExecutionState]) VALUES ('asdf1', GETDATE(),'Wait')
                    INSERT INTO EFMessages ([SavedBy], [SavedAt], [ExecutionState]) VALUES ('qwer1', GETDATE(),'Wait')
                    DELETE EFMessages WHERE Id in (select top 2 Id from [EFMessages] order by Id desc)");
            }

            // these are be unprocessed
            Db().ExecuteTestScript("UPDATE EFMessages set ExecutionState = 'Wait', LockedBy = null, LockedAt = null");

            sb.Clear();
            uncompleted = DataHandler.LoadCompletionState(SecurityContext.General.DataProvider, out lastActivityIdFromDb);
            SecurityActivityQueue.Startup(uncompleted, lastActivityIdFromDb);

            var cs1 = SecurityActivityQueue.GetCurrentCompletionState();

            // expectation: there is no any gap.
            Assert.AreEqual(0, cs1.Gaps.Length);

            // create a gap
            Db().ExecuteTestScript(@"
                    -- 2 gap
                    INSERT INTO EFMessages ([SavedBy], [SavedAt], [ExecutionState]) VALUES ('asdf1', GETDATE(),'Wait')
                    INSERT INTO EFMessages ([SavedBy], [SavedAt], [ExecutionState]) VALUES ('qwer1', GETDATE(),'Wait')
                    DELETE EFMessages WHERE Id in (select top 2 Id from [EFMessages] order by Id desc)
                    -- copy last
                    INSERT INTO EFMessages([SavedBy],[SavedAt],[ExecutionState],[LockedBy],[LockedAt],[Body])
                         SELECT TOP 1 [SavedBy],GETDATE(),[ExecutionState],[LockedBy],[LockedAt],[Body] FROM EFMessages ORDER BY Id DESC
                    -- 2 gap
                    INSERT INTO EFMessages ([SavedBy], [SavedAt], [ExecutionState]) VALUES ('asdf2', GETDATE(),'Wait')
                    INSERT INTO EFMessages ([SavedBy], [SavedAt], [ExecutionState]) VALUES ('qwer2', GETDATE(),'Wait')
                    DELETE EFMessages WHERE Id in (select top 2 Id from [EFMessages] order by Id desc)");

            // last activity
            sctx.CreateSecurityEntity(101, rootEntityId, user1Id);

            var cs2 = SecurityActivityQueue.GetCurrentCompletionState();

            Assert.AreEqual(4, cs2.Gaps.Length);
            Assert.AreEqual(cs1.LastActivityId + 6, cs2.LastActivityId);

            SecurityActivityQueue.HealthCheck();

            var cs3 = SecurityActivityQueue.GetCurrentCompletionState();

            Assert.AreEqual(0, cs3.Gaps.Length);
            Assert.AreEqual(cs2.LastActivityId, cs3.LastActivityId);

            CommunicationMonitor.Start();
        }
Exemple #9
0
        public void EF_LoadActivities_RightDependencies()
        {
            context = Start();
            var sctx    = context.Security;
            var user1Id = TestUser.User1.Id;

            // register some dependent activities
            // create a tree
            string waitingActivitiesDump = null;

            try
            {
                SecurityActivityQueue.__disableExecution();

                new CreateSecurityEntityActivity(Id("E01"), default(int), user1Id).Execute(sctx, false);
                {
                    new CreateSecurityEntityActivity(Id("E02"), Id("E01"), user1Id).Execute(sctx, false);
                    {
                        new CreateSecurityEntityActivity(Id("E03"), Id("E02"), user1Id).Execute(sctx, false);
                        {
                            new CreateSecurityEntityActivity(Id("E04"), Id("E03"), user1Id).Execute(sctx, false);
                            new CreateSecurityEntityActivity(Id("E05"), Id("E03"), user1Id).Execute(sctx, false);
                        }
                    }
                }
                // set acl
                new SetAclActivity(null, new List <int>(), new List <int> {
                    Id("E111"), Id("E03")
                }).Execute(sctx, false);
                new SetAclActivity(null, new List <int>(), new List <int> {
                    Id("E112"), Id("E113")
                }).Execute(sctx, false);
                new SetAclActivity(null, new List <int>(), new List <int> {
                    Id("E113"), Id("E114")
                }).Execute(sctx, false);
                // delete a chain
                new DeleteSecurityEntityActivity(Id("E04")).Execute(sctx, false);
                new DeleteSecurityEntityActivity(Id("E03")).Execute(sctx, false);
                new DeleteSecurityEntityActivity(Id("E02")).Execute(sctx, false);

                // dump
                var waitingActivities = SecurityActivityQueue.__getWaitingSet();
                var x = waitingActivities.Select(a => "{"
                                                 + String.Format("id:{0}, w:[{1}], wm:[{2}]"
                                                                 , a.Id
                                                                 , String.Join(",", a.WaitingFor.Select(b => b.Id))
                                                                 , String.Join(",", a.WaitingForMe.Select(c => c.Id)))
                                                 + "}");
                waitingActivitiesDump = String.Join(",", x);
            }
            finally
            {
                SecurityActivityQueue.__enableExecution();
            }

            var lastId  = Db().ExecuteTestScript <int>("select top 1 Id from [EFMessages] order by Id desc").First();
            var create1 = lastId - 10;
            var create2 = lastId - 9;
            var create3 = lastId - 8;
            var create4 = lastId - 7;
            var create5 = lastId - 6;
            var setAcl1 = lastId - 5;
            var setAcl2 = lastId - 4;
            var setAcl3 = lastId - 3;
            var delete1 = lastId - 2;
            var delete2 = lastId - 1;
            var delete3 = lastId;

            var expectedWaitingActivitiesDump =
                "{id:" + create1 + ", w:[], wm:[" + create2 + "]},"
                + "{id:" + create2 + ", w:[" + create1 + "], wm:[" + create3 + "," + delete3 + "]},"
                + "{id:" + create3 + ", w:[" + create2 + "], wm:[" + create4 + "," + create5 + "," + setAcl1 + "," + delete2 + "]},"
                + "{id:" + create4 + ", w:[" + create3 + "], wm:[" + delete1 + "]},"
                + "{id:" + create5 + ", w:[" + create3 + "], wm:[]},"

                + "{id:" + setAcl1 + ", w:[" + create3 + "], wm:[]},"
                + "{id:" + setAcl2 + ", w:[], wm:[" + setAcl3 + "]},"
                + "{id:" + setAcl3 + ", w:[" + setAcl2 + "], wm:[]},"

                + "{id:" + delete1 + ", w:[" + create4 + "], wm:[]},"
                + "{id:" + delete2 + ", w:[" + create3 + "], wm:[]},"
                + "{id:" + delete3 + ", w:[" + create2 + "], wm:[]}";

            Assert.AreEqual(expectedWaitingActivitiesDump, waitingActivitiesDump);
        }
Exemple #10
0
        public void EF_LoadActivities_AtStart_ActivityQueueLevel()
        {
            int             lastActivityIdFromDb;
            CompletionState uncompleted;

            context = Start();
            var sctx         = context.Security;
            var user1Id      = TestUser.User1.Id;
            var rootEntityId = Id("E01");

            // create 30 activities
            sctx.CreateSecurityEntity(rootEntityId, default(int), user1Id);
            for (int entityId = rootEntityId + 1; entityId < rootEntityId + 31; entityId++)
            {
                sctx.CreateSecurityEntity(entityId, rootEntityId, user1Id);
            }

            var lastId = Db().ExecuteTestScript <int>("select top 1 Id from [EFMessages] order by Id desc").First();


            // test0: initial state
            var expectedCs = new CompletionState {
                LastActivityId = lastId
            };

            uncompleted = DataHandler.LoadCompletionState(SecurityContext.General.DataProvider, out lastActivityIdFromDb);
            SecurityActivityQueue.Startup(uncompleted, lastActivityIdFromDb);
            var cs0 = SecurityActivityQueue.GetCurrentState().Termination;

            Assert.AreEqual(expectedCs.ToString(), cs0.ToString());


            // test1: create some unprocessed activities: 4 continuous activity (except last) + 2 gaps before
            //        last-2 and last-6 "Wait", the others "Executing" by another appdomain.
            Db().ExecuteTestScript(@"declare @last int
                select top 1 @last = Id from [EFMessages] order by Id desc
                UPDATE EFMessages set ExecutionState = 'Executing', LockedBy = 'AnotherComputer'
                    where Id in (@last-1, @last-3, @last-4, @last-9)
                UPDATE EFMessages set ExecutionState = 'Wait', LockedBy = null, LockedAt = null
                    where Id in (@last-2, @last-6)
                ");

            var expectedIsFromDb1 = String.Join(", ", new[] { lastId - 9, lastId - 4, lastId - 3, lastId - 1, lastId });

            uncompleted = DataHandler.LoadCompletionState(SecurityContext.General.DataProvider, out lastActivityIdFromDb);
            SecurityActivityQueue.Startup(uncompleted, lastActivityIdFromDb);
            var cs1        = SecurityActivityQueue.GetCurrentState().Termination;
            var idsFromDb1 = String.Join(", ", Db().GetUnprocessedActivityIds());

            Assert.AreEqual(expectedCs.ToString(), cs1.ToString());
            Assert.AreEqual(expectedIsFromDb1, idsFromDb1);

            // test2: create unprocessed activities: last 5 continuous activity + 2 gaps before
            //        last-2 and last-6 "Wait", the others "Executing" by another appdomain.
            Db().ExecuteTestScript(@"declare @last int
                select top 1 @last = Id from [EFMessages] order by Id desc
                UPDATE EFMessages set ExecutionState = 'Executing', LockedBy = 'AnotherComputer'
                    where Id in (@last, @last-1, @last-3, @last-4, @last-9)
                UPDATE EFMessages set ExecutionState = 'Wait', LockedBy = null, LockedAt = null
                    where Id in (@last-2, @last-6)
                ");

            var expectedIsFromDb2 = String.Join(", ", new[] { lastId - 9, lastId - 4, lastId - 3, lastId - 1, lastId, lastId });

            uncompleted = DataHandler.LoadCompletionState(SecurityContext.General.DataProvider, out lastActivityIdFromDb);
            SecurityActivityQueue.Startup(uncompleted, lastActivityIdFromDb);
            var cs2        = SecurityActivityQueue.GetCurrentState().Termination;
            var idsFromDb2 = String.Join(", ", Db().GetUnprocessedActivityIds());

            Assert.AreEqual(expectedCs.ToString(), cs2.ToString());
            Assert.AreEqual(expectedIsFromDb2, idsFromDb2);
        }
Exemple #11
0
 private Context GetContext(LockRecursionUser currentUser)
 {
     SecurityActivityQueue._setCurrentExecutionState(new CompletionState());
     MemoryDataProvider.LastActivityId = 0;
     return(new Context(currentUser));
 }
Exemple #12
0
 private void StartTheSystem()
 {
     SecurityActivityQueue._setCurrentExecutionState(new CompletionState());
     MemoryDataProvider._lastActivityId = 0;
     Context.StartTheSystem(new MemoryDataProvider(DatabaseStorage.CreateEmpty()), new DefaultMessageProvider());
 }
Exemple #13
0
 internal static Context GetEmptyContext(TestUser currentUser)
 {
     SecurityActivityQueue._setCurrentExecutionState(new CompletionState());
     MemoryDataProvider.LastActivityId = 0;
     return(GetEmptyContext(currentUser, new MemoryDataProvider(DatabaseStorage.CreateEmpty())));
 }