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); }
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); }
/// <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; } }
/// <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; }
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; }
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(); }
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); }
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); }
private Context GetContext(LockRecursionUser currentUser) { SecurityActivityQueue._setCurrentExecutionState(new CompletionState()); MemoryDataProvider.LastActivityId = 0; return(new Context(currentUser)); }
private void StartTheSystem() { SecurityActivityQueue._setCurrentExecutionState(new CompletionState()); MemoryDataProvider._lastActivityId = 0; Context.StartTheSystem(new MemoryDataProvider(DatabaseStorage.CreateEmpty()), new DefaultMessageProvider()); }
internal static Context GetEmptyContext(TestUser currentUser) { SecurityActivityQueue._setCurrentExecutionState(new CompletionState()); MemoryDataProvider.LastActivityId = 0; return(GetEmptyContext(currentUser, new MemoryDataProvider(DatabaseStorage.CreateEmpty()))); }