public HttpResponseMessage Disconnect([FromBody] CommandViewModel commandViewModel) { try { var response = new CommandResponseViewModel(); _logger.WriteLogEntry(_tenantId.ToString(), null, string.Format(MethodBase.GetCurrentMethod().Name + " in ProvisioningAPI was called."), LogLevelType.Info); if (commandViewModel == null) { throw new Exception("Did not receive any json message in the post body."); } if (commandViewModel.EquipmentId < 1) { throw new Exception("EquipmentId is a required parameter."); } var connectionInfo = Setup(commandViewModel.EquipmentId, commandViewModel.SessionId); if (connectionInfo == null) { throw new Exception("Could not find any connection settings for the equipmentId."); } //Now lock the thread so it cannot be used by any other thread. using (var tlh = new ThreadLockHelper()) { tlh.Lock(connectionInfo.LockObj, commandViewModel.Timeout); // Do thread safe work here if (connectionInfo.ConnectionManagerService.IsConnected) { var sr = connectionInfo.ConnectionManagerService.Disconnect(); response = new CommandResponseViewModel { Data = sr.Data, SessionId = connectionInfo.SessionId, TimeoutOccurred = sr.TimeoutOccurred }; } } //Clear Cache Service in memory var memoryCachingService = new MemoryCacheProvider(); memoryCachingService.ClearCache(connectionInfo.SessionId); return(Request.CreateResponse(HttpStatusCode.OK, response)); } catch (Exception ex) { _logger.WriteLogEntry(_tenantId.ToString(), new List <object> { ex.RetrieveEntityExceptionDataAsObjectList() }, string.Format(MethodBase.GetCurrentMethod().Name + " in " + _name), LogLevelType.Error, ex.GetInnerMostException()); throw; } }
public void NullValueExpressionTest() { MemoryCacheProvider.ClearCache(); var loggerProvider = new DebugLoggerProvider(); var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var options = new DbContextOptionsBuilder <BloggingContext>() .UseLoggerFactory(loggerFactory) .UseInMemoryDatabase(databaseName: "ConstantExpressionTest") .Options; // create test entries using (var initContext = new BloggingContext(options)) { initContext.Blogs.Add(new Blog { BlogId = 1, Url = "http://sample.com/cats" }); initContext.Blogs.Add(new Blog { BlogId = 2, Url = "http://sample.com/catfish" }); initContext.Blogs.Add(new Blog { BlogId = 3, Url = "http://sample.com/dogs" }); initContext.SaveChanges(); } int?ratingValue = null; using (var constantContext = new BloggingContext(options)) { // shoud not hit cache, because first execution var result = constantContext.Blogs .Where(d => d.BlogId > 1) .Where(d => d.Rating == ratingValue) .Select(d => d.BlogId) .Cacheable(TimeSpan.FromMinutes(5)) .ToList(); // shoud hit cache, because second execution var cachedResult = constantContext.Blogs .Where(d => d.BlogId > 1) .Where(d => d.Rating == ratingValue) .Select(d => d.BlogId) .Cacheable(TimeSpan.FromMinutes(5)) .ToList(); Assert.AreEqual(result.Count, cachedResult.Count); } // find "cache hit" log entries var logs = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.CacheHit); // cache should hit one time Assert.IsTrue(logs.Count() == 1); }
public void GlobalQueryFilterTest() { MemoryCacheProvider.ClearCache(); var loggerProvider = new DebugLoggerProvider(); var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var options = new DbContextOptionsBuilder <AgnosticBloggingContext>() .UseLoggerFactory(loggerFactory) .UseInMemoryDatabase(databaseName: "GlobalQueryFilterTest") .UseSecondLevelCache() .Options; // create test entries using (var initContext = new AgnosticBloggingContext(options)) { initContext.Blogs.Add(new Blog { BlogId = 1, Url = "http://sample.com/cats" }); initContext.Blogs.Add(new Blog { BlogId = 2, Url = "http://sample.com/catfish" }); initContext.Blogs.Add(new Blog { BlogId = 3, Url = "http://sample.com/dogs" }); initContext.SaveChanges(); } using (var constantContext = new AgnosticBloggingContext(options, minBlogId: 2)) { // shoud not hit cache, because no Cacheable call var rawResult = constantContext.Blogs .Count(); // shoud not hit cache, because first execution var result = constantContext.Blogs .Cacheable(TimeSpan.FromMinutes(5)) .Count(); // shoud hit cache, because second execution var cachedResult = constantContext.Blogs .Cacheable(TimeSpan.FromMinutes(5)) .Count(); Assert.AreEqual(result, cachedResult); } // find "cache hit" log entries var logs = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.CacheHit); // cache should hit one time Assert.IsTrue(logs.Count() == 1); }
public void PerformanceTest() { MemoryCacheProvider.ClearCache(); decimal loopCount = 1000; var loggerProvider = new DebugLoggerProvider(); var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var options = new DbContextOptionsBuilder <AgnosticBloggingContext>() .UseLoggerFactory(loggerFactory) .UseInMemoryDatabase(databaseName: "PerformanceTest") .UseSecondLevelCache() .Options; // create test entries using (var initContext = new AgnosticBloggingContext(options)) { initContext.ChangeTracker.AutoDetectChangesEnabled = false; for (int i = 0; i < 100000; i++) { initContext.Blogs.Add(new Blog { Url = $"http://sample.com/cat{i}", Posts = new List <Post> { { new Post { Title = $"Post{1}" } } } }); } initContext.SaveChanges(); } var rawOptions = new DbContextOptionsBuilder <AgnosticBloggingContext>() .UseLoggerFactory(loggerFactory) .UseInMemoryDatabase(databaseName: "PerformanceTest") .Options; using (var performanceContext = new AgnosticBloggingContext(rawOptions)) { Stopwatch watch = new Stopwatch(); watch.Start(); // raw queries for (int i = 0; i < loopCount; i++) { var result = performanceContext.Blogs .Where(d => d.BlogId >= 0) .Take(100) .ToList(); } var rawTimeSpan = watch.Elapsed; Debug.WriteLine($"Average default context database query duration [+{TimeSpan.FromTicks((long)(rawTimeSpan.Ticks / loopCount))}]."); } using (var performanceContext = new AgnosticBloggingContext(options)) { Stopwatch watch = new Stopwatch(); watch.Start(); // uncached queries for (int i = 0; i < loopCount; i++) { var result = performanceContext.Blogs .Where(d => d.BlogId >= 0) .Take(100) .ToList(); } var uncachedTimeSpan = watch.Elapsed; // caching query result performanceContext.Blogs .Where(d => d.BlogId >= 0) .Cacheable(TimeSpan.FromMinutes(10)) .Take(100) .ToList(); watch.Restart(); // cached queries for (int i = 0; i < loopCount; i++) { var result = performanceContext.Blogs .Where(d => d.BlogId >= 0) .Cacheable(TimeSpan.FromMinutes(10)) .Take(100) .ToList(); } var cachedTimeSpan = watch.Elapsed; // find log entries var queryResultsCachedCount = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.QueryResultCached).Count(); var cacheHitsCount = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.CacheHit).Count(); // check cache event counts Assert.IsTrue(queryResultsCachedCount == 1); Assert.IsTrue(cacheHitsCount == loopCount); Debug.WriteLine($"Average database query duration [+{TimeSpan.FromTicks((long)(uncachedTimeSpan.Ticks / loopCount))}]."); Debug.WriteLine($"Average cache query duration [+{TimeSpan.FromTicks((long)(cachedTimeSpan.Ticks / loopCount))}]."); Debug.WriteLine($"Cached queries are x{((Decimal)uncachedTimeSpan.Ticks / (Decimal)cachedTimeSpan.Ticks) - 1:N2} times faster."); Assert.IsTrue(cachedTimeSpan < uncachedTimeSpan); } }
/// <summary> /// Testing cache expiration functionality. /// </summary> //[TestMethod] public void ExpirationTest() { MemoryCacheProvider.ClearCache(); var loggerProvider = new DebugLoggerProvider(); var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var options = new DbContextOptionsBuilder <AgnosticBloggingContext>() .UseLoggerFactory(loggerFactory) .UseInMemoryDatabase(databaseName: "ExpirationTest") .UseSecondLevelCache() .Options; // create test entries using (var initContext = new AgnosticBloggingContext(options)) { initContext.Blogs.Add(new Blog { BlogId = 1, Url = "http://sample.com/cats" }); initContext.Blogs.Add(new Blog { BlogId = 2, Url = "http://sample.com/catfish" }); initContext.Blogs.Add(new Blog { BlogId = 3, Url = "http://sample.com/dogs" }); initContext.SaveChanges(); } using (var expirationContext = new AgnosticBloggingContext(options)) { // shoud not hit cache, because first execution var result = expirationContext.Blogs .Where(d => d.BlogId == 1) .Cacheable(TimeSpan.FromSeconds(5)) .ToList(); // shoud hit cache, because second execution result = expirationContext.Blogs .Where(d => d.BlogId == 1) .Cacheable(TimeSpan.FromSeconds(5)) .ToList(); // shoud not hit cache, because different parameter result = expirationContext.Blogs .Where(d => d.BlogId == 2) .Cacheable(TimeSpan.FromSeconds(5)) .ToList(); Thread.Sleep(TimeSpan.FromSeconds(10)); // shoud not hit cache, because expiration result = expirationContext.Blogs .Where(d => d.BlogId == 1) .Cacheable(TimeSpan.FromSeconds(5)) .ToList(); } // find "cache hit" log entries var logs = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.CacheHit); // cache should hit one time Assert.IsTrue(logs.Count() == 1); }
public void SingleProjectionExpressionTest() { MemoryCacheProvider.ClearCache(); var loggerProvider = new DebugLoggerProvider(); var loggerFactory = new LoggerFactory(new[] { loggerProvider }); var options = new DbContextOptionsBuilder <AgnosticBloggingContext>() .UseLoggerFactory(loggerFactory) .UseInMemoryDatabase(databaseName: "ProjectionExpressionTest") .UseSecondLevelCache() .Options; // create test entries using (var initContext = new AgnosticBloggingContext(options)) { initContext.Blogs.Add(new Blog { BlogId = 1, Url = "http://sample.com/cats" }); initContext.Blogs.Add(new Blog { BlogId = 2, Url = "http://sample.com/catfish" }); initContext.Blogs.Add(new Blog { BlogId = 3, Url = "http://sample.com/dogs" }); initContext.SaveChanges(); } using (var projectionContext = new AgnosticBloggingContext(options)) { // shoud not hit cache, because first execution var result = projectionContext.Blogs .Where(d => d.BlogId == 1) .Select(d => new { d.BlogId, d.Rating }) .Cacheable(TimeSpan.FromMinutes(5)) .SingleOrDefault(); Thread.Sleep(TimeSpan.FromSeconds(1)); // shoud hit cache, because second execution var cachedResult = projectionContext.Blogs .Where(d => d.BlogId == 1) .Select(d => new { d.BlogId, d.Rating }) .Cacheable(TimeSpan.FromMinutes(5)) .SingleOrDefault(); Assert.IsNotNull(result); Assert.AreSame(result, cachedResult); } // find "cache hit" log entries var logs = loggerProvider.Entries.Where(e => e.EventId == CacheableEventId.CacheHit); // cache should hit one time Assert.IsTrue(logs.Count() == 1); }
/// <summary> /// Retrieves the bearer token from cache or gets a new token. /// </summary> /// <param name="authenticationSettings">The authentication settings.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"> /// authenticationSettings.ClientId /// or /// authenticationSettings.ClientSecret /// or /// authenticationSettings.Url /// or /// authenticationSettings.Password /// or /// authenticationSettings.Username /// or /// authenticationSettings.TenantName /// </exception> public static AccessTokenResponse RetrieveBearTokenFromCacheOrNew(Oauth2AuthenticationSettings authenticationSettings) { if (string.IsNullOrEmpty(authenticationSettings.ClientId)) { throw new ArgumentNullException("authenticationSettings.ClientId"); } if (string.IsNullOrEmpty(authenticationSettings.ClientSecret)) { throw new ArgumentNullException("authenticationSettings.ClientSecret"); } if (string.IsNullOrEmpty(authenticationSettings.Url)) { throw new ArgumentNullException("authenticationSettings.Url"); } if (string.IsNullOrEmpty(authenticationSettings.Password)) { throw new ArgumentNullException("authenticationSettings.Password"); } if (string.IsNullOrEmpty(authenticationSettings.Username)) { throw new ArgumentNullException("authenticationSettings.Username"); } if (string.IsNullOrEmpty(authenticationSettings.TenantName)) { throw new ArgumentNullException("authenticationSettings.TenantName"); } var oauthClient = new OAuth2Client(new Uri(authenticationSettings.Url + "token"), authenticationSettings.ClientId, authenticationSettings.ClientSecret); string key = string.Concat("AuthHash:", EncryptionHelper.Md5Encryption.GetMd5Hash(string.Concat(authenticationSettings.TenantName, authenticationSettings.Username))); //Cache Token in Memory var memoryCachingService = new MemoryCacheProvider(); var accessTokenResponse = memoryCachingService.FetchAndCache(key, () => oauthClient.RequestAccessTokenUserName(authenticationSettings.Username, authenticationSettings.Password, authenticationSettings.TenantName), SecurityTokenConstants.TokenLifeTime); //If token is within the threshold of expiring get refresh token. var timspan = accessTokenResponse.ExpiresOn - DateTime.Now; //if (accessTokenResponse.ExpiresOn >= DateTime.Now - SecurityTokenConstants.TokenLifeTimeEndOfLifeThreshold) if (timspan > new TimeSpan(0, 0, 0, 0) && timspan < SecurityTokenConstants.TokenLifeTimeEndOfLifeThreshold) { accessTokenResponse = RetrieveNewRefreshBearToken(authenticationSettings, accessTokenResponse.RefreshToken); } if (accessTokenResponse == null || accessTokenResponse.ExpiresOn <= DateTime.Now) { memoryCachingService.ClearCache(key); accessTokenResponse = memoryCachingService.FetchAndCache(key, () => oauthClient.RequestAccessTokenUserName(authenticationSettings.Username, authenticationSettings.Password, authenticationSettings.TenantName), SecurityTokenConstants.TokenLifeTime); return(accessTokenResponse); } return(accessTokenResponse); }