Exemple #1
0
        static void Main(string[] args)
        {
            //EntityFrameworkCache.Initialize(new ServiceStackRedisCache(new ServiceStackRedisCacheOptions
            //{
            //    Host = "172.16.6.40",
            //    Password = "******"
            //}));
            //EntityFrameworkCache.Initialize(new StackExchangeRedisCache(new StackExchangeRedisCacheOptions()
            //{
            //    Configuration="172.16.6.40:6379,serviceName=Sky-Redis01-Cluster01,password=SCFLgskjhb9wqdi0weugbfjpsodkf8"
            //}));
            EntityFrameworkCache.Initialize(new InMemoryCache());

            litlyEntities db   = new litlyEntities();
            var           urls = db.Urls.Where(u => u.CompanyId == 1).Select(u => new { u.ShortUrl, u.LongUrl }).ToList();

            db.Urls.Add(new Url {
                ShortUrl = "test", LongUrl = "test.com", CompanyId = 1, UserId = "54731be8-2b39-4bf7-be15-19ecabbb821e", RegDate = DateTime.Now
            });
            db.SaveChanges();
            var url = db.Urls.First(u => u.ShortUrl == "test");

            url.Hits = 10;
            db.SaveChanges();

            db.Urls.Remove(url);
            db.SaveChanges();

            urls = db.Urls.Where(u => u.CompanyId == 1).Select(u => new { u.ShortUrl, u.LongUrl }).ToList();
        }
		public void InMemoryCacheInitialStatisticsAreAllZero()
		{
			var cacheWithStatistics = new EntityFrameworkCache();
			Assert.AreEqual(0, cacheWithStatistics.Hits);
			Assert.AreEqual(0, cacheWithStatistics.ItemAdds);
			Assert.AreEqual(0, cacheWithStatistics.ItemInvalidations);
			Assert.AreEqual(0, cacheWithStatistics.Misses);
		}
		public void InMemoryCacheCacheMissTests()
		{
			var cacheWithStatistics = new EntityFrameworkCache();
			object value;

			Assert.IsFalse(cacheWithStatistics.GetItem("NoSuchItem", out value));
			Assert.IsNull(value);
			Assert.AreEqual(0, cacheWithStatistics.Hits);
			Assert.AreEqual(1, cacheWithStatistics.Misses);
			Assert.AreEqual(0, cacheWithStatistics.ItemInvalidations);
			Assert.AreEqual(0, cacheWithStatistics.ItemAdds);
		}
		public void InMemoryCacheCacheHitTests()
		{
			var cacheWithStatistics = new EntityFrameworkCache();
			object value;

			cacheWithStatistics.PutItem("Item1", "someValue", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			Assert.IsTrue(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual(value, "someValue");
			Assert.AreEqual(1, cacheWithStatistics.Hits);
			Assert.AreEqual(0, cacheWithStatistics.Misses);
			Assert.AreEqual(0, cacheWithStatistics.ItemInvalidations);
			Assert.AreEqual(1, cacheWithStatistics.ItemAdds);
		}
Exemple #5
0
        private static void Main()
        {
            EntityFrameworkCache.Initialize(new InMemoryCache());

            var language = ConfigurationManager.AppSettings["language"];

            Thread.CurrentThread.CurrentCulture   = new System.Globalization.CultureInfo(language);
            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (Properties.Settings.Default.firstTime)
            {
                Application.Run(new Ar_Eng());
            }
            else
            {
                Application.Run(new Loginn());
            }
        }
		public void InMemoryCacheCacheExpirationTest1()
		{
			var cacheWithStatistics = new EntityFrameworkCache();

			object value;

			// current time is 10:00
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 10, 0, 0);

			// set expiration time to 11:00
			cacheWithStatistics.PutItem("Item1", "someValue", new string[0], TimeSpan.Zero, new DateTime(2009, 1, 1, 11, 0, 0));

			// make sure the item is still there
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 10, 59, 59);
			Assert.IsTrue(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual(value, "someValue");
			Assert.AreEqual(0, cacheWithStatistics.ItemInvalidations);

			// make sure the item gets evicted at 11:00
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 11, 00, 00);
			Assert.IsFalse(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual(1, cacheWithStatistics.ItemInvalidations);
		}
Exemple #7
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddHttpsRedirection(options => { options.HttpsPort = 443; });

            services.AddDistributedMemoryCache();

            // If environment is localhost, then enable CORS policy, otherwise no cross-origin access
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy", builder => builder
                                  .AllowAnyOrigin()
                                  .AllowAnyHeader()
                                  .AllowAnyMethod());
            });

            // Add framework services
            // Add functionality to inject IOptions<T>
            services.AddOptions();
            services.Configure <JwtSettings>(_configuration.GetSection("JwtSettings"));

            // Add our Config object so it can be injected
            //services.Configure<SecureHeadersMiddlewareConfiguration>(
            //    _configuration.GetSection("SecureHeadersMiddlewareConfiguration"));

            services.AddLogging();

            services.AddRouting(options => options.LowercaseUrls = true);

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout         = TimeSpan.FromMinutes(50);
                options.Cookie.HttpOnly     = true;
                options.Cookie.Name         = ApiConstants.ApplicationName;
                options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
            });

            services.AddDbContext <EntityDbContext>(builder =>
            {
                if (_env.IsDevelopment())
                {
                    builder.UseSqlite(_configuration.GetValue <string>("ConnectionStrings:Sqlite"));
                }
                else
                {
                    builder.UseNpgsql(
                        ConnectionStringUrlToResource(_configuration.GetRequiredValue <string>("DATABASE_URL")));
                }
            });

            services.AddIdentity <User, UserRole>(opt => opt.User.RequireUniqueEmail = true)
            .AddRoles <UserRole>()
            .AddEntityFrameworkStores <EntityDbContext>()
            .AddDefaultTokenProviders();

            if (_env.IsDevelopment())
            {
                EntityFrameworkCache.Initialize(new InMemoryCache());
            }
            else
            {
                var redisCacheConfig = ConfigurationOptions.Parse(_configuration.GetValue <string>("REDISTOGO_URL"));

                redisCacheConfig.AbortOnConnectFail = false;    // Needed otherwise redis client will fail

                EntityFrameworkCache.Initialize(new RedisCache(redisCacheConfig));
            }

            var jwtSetting = _configuration
                             .GetSection("JwtSettings")
                             .Get <JwtSettings>();

            services.AddAuthentication(options => {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(config =>
            {
                config.RequireHttpsMetadata = false;
                config.SaveToken            = true;

                config.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer      = jwtSetting.Issuer,
                    ValidAudience    = jwtSetting.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.Key))
                };
            });

            services.AddControllers(opt =>
            {
                opt.EnableEndpointRouting = false;

                opt.ModelValidatorProviders.Clear();

                // Not need to have https
                opt.RequireHttpsPermanent = false;

                // Allow anonymous for localhost
                if (_env.IsDevelopment())
                {
                    opt.Filters.Add <AllowAnonymousFilter>();
                }

                opt.Filters.Add <CustomExceptionFilterAttribute>();
                opt.Filters.Add <FileUploadActionFilterAttribute>();
            })
            .AddNewtonsoftJson(option => option.SerializerSettings.Converters.Add(new StringEnumConverter()));

            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                                           ForwardedHeaders.XForwardedProto;
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
            });

            services.AddSwaggerGen(config =>
            {
                config.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title       = "Contractor-Finder-Api",
                    Description = "Contractor finder service API layer, .NET Core + PostgresSQL"
                });

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

                if (File.Exists(xmlPath))
                {
                    config.IncludeXmlComments(xmlPath);
                }

                config.OperationFilter <FileUploadOperation>();

                config.AddSecurityDefinition("Bearer", // Name the security scheme
                                             new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Type        = SecuritySchemeType.Http, // We set the scheme type to http since we're using bearer authentication
                    Scheme      = "bearer"                 // The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer".
                });
            });

            var container = new Container(config =>
            {
                if (_env.IsDevelopment())
                {
                    config.For <IS3Service>().Use <InMemoryS3>().Singleton();
                }
                else
                {
                    var(accessKeyId, secretAccessKey, url) = (
                        _configuration.GetRequiredValue <string>("CLOUDCUBE_ACCESS_KEY_ID"),
                        _configuration.GetRequiredValue <string>("CLOUDCUBE_SECRET_ACCESS_KEY"),
                        _configuration.GetRequiredValue <string>("CLOUDCUBE_URL")
                        );

                    var prefix = new Uri(url).Segments.Skip(1).FirstOrDefault() ?? throw new Exception("S3 url is malformed");
                    const string bucketName = "cloud-cube";

                    // Generally bad practice
                    var credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);

                    // Create S3 client
                    config.For <IAmazonS3>().Use(() => new AmazonS3Client(credentials, RegionEndpoint.USEast1));
                    config.For <S3ServiceConfig>().Use(new S3ServiceConfig(bucketName, prefix));
                }

                // Register stuff in container, using the StructureMap APIs...
                config.Scan(_ =>
                {
                    _.AssemblyContainingType(typeof(Startup));
                    _.Assembly("Logic");
                    _.Assembly("Dal");
                    _.WithDefaultConventions();
                });

                // Populate the container using the service collection
                config.Populate(services);

                config.For <IMapper>().Use(ctx => ResolveMapper(ctx, Assembly.Load("Logic"))).Singleton();
            });

            // container.AssertConfigurationIsValid();

            return(container.GetInstance <IServiceProvider>());
        }
Exemple #8
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            var postgresConnectionString =
                ConnectionStringUrlToResource(_configuration.GetValue <string>("DATABASE_URL")
                                              ?? throw new Exception("DATABASE_URL is null"));

            services.AddOptions();

            services.AddLogging();

            services.AddRouting(options => { options.LowercaseUrls = true; });

            if (_env.IsDevelopment())
            {
                services.AddDistributedMemoryCache();
            }
            else
            {
                services.AddStackExchangeRedisCache(x =>
                                                    x.Configuration = _configuration.GetValue <string>("REDISTOGO_URL"));
            }

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout         = TimeSpan.FromMinutes(50);
                options.Cookie.HttpOnly     = true;
                options.Cookie.Name         = ApiConstants.AuthenticationSessionCookieName;
                options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "oriental-rug-gallery-API", Version = "v1"
                });
            });

            services.AddMvc(x =>
            {
                x.ModelValidatorProviders.Clear();

                // Not need to have https
                x.RequireHttpsPermanent = false;

                // Allow anonymous for localhost
                if (_env.IsDevelopment())
                {
                    x.Filters.Add <AllowAnonymousFilter>();
                }
            }).AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                x.SerializerSettings.Converters.Add(new StringEnumConverter());
            }).AddRazorPagesOptions(x => { x.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()); });

            services.AddWebMarkupMin(opt =>
            {
                opt.AllowMinificationInDevelopmentEnvironment = true;
                opt.AllowCompressionInDevelopmentEnvironment  = true;
            })
            .AddHtmlMinification()
            .AddHttpCompression();

            services.AddDbContext <EntityDbContext>(opt => opt.UseNpgsql(postgresConnectionString));

            services.AddIdentity <User, IdentityRole <int> >(x => { x.User.RequireUniqueEmail = true; })
            .AddEntityFrameworkStores <EntityDbContext>()
            .AddRoles <IdentityRole <int> >()
            .AddDefaultTokenProviders();

            // L2 EF cache
            if (_env.IsDevelopment())
            {
                EntityFrameworkCache.Initialize(new InMemoryCache());
            }
            else
            {
                var redisConfigurationOptions =
                    ConfigurationOptions.Parse(_configuration.GetValue <string>("REDISTOGO_URL"));

                // Important
                redisConfigurationOptions.AbortOnConnectFail = false;

                EntityFrameworkCache.Initialize(new RedisCache(redisConfigurationOptions));
            }

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(x =>
            {
                x.Cookie.MaxAge = TimeSpan.FromMinutes(60);
            });

            // Re-Captcha config
            services.Configure <RecaptchaSettings>(_configuration.GetSection("RecaptchaSettings"));
            services.AddTransient <IRecaptchaService, RecaptchaService>();

            _container = new Container(config =>
            {
                config.For <DocumentStore>().Use(DocumentStore.For(y =>
                {
                    // Important as PLV8 is disabled on Heroku
                    y.PLV8Enabled = false;

                    y.Connection(postgresConnectionString);

                    y.AutoCreateSchemaObjects = AutoCreate.CreateOrUpdate;
                }));

                var(accessKeyId, secretAccessKey, url) = (
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_ACCESS_KEY_ID"),
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_SECRET_ACCESS_KEY"),
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_URL")
                    );

                var prefix = new Uri(url).Segments.Skip(1).FirstOrDefault() ?? throw new Exception("S3 url is malformed");
                const string bucketName = "cloud-cube";

                // Generally bad practice
                var credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);

                // Create S3 client
                config.For <IAmazonS3>().Use(() => new AmazonS3Client(credentials, RegionEndpoint.USEast1));
                config.For <S3ServiceConfig>().Use(new S3ServiceConfig(bucketName, prefix));

                // Register stuff in container, using the StructureMap APIs...
                config.Scan(_ =>
                {
                    _.AssemblyContainingType(typeof(Startup));
                    _.Assembly("Api");
                    _.Assembly("Logic");
                    _.Assembly("Dal");
                    _.WithDefaultConventions();
                });

                // Populate the container using the service collection
                config.Populate(services);
            });

            _container.AssertConfigurationIsValid();

            return(_container.GetInstance <IServiceProvider>());
        }
		public void InMemoryCacheCacheExpirationTest2()
		{
			var cacheWithStatistics = new EntityFrameworkCache();

			object value;

			// current time is 10:00
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 10, 0, 0);

			// set expiration time to 1 hour from the last access
			cacheWithStatistics.PutItem("Item1", "someValue", new string[0], TimeSpan.FromHours(1), DateTime.MaxValue);

			// make sure the item is still there
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 10, 59, 59);
			Assert.IsTrue(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual(value, "someValue");
			Assert.AreEqual(0, cacheWithStatistics.ItemInvalidations);

			// make sure the item does not get evicted at 11:00 because we have touched it a second ago
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 11, 00, 00);
			Assert.IsTrue(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual(value, "someValue");
			Assert.AreEqual(0, cacheWithStatistics.ItemInvalidations);

			Assert.IsNotNull(cacheWithStatistics.LruChainHead);

			// make sure the item does not get evicted at 12:00 because we have touched it an hour ago
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 12, 00, 00);
			Assert.IsFalse(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual(1, cacheWithStatistics.ItemInvalidations);

			Assert.IsNull(cacheWithStatistics.LruChainHead);
			Assert.IsNull(cacheWithStatistics.LruChainTail);
		}
		private static string GetItemKeysInLruOrder(EntityFrameworkCache imc)
		{
			var sb = new StringBuilder();
			var separator = string.Empty;
			var visisted = new HashSet<string>();

			CacheEntry lastEntry = null;

			for (var ce = imc.LruChainHead; ce != null; ce = ce.NextEntry)
			{
				if (visisted.Contains(ce.Key))
				{
					throw new InvalidOperationException("Cycle in the LRU chain on: " + ce);
				}

				if (!Equals(ce.PreviousEntry, lastEntry))
				{
					var message = "Invalid previous pointer on LRU chain: " + ce + " Is: " + ce.PreviousEntry + " expected: " + lastEntry;
					throw new InvalidOperationException(message);
				}

				if (lastEntry != null && ce.LastAccessTime.Subtract(lastEntry.LastAccessTime).TotalMilliseconds > 500)
				{
					var message =
						"Invalid LastAccess time. Current: " + ce.LastAccessTime.Ticks + " previous: " + lastEntry.LastAccessTime.Ticks;
					throw new InvalidOperationException(message);
				}

				sb.Append(separator);
				sb.Append(ce.Key);
				separator = "|";
				visisted.Add(ce.Key);
				lastEntry = ce;
			}

			Assert.AreSame(lastEntry, imc.LruChainTail);

			return sb.ToString();
		}
		public void MicroStressTest()
		{
			// Run a bunch of concurrent reads and writes, make sure we get no exceptions
			var imc = new EntityFrameworkCache(100);
			const int NumberOfRequestBatches = 50; // will be multiplied by 5 (3 readers + 1 writer + 1 invalidator)
			const int NumberOfIterationsPerThread = 100;

			var startEvent = new ManualResetEvent(false);

			Action writer = () =>
			{
				startEvent.WaitOne();
				var random = new Random();

				for (var i = 0; i < NumberOfIterationsPerThread; ++i)
				{
					var randomKey = Guid.NewGuid().ToString("N").Substring(0, 4);
					var randomValue = randomKey + "_V";
					var dependentSets = new List<string>();
					var numberOfDependencies = random.Next(5);

					for (var j = 0; j < numberOfDependencies; ++j)
					{
						var randomSetName = new string((char)('A' + random.Next(26)), 1);
						dependentSets.Add(randomSetName);
					}

					imc.PutItem(randomKey, randomValue, dependentSets, TimeSpan.Zero, DateTime.MaxValue);
				}
			};

			Action invalidator = () =>
			{
				startEvent.WaitOne();
				var random = new Random();

				for (var i = 0; i < NumberOfIterationsPerThread; ++i)
				{
					var dependentSets = new List<string>();
					var numberOfDependencies = random.Next(5);
					for (var j = 0; j < numberOfDependencies; ++j)
					{
						var randomSetName = new string((char)('A' + random.Next(26)), 1);
						dependentSets.Add(randomSetName);
					}

					imc.InvalidateSets(dependentSets);
				}
			};

			Action reader = () =>
			{
				startEvent.WaitOne();

				for (var i = 0; i < NumberOfIterationsPerThread; ++i)
				{
					var randomKey = Guid.NewGuid().ToString("N").Substring(0, 4);
					object value;

					if (imc.GetItem(randomKey, out value))
					{
						Assert.AreEqual(randomKey + "_V", value);
					}
				}
			};

			var threads = new List<Thread>();

			for (var i = 0; i < NumberOfRequestBatches; ++i)
			{
				threads.Add(new Thread(() => writer()));
				threads.Add(new Thread(() => invalidator()));
				threads.Add(new Thread(() => reader()));
				threads.Add(new Thread(() => reader()));
				threads.Add(new Thread(() => reader()));
			}

			foreach (var t in threads)
			{
				t.Start();
			}

			startEvent.Set();

			foreach (var t in threads)
			{
				t.Join();
			}
		}
		public void DependenciesTest4()
		{
			var imc = new EntityFrameworkCache();

			imc.PutItem("A", "A1", new[] { "set1" }, TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("B", "B1", new[] { "set1", "set2" }, TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("C", "C1", new[] { "set2", "set3" }, TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("D", "D1", new[] { "set3", "set1" }, TimeSpan.Zero, DateTime.MaxValue);

			Assert.AreEqual("D|C|B|A", GetItemKeysInLruOrder(imc));
			imc.PutItem("B", "C1", new[] { "set3" }, TimeSpan.Zero, DateTime.MaxValue);
			Assert.AreEqual("B|D|C|A", GetItemKeysInLruOrder(imc));

			imc.InvalidateSets(new[] { "set3" });
			Assert.AreEqual("A", GetItemKeysInLruOrder(imc));
		}
		public void LruWithLimitTest2()
		{
			var imc = new EntityFrameworkCache(3);

			Assert.AreEqual(3, imc.MaxItems);

			imc.PutItem("A", "A1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("B", "B1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("C", "C1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("D", "D1", new string[0], TimeSpan.Zero, DateTime.MaxValue);

			Assert.AreEqual("D|C|B", GetItemKeysInLruOrder(imc));
			imc.PutItem("E", "E1", new string[0], TimeSpan.Zero, DateTime.MaxValue);

			Assert.AreEqual("E|D|C", GetItemKeysInLruOrder(imc));
			imc.PutItem("F", "F1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			Assert.AreEqual("F|E|D", GetItemKeysInLruOrder(imc));
		}
		public void LruTest1()
		{
			var imc = new EntityFrameworkCache();
			Assert.AreEqual(int.MaxValue, imc.MaxItems);

			imc.PutItem("A", "A1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("B", "B1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("C", "C1", new string[0], TimeSpan.Zero, DateTime.MaxValue);
			imc.PutItem("D", "D1", new string[0], TimeSpan.Zero, DateTime.MaxValue);

			Assert.AreEqual("D|C|B|A", GetItemKeysInLruOrder(imc));

			object value;
			imc.GetItem("D", out value);
			Assert.AreEqual("D|C|B|A", GetItemKeysInLruOrder(imc));
			imc.GetItem("C", out value);
			Assert.AreEqual("C|D|B|A", GetItemKeysInLruOrder(imc));
			imc.GetItem("D", out value);
			Assert.AreEqual("D|C|B|A", GetItemKeysInLruOrder(imc));
			imc.GetItem("A", out value);
			Assert.AreEqual("A|D|C|B", GetItemKeysInLruOrder(imc));
			imc.GetItem("B", out value);
			Assert.AreEqual("B|A|D|C", GetItemKeysInLruOrder(imc));
			imc.InvalidateItem("B");
			Assert.AreEqual("A|D|C", GetItemKeysInLruOrder(imc));
			imc.InvalidateItem("C");
			Assert.AreEqual("A|D", GetItemKeysInLruOrder(imc));
			imc.InvalidateItem("A");
			Assert.AreEqual("D", GetItemKeysInLruOrder(imc));
			imc.InvalidateItem("D");
			Assert.AreEqual(string.Empty, GetItemKeysInLruOrder(imc));
		}
		public void InMemoryCacheCacheExpirationTest3()
		{
			var cacheWithStatistics = new EntityFrameworkCache();

			object value;

			// current time is 10:00
			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 10, 0, 0);
			cacheWithStatistics.PutItem("Item1", "someValue", new string[0], TimeSpan.Zero, new DateTime(2009, 1, 1, 10, 0, 0));
			cacheWithStatistics.PutItem("Item2", "someValue", new string[0], TimeSpan.Zero, new DateTime(2009, 1, 1, 10, 1, 0));
			cacheWithStatistics.PutItem("Item3", "someValue", new string[0], TimeSpan.Zero, new DateTime(2009, 1, 1, 10, 2, 0));
			cacheWithStatistics.PutItem("Item4", "someValue", new string[0], TimeSpan.Zero, new DateTime(2009, 1, 1, 10, 3, 0));

			cacheWithStatistics.GetCurrentDate = () => new DateTime(2009, 1, 1, 10, 2, 0);

			// no invalidation happens until we try to get an item
			Assert.AreEqual("Item4|Item3|Item2|Item1", GetItemKeysInLruOrder(cacheWithStatistics));

			Assert.IsFalse(cacheWithStatistics.GetItem("Item1", out value));
			Assert.AreEqual("Item4", GetItemKeysInLruOrder(cacheWithStatistics));
		}
Exemple #16
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            // services.AddMiniProfiler(opt =>
            // {
            //     // opt.RouteBasePath = "/profiler";
            //     opt.ShouldProfile = _ => true;
            //     opt.ShowControls = true;
            //     opt.StackMaxLength = short.MaxValue;
            //     opt.PopupStartHidden = false;
            //     opt.PopupShowTrivial = true;
            //     opt.PopupShowTimeWithChildren = true;
            // });

            services.AddHttpsRedirection(options => options.HttpsPort = 443);

            // If environment is localhost, then enable CORS policy, otherwise no cross-origin access
            services.AddCors(options => options.AddPolicy("CorsPolicy", builder => builder
                                                          .WithOrigins(_configuration.GetSection("TrustedSpaUrls").Get <string[]>())
                                                          .AllowAnyHeader()
                                                          .AllowAnyMethod()
                                                          .AllowCredentials()));

            // Add framework services
            // Add functionality to inject IOptions<T>
            services.AddOptions();

            services.AddResponseCompression();

            services.Configure <JwtSettings>(_configuration.GetSection("JwtSettings"));

            services.AddLogging();

            services.AddRouting(options => options.LowercaseUrls = true);

            if (_env.IsDevelopment())
            {
                services.AddDistributedMemoryCache();
            }
            else
            {
                var redisConnectionString =
                    ConnectionStringUrlToRedisResource(_configuration.GetValue <string>("REDISTOGO_URL"));

                services.AddStackExchangeRedisCache(c => c.Configuration = redisConnectionString);
            }

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout         = TimeSpan.FromMinutes(60);
                options.Cookie.HttpOnly     = true;
                options.Cookie.Name         = ApiConstants.AuthenticationSessionCookieName;
                options.Cookie.SecurePolicy = CookieSecurePolicy.None;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "dotnet-template", Version = "v1"
                });

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

                if (File.Exists(xmlPath))
                {
                    c.IncludeXmlComments(xmlPath);
                }

                c.AddSecurityDefinition("Bearer", // Name the security scheme
                                        new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Type        = SecuritySchemeType.Http, // We set the scheme type to http since we're using bearer authentication
                    Scheme      = "bearer"                 // The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer".
                });
            });

            services.AddMvc(x =>
            {
                x.ModelValidatorProviders.Clear();

                // Not need to have https
                x.RequireHttpsPermanent = false;

                // Allow anonymous for localhost
                if (_env.IsDevelopment())
                {
                    x.Filters.Add <AllowAnonymousFilter>();
                }

                // Exception filter attribute
                x.Filters.Add <ExceptionFilterAttribute>();
            }).AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            })
            .AddRazorPagesOptions(x => x.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()));

            services.AddDbContext <EntityDbContext>(opt =>
            {
                if (_env.IsDevelopment())
                {
                    opt.UseSqlite(_configuration.GetValue <string>("ConnectionStrings:Sqlite"));
                }
                else
                {
                    var postgresConnectionString =
                        ConnectionStringUrlToPgResource(_configuration.GetValue <string>("DATABASE_URL")
                                                        ?? throw new Exception("DATABASE_URL is null"));
                    opt.UseNpgsql(postgresConnectionString);
                }
            });

            services.AddIdentity <User, IdentityRole <int> >(x => x.User.RequireUniqueEmail = true)
            .AddEntityFrameworkStores <EntityDbContext>()
            .AddRoles <IdentityRole <int> >()
            .AddDefaultTokenProviders();

            // L2 EF cache
            if (_env.IsDevelopment())
            {
                EntityFrameworkCache.Initialize(new InMemoryCache());
            }
            else
            {
                var redisConnectionString =
                    ConnectionStringUrlToRedisResource(_configuration.GetValue <string>("REDISTOGO_URL"));

                var redisConfigurationOptions = ConfigurationOptions.Parse(redisConnectionString);

                // Important
                redisConfigurationOptions.AbortOnConnectFail = false;

                EntityFrameworkCache.Initialize(new RedisCache(redisConfigurationOptions));
            }

            var jwtSetting = _configuration
                             .GetSection("JwtSettings")
                             .Get <JwtSettings>();

            if (_env.IsDevelopment() && string.IsNullOrEmpty(jwtSetting.Key))
            {
                jwtSetting.Key = PasswordGenerator.Generate(length: 100, allowed: Sets.Alphanumerics);

                IdentityModelEventSource.ShowPII = true;
            }

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(x => x.Cookie.MaxAge = TimeSpan.FromMinutes(60))
            .AddJwtBearer(config =>
            {
                config.RequireHttpsMetadata = false;
                config.SaveToken            = true;

                config.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer      = jwtSetting.Issuer,
                    ValidAudience    = jwtSetting.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.Key))
                };
            });

            services.AddSingleton <IUserIdProvider, CustomUserIdProvider>();

            services.AddSignalR(config =>
            {
                config.MaximumReceiveMessageSize = 10 * 1024 * 1024; // 10 mega-bytes
                config.StreamBufferCapacity      = 50;
                config.EnableDetailedErrors      = true;
            });

            // Re-Captcha config
            services.Configure <RecaptchaSettings>(_configuration.GetSection("RecaptchaSettings"));
            services.AddTransient <IRecaptchaService, RecaptchaService>();

            services.AddEfRepository <EntityDbContext>(x => x.Profile(Assembly.Load("Dal")));

            var container = new Container(config =>
            {
                config.For <JwtSettings>().Use(jwtSetting).Singleton();

                // If environment is localhost then use mock email service
                if (_env.IsDevelopment())
                {
                    config.For <IS3Service>().Use(new S3Service()).Singleton();
                }
                else
                {
                    var(accessKeyId, secretAccessKey, url) = (
                        _configuration.GetRequiredValue <string>("CLOUDCUBE_ACCESS_KEY_ID"),
                        _configuration.GetRequiredValue <string>("CLOUDCUBE_SECRET_ACCESS_KEY"),
                        _configuration.GetRequiredValue <string>("CLOUDCUBE_URL")
                        );

                    var prefix = new Uri(url).Segments.GetValue(1)?.ToString();
                    const string bucketName = "cloud-cube";

                    // Generally bad practice
                    var credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);

                    // Create S3 client
                    config.For <IAmazonS3>().Use(() => new AmazonS3Client(credentials, RegionEndpoint.USEast1));
                    config.For <S3ServiceConfig>().Use(new S3ServiceConfig(bucketName, prefix));

                    config.For <IS3Service>().Use(ctx => new S3Service(
                                                      ctx.GetInstance <ILogger <S3Service> >(),
                                                      ctx.GetInstance <IAmazonS3>(),
                                                      ctx.GetInstance <S3ServiceConfig>()
                                                      ));
                }

                // Register stuff in container, using the StructureMap APIs...
                config.Scan(_ =>
                {
                    _.AssemblyContainingType(typeof(Startup));
                    _.Assembly("Api");
                    _.Assembly("Logic");
                    _.Assembly("Dal");
                    _.WithDefaultConventions();
                });

                // Populate the container using the service collection
                config.Populate(services);
            });

            container.AssertConfigurationIsValid();

            return(container.GetInstance <IServiceProvider>());
        }