Esempio n. 1
0
        public void Test_CacheInvalidators()
        {
            CacheInvalidatorFactory factory;

            factory = new CacheInvalidatorFactory();

            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(2).TypeOf <SecurityQueryCacheInvalidator>());
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(2).TypeOf <SecurityCacheInvalidatorBase <UserEntityPermissionTuple, bool> >());
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <ReportToQueryCacheInvalidator>());
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <EntityMemberRequestCacheInvalidator>());
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <UserRoleRepositoryCacheInvalidator>());
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).Property("Name").Matches("PerTenantEntityTypeCacheInvalidator"));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <CachingQuerySqlBuilderInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <CachingQueryRunnerInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <CachingUserRuleSetProviderInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <MetadataCacheInvalidator>());
        }
        internal static void Test_Scenario(StructuredQuery structuredQuery, Action invalidationCallback, bool expectInvalidation)
        {
            CachingQuerySqlBuilder  cachingQuerySqlBuilder;
            Mock <IQuerySqlBuilder> mockQuerySqlBuilder;
            IQuerySqlBuilder        querySqlBuilder;
            QuerySettings           settings;
            QueryBuild           queryBuild;
            IUserRuleSetProvider userRuleSetProvider = MockUserRuleSetProvider( );

            settings   = new QuerySettings( );
            queryBuild = new QueryBuild( );

            var cacheInvalidators = new CacheInvalidatorFactory( ).CacheInvalidatorsList_TestOnly;

            mockQuerySqlBuilder = new Mock <IQuerySqlBuilder>(MockBehavior.Strict);
            mockQuerySqlBuilder.Setup(x => x.BuildSql(It.IsAny <StructuredQuery>( ), settings))
            .Returns <StructuredQuery, QuerySettings>((sq, qs) =>
            {
                QuerySqlBuilder.IdentifyCacheDependencies(sq, settings);
                return(queryBuild);
            })
            .Verifiable( );
            querySqlBuilder        = mockQuerySqlBuilder.Object;
            cachingQuerySqlBuilder = new CachingQuerySqlBuilder(querySqlBuilder, userRuleSetProvider);

            try
            {
                // Add current cache invalidator to global factory
                cacheInvalidators.Add(cachingQuerySqlBuilder.CacheInvalidator);

                using (var scope = Factory.Current.BeginLifetimeScope(cb =>
                {
                    cb.Register(c => cachingQuerySqlBuilder).As <ICacheService>( );
                }))
                    using (Factory.SetCurrentScope(scope))
                    {
                        // Run first time
                        cachingQuerySqlBuilder.BuildSql(structuredQuery.DeepCopy( ), settings);

                        // Perform potential invalidation task
                        using (new SecurityBypassContext( ))
                        {
                            invalidationCallback( );
                        }

                        // Run second time
                        cachingQuerySqlBuilder.BuildSql(structuredQuery.DeepCopy( ), settings);
                    }

                int times = expectInvalidation ? 2 : 1;
                mockQuerySqlBuilder.Verify(x => x.BuildSql(It.IsAny <StructuredQuery>( ), settings), Times.Exactly(times));
                mockQuerySqlBuilder.VerifyAll( );
            }
            finally
            {
                // Restore cache invalidators
                cacheInvalidators.Remove(cachingQuerySqlBuilder.CacheInvalidator);
            }
        }
Esempio n. 3
0
        public void Test_CacheInvalidators( )
        {
            CacheInvalidatorFactory factory = new CacheInvalidatorFactory( );

            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <CachingQuerySqlBuilderInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <CachingQueryRunnerInvalidator>( ));
        }
Esempio n. 4
0
        /// <summary>
        /// Updates the user accounts last logon time.
        /// </summary>
        /// <param name="entityId">The entity identifier.</param>
        /// <remarks>
        /// This intentionally bypasses the entity model and directly updates the database asynchronously.
        /// Any cached values are removed from the read-only cache upon completion.
        /// Cache invalidators are not invoked due to this call.
        /// </remarks>
        private static void UpdateUserAccountLastLogon(long entityId)
        {
            long     tenantId = RequestContext.TenantId;
            long     fieldId  = WellKnownAliases.CurrentTenant.LastLogon;
            DateTime now      = DateTime.UtcNow;

            ThreadPool.QueueUserWorkItem(state =>
            {
                using (DatabaseContextInfo.SetContextInfo($"Update last logon for user '{entityId}'"))
                    using (DatabaseContext ctx = DatabaseContext.GetContext( ))
                    {
                        using (var command = ctx.CreateCommand("spData_DateTimeMerge", CommandType.StoredProcedure))
                        {
                            ctx.AddParameter(command, "@entityId", DbType.Int64, entityId);
                            ctx.AddParameter(command, "@tenantId", DbType.Int64, tenantId);
                            ctx.AddParameter(command, "@fieldId", DbType.Int64, fieldId);
                            ctx.AddParameter(command, "@data", DbType.DateTime, now);
                            ctx.AddParameter(command, "@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(entityId));

                            command.ExecuteNonQuery( );

                            IEntityFieldValues values;

                            /////
                            // Remove the last logon time from the field cache (if it exists).
                            /////
                            if (EntityFieldCache.Instance.TryGetValue(entityId, out values))
                            {
                                object lastLogon;

                                if (values.TryGetValue(fieldId, out lastLogon))
                                {
                                    values [fieldId] = now;
                                }
                            }

                            /////
                            // Invalidate any items referencing the LastLogon item (NOT the UserAccount item)
                            ////
                            var cacheInvalidators = new CacheInvalidatorFactory( ).CacheInvalidators.ToList( );

                            List <IEntity> fieldTypes = new List <IEntity>
                            {
                                new IdEntity(fieldId)
                            };

                            foreach (ICacheInvalidator cacheInvalidator in cacheInvalidators)
                            {
                                cacheInvalidator.OnEntityChange(fieldTypes, InvalidationCause.Save, null);
                            }
                        }
                    }
            });
        }
        /// <summary>
        /// Invalidates the specified identifier.
        /// </summary>
        /// <param name="serializableEntityIds">The serializable entity ids.</param>
        public static void Invalidate(IList <SerializableEntityId> serializableEntityIds)
        {
            if (serializableEntityIds == null || serializableEntityIds.Count <= 0)
            {
                return;
            }

            var invalidators = new CacheInvalidatorFactory( ).CacheInvalidators.ToList();

            var list = serializableEntityIds.Select(serializableEntityId => IdEntity.FromId(serializableEntityId.Id, serializableEntityId.TypeIds)).Cast <IEntity>( ).ToList( );

            foreach (var invalidator in invalidators)
            {
                invalidator.OnEntityChange(list, InvalidationCause.Delete, null);
            }
        }
Esempio n. 6
0
        public void Test_CacheInvalidators( )
        {
            CacheInvalidatorFactory factory;

            factory = new CacheInvalidatorFactory( );

            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <CachingUserRuleSetProviderInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(2).TypeOf <SecurityQueryCacheInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(2).TypeOf <SecurityCacheInvalidatorBase <UserEntityPermissionTuple, bool> >( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <EntityMemberRequestCacheInvalidator>( ));
            Assert.That(factory.CacheInvalidators,
                        Has.Exactly(1).TypeOf <UserRoleRepositoryCacheInvalidator>( ));
        }