private bool IsCacheRetrievalEnabled(IResourceDataRequest request) { bool isRead = request.Action == ResourceAction.Read; bool isLoginAttempt = request.Type == typeof(ILoginAttempt); bool isProviderAccountAccess = request.Type == typeof(IProviderAccountAccess); bool isCollectionResource = this.typeLookup.IsCollectionResponse(request.Type); bool isExpandedRequest = request.Uri.ToString().Contains("expand="); return // Only consider cache retrieval for GETs (isRead && // Login attempts are always sent to the server !isLoginAttempt && // Provider account access looks like an IAccount response, but it should not be cached !isProviderAccountAccess && // Not currently caching collections !isCollectionResource && // Always send expanded requests to the server !isExpandedRequest); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { if (request.Action == ResourceAction.Delete) { return(new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null)); } else { return(chain.Filter(request, logger)); } }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { if (request.Action == ResourceAction.Delete) { return new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null); } else { return chain.Filter(request, logger); } }
Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { if (request.Action == ResourceAction.Delete) { return(Task.FromResult <IResourceDataResult>( new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null))); } else { return(chain.FilterAsync(request, logger, cancellationToken)); } }
private void CacheNestedCustomDataUpdates(IResourceDataRequest request, IResourceDataResult result, ILogger logger) { object customDataObj = null; Map customData = null; if (!request.Properties.TryGetValue(AbstractExtendableInstanceResource.CustomDataPropertyName, out customDataObj)) { return; } customData = customDataObj as Map; if (customData.IsNullOrEmpty()) { return; } bool creating = request.Action == ResourceAction.Create; var parentHref = request.Uri.ResourcePath.ToString(); if (creating && !result.Body.TryGetValueAsString(AbstractResource.HrefPropertyName, out parentHref)) { return; } var customDataHref = parentHref + "/customData"; var dataToCache = this.GetCachedValue(typeof(ICustomData), customDataHref); if (!creating && dataToCache == null) { logger.Trace($"Request {request.Uri} has nested custom data updates, but no authoritative cached custom data exists; aborting", "WriteCacheFilter.CacheNestedCustomDataUpdates"); return; } logger.Trace($"Request {request.Uri} has nested custom data updates, updating cached custom data", "WriteCacheFilter.CacheNestedCustomDataUpdates"); if (dataToCache.IsNullOrEmpty()) { dataToCache = new Dictionary <string, object>(); } foreach (var updatedItem in customData) { dataToCache[updatedItem.Key] = updatedItem.Value; } // Ensure the href property exists dataToCache[AbstractResource.HrefPropertyName] = customDataHref; this.Cache(typeof(ICustomData), dataToCache, logger); }
public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { bool cacheEnabled = this.cacheResolver.IsSynchronousSupported; if (!cacheEnabled) { return(chain.Filter(request, logger)); } bool isDelete = request.Action == ResourceAction.Delete; bool isCustomDataPropertyRequest = request.Uri.ResourcePath.ToString().Contains("/customData/"); if (isCustomDataPropertyRequest && isDelete) { logger.Trace($"Request {request.Action} {request.Uri} is a custom data property delete, deleting cached property name if exists", "WriteCacheFilter.FilterAsync"); this.UncacheCustomDataProperty(request.Uri.ResourcePath, logger); } else if (isDelete) { logger.Trace($"Request {request.Action} {request.Uri} is a resource deletion, purging from cache if exists", "WriteCacheFilter.Filter"); var cacheKey = this.GetCacheKey(request); this.Uncache(request.Type, cacheKey); } var result = chain.Filter(request, logger); bool isEmailVerificationResponse = result.Type == typeof(IEmailVerificationToken); if (isEmailVerificationResponse) { logger.Trace($"Request {request.Action} {request.Uri} is an email verification request, purging account from cache if exists", "WriteCacheFilter.Filter"); this.UncacheAccountOnEmailVerification(result); } bool possibleCustomDataUpdate = (request.Action == ResourceAction.Create || request.Action == ResourceAction.Update) && AbstractExtendableInstanceResource.IsExtendable(request.Type); if (possibleCustomDataUpdate) { this.CacheNestedCustomDataUpdates(request, result, logger); } if (IsCacheable(request, result)) { logger.Trace($"Caching request {request.Action} {request.Uri}", "WriteCacheFilter.Filter"); this.Cache(result.Type, result.Body, logger); } return(result); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { if (request.Action == ResourceAction.Create) { return new DefaultResourceDataResult( ResourceAction.Create, typeof(IDictionary<string, object>), request.Uri, httpStatus: 200, body: new Dictionary<string, object>() { { "Foo", "bar" } }); } else { return chain.Filter(request, logger); } }
public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { bool cacheEnabled = this.cacheResolver.IsSynchronousSupported; if (!cacheEnabled) { return chain.Filter(request, logger); } bool isDelete = request.Action == ResourceAction.Delete; bool isCustomDataPropertyRequest = request.Uri.ResourcePath.ToString().Contains("/customData/"); if (isCustomDataPropertyRequest && isDelete) { logger.Trace($"Request {request.Action} {request.Uri} is a custom data property delete, deleting cached property name if exists", "WriteCacheFilter.FilterAsync"); this.UncacheCustomDataProperty(request.Uri.ResourcePath, logger); } else if (isDelete) { logger.Trace($"Request {request.Action} {request.Uri} is a resource deletion, purging from cache if exists", "WriteCacheFilter.Filter"); var cacheKey = this.GetCacheKey(request); this.Uncache(request.Type, cacheKey); } var result = chain.Filter(request, logger); bool isEmailVerificationResponse = result.Type == typeof(IEmailVerificationToken); if (isEmailVerificationResponse) { logger.Trace($"Request {request.Action} {request.Uri} is an email verification request, purging account from cache if exists", "WriteCacheFilter.Filter"); this.UncacheAccountOnEmailVerification(result); } bool possibleCustomDataUpdate = (request.Action == ResourceAction.Create || request.Action == ResourceAction.Update) && AbstractExtendableInstanceResource.IsExtendable(request.Type); if (possibleCustomDataUpdate) { this.CacheNestedCustomDataUpdates(request, result, logger); } if (IsCacheable(request, result)) { logger.Trace($"Caching request {request.Action} {request.Uri}", "WriteCacheFilter.Filter"); this.Cache(result.Type, result.Body, logger); } return result; }
IResourceDataResult ISynchronousFilterChain.Filter(IResourceDataRequest request, ILogger logger) { bool hasFilters = !this.filters.IsNullOrEmpty(); if (!hasFilters) { throw new ApplicationException("Empty filter chain"); } if (this.filters.Count == 1) { return this.filters.Single().Filter( request, chain: null, logger: logger); } var remainingChain = new DefaultSynchronousFilterChain(this.dataStore, this.filters.Skip(1)); return this.filters.First().Filter(request, remainingChain, logger); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { if (request.Action == ResourceAction.Create) { return(new DefaultResourceDataResult( ResourceAction.Create, typeof(IDictionary <string, object>), request.Uri, httpStatus: 200, body: new Dictionary <string, object>() { { "Foo", "bar" } })); } else { return(chain.Filter(request, logger)); } }
Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { if (request.Action == ResourceAction.Create) { return(Task.FromResult <IResourceDataResult>(new DefaultResourceDataResult( ResourceAction.Create, typeof(IDictionary <string, object>), request.Uri, httpStatus: 200, body: new Dictionary <string, object>() { { "Foo", "bar" } }))); } else { return(chain.FilterAsync(request, logger, cancellationToken)); } }
async Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false); if (!IsCreateOrUpdate(request)) { return(result); // short-circuit } if (!IsAccountStoreMapping(result)) { return(result); // short-circuit } var applicationHref = GetContainerHref("application", result); if (!string.IsNullOrEmpty(applicationHref)) { var application = await chain.DataStore.GetResourceSkipCacheAsync <IApplication>(applicationHref, cancellationToken).ConfigureAwait(false); var allMappings = await application.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync"); return(result); // done } var organizationHref = GetContainerHref("organization", result); if (!string.IsNullOrEmpty(organizationHref)) { var organization = await chain.DataStore.GetResourceSkipCacheAsync <IOrganization>(organizationHref, cancellationToken).ConfigureAwait(false); var allMappings = await organization.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync"); return(result); // done } throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}"); }
private IResourceDataResult GetCachedResourceData(IResourceDataRequest request, ILogger logger) { // TODO isApiKeyCollectionQuery var cacheKey = this.GetCacheKey(request); if (string.IsNullOrEmpty(cacheKey)) { logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceData"); return(null); } var data = this.GetCachedValue(request.Type, cacheKey); if (data == null) { return(null); } return(new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data)); }
private static bool IsCacheable(IResourceDataRequest request, IResourceDataResult result) { bool hasData = !result.Body.IsNullOrEmpty(); return // Must be a resource (IsResource(result?.Body) && // Don't cache password reset or email verification requests result.Type != typeof(IPasswordResetToken) && result.Type != typeof(IEmailVerificationToken) && result.Type != typeof(IEmailVerificationRequest) && // Don't cache login attempts result.Type != typeof(IAuthenticationResult) && // ProviderAccountResults look like IAccounts but should not be cached either result.Type != typeof(IProviderAccountResult)); }
private async Task <IResourceDataResult> GetCachedResourceDataAsync(IResourceDataRequest request, ILogger logger, CancellationToken cancellationToken) { // TODO isApiKeyCollectionQuery var cacheKey = this.GetCacheKey(request); if (string.IsNullOrEmpty(cacheKey)) { logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceDataAsync"); return(null); } var data = await this.GetCachedValueAsync(request.Type, cacheKey, cancellationToken).ConfigureAwait(false); if (data == null) { return(null); } return(new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data)); }
IResourceDataResult ISynchronousFilterChain.Filter(IResourceDataRequest request, ILogger logger) { bool hasFilters = !this.filters.IsNullOrEmpty(); if (!hasFilters) { throw new ApplicationException("Empty filter chain"); } if (this.filters.Count == 1) { return(this.filters.Single().Filter( request, chain: null, logger: logger)); } var remainingChain = new DefaultSynchronousFilterChain(this.dataStore, this.filters.Skip(1)); return(this.filters.First().Filter(request, remainingChain, logger)); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { var result = chain.Filter(request, logger); if (!IsCreateOrUpdate(request)) { return(result); // short-circuit } if (!IsAccountStoreMapping(result)) { return(result); // short-circuit } var applicationHref = GetContainerHref("application", result); if (!string.IsNullOrEmpty(applicationHref)) { var application = chain.DataStore.GetResourceSkipCache <IApplication>(applicationHref); var allMappings = application.GetAccountStoreMappings().Synchronously().ToList(); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter"); return(result); // done } var organizationHref = GetContainerHref("organization", result); if (!string.IsNullOrEmpty(organizationHref)) { var organization = chain.DataStore.GetResourceSkipCache <IOrganization>(organizationHref); var allMappings = organization.GetAccountStoreMappings().Synchronously().ToList(); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter"); return(result); // done } throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}"); }
public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { bool cacheEnabled = this.cacheResolver.IsAsynchronousSupported && this.IsCacheRetrievalEnabled(request) && !request.SkipCache; if (cacheEnabled) { logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.Filter"); var result = this.GetCachedResourceData(request, logger); if (result != null) { logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.Filter"); return result; // short-circuit the remainder of the filter chain } logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.Filter"); } return chain.Filter(request, logger); }
public override async Task<IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { bool cacheEnabled = this.cacheResolver.IsAsynchronousSupported && this.IsCacheRetrievalEnabled(request) && !request.SkipCache; if (cacheEnabled) { logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.FilterAsync"); var result = await this.GetCachedResourceDataAsync(request, logger, cancellationToken).ConfigureAwait(false); if (result != null) { logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.FilterAsync"); return result; // short-circuit the remainder of the filter chain } logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.FilterAsync"); } return await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { var result = chain.Filter(request, logger); if (!IsCreateOrUpdate(request)) { return result; // short-circuit } if (!IsAccountStoreMapping(result)) { return result; // short-circuit } var applicationHref = GetContainerHref("application", result); if (!string.IsNullOrEmpty(applicationHref)) { var application = chain.DataStore.GetResourceSkipCache<IApplication>(applicationHref); var allMappings = application.GetAccountStoreMappings().Synchronously().ToList(); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter"); return result; // done } var organizationHref = GetContainerHref("organization", result); if (!string.IsNullOrEmpty(organizationHref)) { var organization = chain.DataStore.GetResourceSkipCache<IOrganization>(organizationHref); var allMappings = organization.GetAccountStoreMappings().Synchronously().ToList(); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.Filter"); return result; // done } throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}"); }
async Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false); if (!IsCreateOrUpdate(request)) { return result; // short-circuit } if (!IsAccountStoreMapping(result)) { return result; // short-circuit } var applicationHref = GetContainerHref("application", result); if (!string.IsNullOrEmpty(applicationHref)) { var application = await chain.DataStore.GetResourceSkipCacheAsync<IApplication>(applicationHref, cancellationToken).ConfigureAwait(false); var allMappings = await application.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Application '{applicationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync"); return result; // done } var organizationHref = GetContainerHref("organization", result); if (!string.IsNullOrEmpty(organizationHref)) { var organization = await chain.DataStore.GetResourceSkipCacheAsync<IOrganization>(organizationHref, cancellationToken).ConfigureAwait(false); var allMappings = await organization.GetAccountStoreMappings().ToListAsync(cancellationToken).ConfigureAwait(false); logger.Trace($"AccountStoreMapping update detected; refreshing all {allMappings.Count} AccountStoreMappings in cache for Organization '{organizationHref}'", "AccountStoreMappingCacheInvalidationFilter.FilterAsync"); return result; // done } throw new NotSupportedException($"Unsupported AccountStore container type: {request.Type.Name}"); }
public override async Task <IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { bool cacheEnabled = this.cacheResolver.IsAsynchronousSupported && this.IsCacheRetrievalEnabled(request) && !request.SkipCache; if (cacheEnabled) { logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.FilterAsync"); var result = await this.GetCachedResourceDataAsync(request, logger, cancellationToken).ConfigureAwait(false); if (result != null) { logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.FilterAsync"); return(result); // short-circuit the remainder of the filter chain } logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.FilterAsync"); } return(await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false)); }
public override IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { bool cacheEnabled = this.cacheResolver.IsAsynchronousSupported && this.IsCacheRetrievalEnabled(request) && !request.SkipCache; if (cacheEnabled) { logger.Trace($"Checking cache for resource {request.Uri}", "ReadCacheFilter.Filter"); var result = this.GetCachedResourceData(request, logger); if (result != null) { logger.Trace($"Cache hit for {request.Uri}; returning cached data", "ReadCacheFilter.Filter"); return(result); // short-circuit the remainder of the filter chain } logger.Trace($"Cache miss for {request.Uri}", "ReadCacheFilter.Filter"); } return(chain.Filter(request, logger)); }
private static bool IsCreateOrUpdate(IResourceDataRequest request) => request.Action == ResourceAction.Create || request.Action == ResourceAction.Update;
Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { return this.filterFunc(request, chain, logger, cancellationToken); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { return this.filterFunc(request, chain, logger); }
private async Task<IResourceDataResult> GetCachedResourceDataAsync(IResourceDataRequest request, ILogger logger, CancellationToken cancellationToken) { // TODO isApiKeyCollectionQuery var cacheKey = this.GetCacheKey(request); if (string.IsNullOrEmpty(cacheKey)) { logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceDataAsync"); return null; } var data = await this.GetCachedValueAsync(request.Type, cacheKey, cancellationToken).ConfigureAwait(false); if (data == null) { return null; } return new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data); }
private static bool IsCacheable(IResourceDataRequest request, IResourceDataResult result) { bool hasData = !result.Body.IsNullOrEmpty(); return // Must be a resource IsResource(result?.Body) && // Don't cache password reset or email verification requests result.Type != typeof(IPasswordResetToken) && result.Type != typeof(IEmailVerificationToken) && result.Type != typeof(IEmailVerificationRequest) && // Don't cache login attempts result.Type != typeof(IAuthenticationResult) && // ProviderAccountResults look like IAccounts but should not be cached either result.Type != typeof(IProviderAccountResult); }
private IResourceDataResult GetCachedResourceData(IResourceDataRequest request, ILogger logger) { // TODO isApiKeyCollectionQuery var cacheKey = this.GetCacheKey(request); if (string.IsNullOrEmpty(cacheKey)) { logger.Warn($"Could not construct cacheKey for request {request.Uri}; aborting", "ReadCacheFilter.GetCachedResourceData"); return null; } var data = this.GetCachedValue(request.Type, cacheKey); if (data == null) { return null; } return new DefaultResourceDataResult(request.Action, request.Type, request.Uri, 200, data); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { var result = chain.Filter(request, logger); return FilterCore(result); }
public abstract Task<IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken);
protected string GetCacheKey(IResourceDataRequest request) { return this.GetCacheKey(request.Uri.ResourcePath.ToString()); }
public abstract IResourceDataResult Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger);
Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { if (request.Action == ResourceAction.Create) { return Task.FromResult<IResourceDataResult>(new DefaultResourceDataResult( ResourceAction.Create, typeof(IDictionary<string, object>), request.Uri, httpStatus: 200, body: new Dictionary<string, object>() { { "Foo", "bar" } })); } else { return chain.FilterAsync(request, logger, cancellationToken); } }
Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { if (request.Action == ResourceAction.Delete) { return Task.FromResult<IResourceDataResult>( new DefaultResourceDataResult(ResourceAction.Delete, null, null, 204, null)); } else { return chain.FilterAsync(request, logger, cancellationToken); } }
private bool IsCacheRetrievalEnabled(IResourceDataRequest request) { bool isRead = request.Action == ResourceAction.Read; bool isLoginAttempt = request.Type == typeof(ILoginAttempt); bool isProviderAccountAccess = request.Type == typeof(IProviderAccountAccess); bool isCollectionResource = this.typeLookup.IsCollectionResponse(request.Type); bool isExpandedRequest = request.Uri.ToString().Contains("expand="); return // Only consider cache retrieval for GETs isRead && // Login attempts are always sent to the server !isLoginAttempt && // Provider account access looks like an IAccount response, but it should not be cached !isProviderAccountAccess && // Not currently caching collections !isCollectionResource && // Always send expanded requests to the server !isExpandedRequest; }
async Task<IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false); return FilterCore(result); }
async Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { var result = await chain.FilterAsync(request, logger, cancellationToken).ConfigureAwait(false); return(FilterCore(result)); }
Task <IResourceDataResult> IAsynchronousFilter.FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken) { return(this.filterFunc(request, chain, logger, cancellationToken)); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { var result = chain.Filter(request, logger); return(FilterCore(result)); }
IResourceDataResult ISynchronousFilter.Filter(IResourceDataRequest request, ISynchronousFilterChain chain, ILogger logger) { return(this.filterFunc(request, chain, logger)); }
public abstract Task <IResourceDataResult> FilterAsync(IResourceDataRequest request, IAsynchronousFilterChain chain, ILogger logger, CancellationToken cancellationToken);
private void CacheNestedCustomDataUpdates(IResourceDataRequest request, IResourceDataResult result, ILogger logger) { object customDataObj = null; Map customData = null; if (!request.Properties.TryGetValue(AbstractExtendableInstanceResource.CustomDataPropertyName, out customDataObj)) { return; } customData = customDataObj as Map; if (customData.IsNullOrEmpty()) { return; } bool creating = request.Action == ResourceAction.Create; var parentHref = request.Uri.ResourcePath.ToString(); if (creating && !result.Body.TryGetValueAsString(AbstractResource.HrefPropertyName, out parentHref)) { return; } var customDataHref = parentHref + "/customData"; var dataToCache = this.GetCachedValue(typeof(ICustomData), customDataHref); if (!creating && dataToCache == null) { logger.Trace($"Request {request.Uri} has nested custom data updates, but no authoritative cached custom data exists; aborting", "WriteCacheFilter.CacheNestedCustomDataUpdates"); return; } logger.Trace($"Request {request.Uri} has nested custom data updates, updating cached custom data", "WriteCacheFilter.CacheNestedCustomDataUpdates"); if (dataToCache.IsNullOrEmpty()) { dataToCache = new Dictionary<string, object>(); } foreach (var updatedItem in customData) { dataToCache[updatedItem.Key] = updatedItem.Value; } // Ensure the href property exists dataToCache[AbstractResource.HrefPropertyName] = customDataHref; this.Cache(typeof(ICustomData), dataToCache, logger); }
protected string GetCacheKey(IResourceDataRequest request) { return(this.GetCacheKey(request.Uri.ResourcePath.ToString())); }
private ResourceAction GetPostAction(IResourceDataRequest request, IHttpResponse httpResponse) => httpResponse.StatusCode == 201 ? ResourceAction.Create : request.Action;