diff --git a/Configurations/Entities/XFileEntityConfiguration.cs b/Configurations/Entities/XFileEntityConfiguration.cs new file mode 100644 index 0000000..55cde27 --- /dev/null +++ b/Configurations/Entities/XFileEntityConfiguration.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using xDataService.Providers; +using xFileService.Models.Entities; + +namespace xFileService.Configurations.Entities +{ + public class XFileEntityConfiguration : XBaseEntityTypeConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Files"); + } + } +} \ No newline at end of file diff --git a/Controllers/XFileRepositoryControllerBase.cs b/Controllers/XFileRepositoryControllerBase.cs new file mode 100644 index 0000000..3615275 --- /dev/null +++ b/Controllers/XFileRepositoryControllerBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Providers; +using xDataService.Controllers; +using xDataService.Interfaces; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Controllers +{ + public abstract class XFileRepositoryControllerBase : XBaseRepositoryController, IXBaseRepositoryController + { + protected XFileRepositoryControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + XValidationProvider validationProvider, + IXFileRepository repository, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + validationProvider, + repository, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { } + } +} \ No newline at end of file diff --git a/Controllers/XFileRepositoryProviderControllerBase.cs b/Controllers/XFileRepositoryProviderControllerBase.cs new file mode 100644 index 0000000..efd6623 --- /dev/null +++ b/Controllers/XFileRepositoryProviderControllerBase.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Providers; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; +using xFileService.Providers.Entities; +using xIdentityService.Interfaces; +using xPushService.Controllers; +using xPushService.Interfaces; + +namespace xFileService.Controllers +{ + public abstract class XFileRepositoryProviderControllerBase : XBaseRepositoryProviderController, IXBaseRepositoryProviderController + { + protected XFileRepositoryProviderControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXFileRepositoryProvider provider, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider, + provider, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { } + } +} \ No newline at end of file diff --git a/Controllers/XFileServiceControllerBase.cs b/Controllers/XFileServiceControllerBase.cs index b5c8481..f0cf6c3 100644 --- a/Controllers/XFileServiceControllerBase.cs +++ b/Controllers/XFileServiceControllerBase.cs @@ -1,623 +1,34 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.Logging; using xCommons.Configurations; -using xCommons.Extensions; using xCommons.Providers; -using xFileService.Interfaces; -using xIdentityService.Controllers; -using xIdentityService.Interfaces; -using xModels.Dtos; -using XFileDto = xFileService.Models.Dtos.XFileDto; +using xDataService.Controllers; +using xDataService.Interfaces; +using xFileService.Interfaces.Dtos; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; namespace xFileService.Controllers { - /// - /// a Controller base Class which implement based Actions to Provides File Provider Access ... - /// - public abstract class XFileServiceControllerBase : XIBaseProviderController, IXFileServiceControllerActions + public abstract class XFileServiceControllerBase : XBaseServiceController, IXBaseServiceController { - // - #region Props ... - public IXFileProvider FileProvider { get; } - #endregion - - // - #region Constructor ... protected XFileServiceControllerBase( - ILogger logger, - IXFileProvider fileProvider, + ILogger logger, XAppConfiguration appConfiguration, - IXIdentityProvider identityProvider, - XValidationProvider validationProvider + XValidationProvider validationProvider, + IXFileRepositoryService repositoryService, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null ) : base( logger, appConfiguration, - identityProvider, - validationProvider + validationProvider, + repositoryService, + defaultOrderBuilder, + defaultIncludeBuilder ) - { - // - FileProvider = fileProvider; - } - #endregion - - // - #region Tags ... - /// - /// Attach Tag to Specified Model ... - /// - /// - /// - /// - [HttpPost("{id}/Tags/Attach")] - public virtual async Task AttachTag( - [FromRoute] Guid id, - [FromQuery] string tag - ) - { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - await FileProvider.AttachTag( - id: id, - tag: tag, - userInfo: userInfo, - connectionId: connectionId - ); - - // - return Ok(); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Detach Tag From Specified Model ... - /// - /// - /// - /// - [HttpDelete("{id}/Tags/Detach")] - public virtual async Task DetachTag( - [FromRoute] Guid id, - [FromQuery] string tag - ) - { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - await FileProvider.DetachTag( - id: id, - tag: tag, - userInfo: userInfo, - connectionId: connectionId - ); - - // - return Ok(); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Attach Tags to Specified Model ... - /// - /// - /// - /// - [HttpPost("{id}/Tags/AttachMany")] - public virtual async Task AttachTags( - [FromRoute] Guid id, - [FromQuery] string tags - ) - { - // - // Do ... - try - { - // - var tagsList = tags.ParseListString(); - - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - await FileProvider.AttachTags( - id: id, - tags: tagsList, - userInfo: userInfo, - connectionId: connectionId - ); - - // - return Ok(); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Detach Tags From Specified Model ... - /// - /// - /// - /// - [HttpDelete("{id}/Tags/DetachMany")] - public virtual async Task DetachTags( - [FromRoute] Guid id, - [FromQuery] string tags - ) - { - // - // Do ... - try - { - // - var tagsList = tags.ParseListString(); - - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - await FileProvider.DetachTags( - id: id, - tags: tagsList, - userInfo: userInfo, - connectionId: connectionId - ); - - // - return Ok(); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Retrieve Tags of Specified File ... - /// - /// - /// - [HttpGet("{id}/Tags")] - public virtual async Task>> GetTags( - [FromRoute] Guid id - ) - { - // - // Do ... - try - { - // - var result = await FileProvider.GetTags(id); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - #endregion - - // - #region Tools ... - /// - /// Stream Specified File ... - /// - /// - /// - [HttpGet("{id}/Stream/ById")] - public virtual async Task Stream( - [FromRoute] Guid id - ) - { - // - // Do ... - try - { - // - var result = await FileProvider.Stream(id); - - // - return result; - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Stream Specified File ... - /// - /// - /// - [HttpGet("{name}/Stream/ByName")] - public virtual async Task Stream( - [FromRoute] string name - ) - { - // - // Do ... - try - { - // - var result = await FileProvider.Stream(name); - - // - return result; - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Download Specified File ... - /// - /// - /// - [HttpGet("{id}/Download/ById")] - public virtual async Task Download( - [FromRoute] Guid id - ) - { - // - // Do ... - try - { - // - var result = await FileProvider.Download(id); - - // - return result; - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Download Specified File ... - /// - /// - /// - [HttpGet("{name}/Download/ByName")] - public virtual async Task Download( - [FromRoute] string name - ) - { - // - // Do ... - try - { - // - var result = await FileProvider.Download(name); - - // - return result; - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Upload Files ... - /// - /// - /// - [HttpPost("")] - [RequestSizeLimit(966_367_641)] - public virtual async Task>> Upload( - [FromForm] IFormFileCollection files - ) - { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - var result = await FileProvider.Upload( - files: files, - userInfo: userInfo, - connectionId: connectionId - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Remove Specified Files ... - /// - /// - /// - /// [HttpDelete("Remove")] - [HttpDelete("")] - public virtual async Task>> Remove( - [FromQuery] string ids - ) { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - var result = await FileProvider.Remove( - ids: ids, - userInfo: userInfo, - connectionId: connectionId - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - #endregion - - // - #region Model ... - /// - /// Get Specified File Model ... - /// - /// - /// - [HttpGet("{id}")] - public virtual async Task> Get( - [FromRoute] Guid id - ) { - // - // Do ... - try - { - // - var result = await FileProvider.Get(id); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Get All Exists File Models ... - /// - /// - [HttpGet("All")] - public virtual async Task>> GetAll() { - // - // Do ... - try - { - // - var result = await FileProvider.GetAll(); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// retrieve Entities based on XQuery Pagination structure ... - /// - /// - /// - [HttpGet("Query")] - public virtual async Task>> Query( - [FromQuery] XQuery query - ) { - // - // Do ... - try - { - // - var result = await FileProvider.Query(query); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// retrieve Owned Entities based on XQuery Pagination structure ... - /// - /// - /// - [HttpGet("Query/Owned")] - public virtual async Task>> QueryOwned( - [FromQuery] XQuery query - ) { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - - // - var result = await FileProvider.QueryOwned( - query: query, - userInfo: userInfo - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// count all exists Entities ... - /// - /// - [HttpGet("Count")] - public virtual async Task> Count() { - // - // Do ... - try - { - // - var result = await FileProvider.Count(); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Check an Entity exists or not ... - /// - /// - /// - [HttpGet("{id}/IsExists")] - public virtual async Task> IsExists( - [FromRoute] Guid id - ) { - // - // Do ... - try - { - // - var result = await FileProvider.IsExists(id); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - #endregion + { } } } \ No newline at end of file diff --git a/Controllers/XFileServiceProviderControllerBase.cs b/Controllers/XFileServiceProviderControllerBase.cs new file mode 100644 index 0000000..7232186 --- /dev/null +++ b/Controllers/XFileServiceProviderControllerBase.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Providers; +using xFileService.Interfaces.Dtos; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; +using xFileService.Providers.Dtos; +using xIdentityService.Interfaces; +using xPushService.Controllers; +using xPushService.Interfaces; + +namespace xFileService.Controllers +{ + public abstract class XFileServiceProviderControllerBase : XBaseServiceProviderController, IXBaseServiceProviderController + { + protected XFileServiceProviderControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXFileServiceProvider provider, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider, + provider, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { } + } +} \ No newline at end of file diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index 3fef2dd..4c2d6d8 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -1,12 +1,20 @@ using System; +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using xCommons.Extensions; +using xCommons.Helpers; +using xDataService.Constants; +using xDataService.Db; +using xDataService.DI; +using xDataService.Models; using xExceptions.Constants; -using xFileService.Interfaces; +using xPushService.DI; +using xPushService.Helpers; +using xFileService.Helpers; +using xFileService.Interfaces.Dtos; using xFileService.Interfaces.Entities; -using xFileService.Providers; -using xStorageService.Interfaces; -using xTagService.Interfaces; +using xFileService.Providers.Dtos; +using xFileService.Providers.Entities; namespace xFileService.DI { @@ -16,21 +24,83 @@ namespace xFileService.DI /// Register Service ... /// /// - /// + /// + /// public static void AddXFileService( this IServiceCollection services, - ServiceLifetime lifeTime + XRepositoryType repositoryType, + ServiceLifetime lifeTime = ServiceLifetime.Scoped + ) + { + AddFileService( + contextType: null, + services: services, + lifeTime: lifeTime, + repositoryType: repositoryType + ); + } + + /// + /// Register Service ... + /// + /// + /// + /// + /// + public static void AddXFileService( + this IServiceCollection services, + XRepositoryType repositoryType, + ServiceLifetime lifeTime = ServiceLifetime.Scoped + ) + where TContext : XDbContext + { + AddFileService( + services: services, + lifeTime: lifeTime, + contextType: typeof(TContext), + repositoryType: repositoryType + ); + } + + /// + /// Use XFileService Middleware ... + /// + /// + /// + public static void UseXFileService( + this IApplicationBuilder app, + bool isDevelopmentEnvironment = false ) { // - AddFileService( - services, - lifeTime - ); + #region Using XFile Hubs ... + // + var pushHelper = new XPushServiceHelper(); + + // + pushHelper.AddHub("fileDto"); + pushHelper.AddHub("fileEntity"); + + // + app.UseXPushService(pushHelper); + #endregion + + // + // Using XFile Repository Descriptor ... + if (!descriptor.IsNull()) + { + // + app.UseXRepository( + descriptor: descriptor, + isDevelopmentEnvironment: isDevelopmentEnvironment + ); + } } // #region Private ... + private static XRepositoryDescriptor descriptor = null; + /// /// a LogTag for Service ... /// @@ -49,10 +119,14 @@ namespace xFileService.DI /// Register Service ... /// /// + /// + /// /// private static void AddFileService( IServiceCollection services, - ServiceLifetime lifeTime + XRepositoryType repositoryType, + Type contextType = null, + ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // @@ -64,7 +138,7 @@ namespace xFileService.DI if (!isServicesExists) { // - Log("AddFileService failed, services not provided ..."); + Log("Service Registration failed, services not provided ..."); throw exception; } @@ -74,46 +148,74 @@ namespace xFileService.DI if (!isLifetimeExists) { // - Log("AddFileService failed, lifetime not provided ..."); + Log("Service Registration failed, lifetime not provided ..."); throw exception; } // - // Check Dependencies Exists ... - var isDependenciesPassed = !services - .GetRegisteredService() - .IsNull() && - !services.GetRegisteredService().IsNull(); - if (!isDependenciesPassed) + // Validate Repository Type ... + var isRepositoryTypeValid = + (repositoryType == XRepositoryType.EF && + !contextType.IsNull()) || + ((repositoryType == XRepositoryType.Mongo || + repositoryType == XRepositoryType.InMemory) && + contextType.IsNull()); + if (!isRepositoryTypeValid) { // - Log("AddFileService failed due Dependencies Issues, IXTagProvider, IXStorageProvider not provided ..."); + Log("Service Registration failed, Invalid Repository Type and Context Type ..."); throw exception; } // - // Check Repository Exists ... - var isRepositoryExists = !services - .GetRegisteredService() - .IsNull(); - if (!isRepositoryExists) + // Maske Instance of Repository Descriptor + // Based on Provided Type ... + switch (repositoryType) { // - Log("AddFileService failed, IXFileRepository not provided ..."); - throw exception; + case XRepositoryType.EF: + // + descriptor = typeof(XFileServiceHelper) + .InvokeGenericMethod( + methodName: "GetXFileEFRepositoryDescriptor", + runtimeType: contextType, + args: null + ); + break; + + // + case XRepositoryType.Mongo: + descriptor = XFileServiceHelper.GetXFileMongoRepositoryDescriptor(); + break; + + // + case XRepositoryType.InMemory: + descriptor = XFileServiceHelper.GetXFileInMemoryRepositoryDescriptor(); + break; } // - // Register Tag Provider for Files ... - services.Add(new ServiceDescriptor(typeof(IXFileTagProvider), typeof(XFileTagProvider), lifeTime)); + // Register XFile Repository Descriptor ... + services.AddXRepository( + lifeTime: lifeTime, + descriptor: descriptor + ); // - // Register Main Provider ... - services.Add(new ServiceDescriptor(typeof(IXFileProvider), typeof(XFileProvider), lifeTime)); + // Register Dto Services ... + services.Add( + new ServiceDescriptor(typeof(IXFileServiceProvider), typeof(XFileServiceProvider), lifeTime) + ); + services.Add( + new ServiceDescriptor(typeof(IXFileRepositoryService), typeof(XFileRepositoryService), lifeTime) + ); + services.Add( + new ServiceDescriptor(typeof(IXFileRepositoryProvider), typeof(XFileRepositoryProvider), lifeTime) + ); // - Log("AddFileService Succeed ..."); + Log("Service Regitration Succeed ..."); } - #endregion + #endregion } } \ No newline at end of file diff --git a/DataHelper/Events/XFileEvents.cs b/DataHelper/Events/XFileEvents.cs deleted file mode 100644 index 83faf48..0000000 --- a/DataHelper/Events/XFileEvents.cs +++ /dev/null @@ -1,9 +0,0 @@ -using xDataService.Events; -using xFileService.Interfaces.Entities; -using xFileService.Models.Entities; - -namespace xFileService.DataHelper.Events -{ - public class XFileEvents : XBaseRepositoryEvents, IXFileEvents - { } -} \ No newline at end of file diff --git a/Extensions/XModelExtensions.cs b/Extensions/XModelExtensions.cs new file mode 100644 index 0000000..dbe32b1 --- /dev/null +++ b/Extensions/XModelExtensions.cs @@ -0,0 +1,149 @@ +using System.Collections.Generic; +using System.Linq; +using xCommons.Extensions; +using xDataService.Extensions; +using xDataService.Models; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; + +namespace xFileService.Extensions +{ + public static class XModelExtensions + { + /// + /// Extract References of a Model ... + /// + /// + /// + public static IList> GetReferences( + this XFile source + ) + { + // + var result = new List>(); + + // + if ( + !source.IsNullOrDefault() && + !source.References.IsNullOrEmpty() + ) + { + // + result = source.References + .ParseXReferenceList() + .ToList(); + } + + // + return result; + } + + /// + /// Extract References of a Model ... + /// + /// + /// + public static IList> GetReferences( + this XFileDto source + ) + { + // + var result = new List>(); + + // + if ( + !source.IsNullOrDefault() && + !source.References.IsNullOrEmpty() + ) + { + // + result = source.References + .ParseXReferenceList() + .ToList(); + } + + // + return result; + } + + /// + /// Update a Model's References by Providing References List ... + /// + /// + /// + /// + /// + public static XFile UpdateReferences( + this XFile source, + IList> references, + bool forceClean = true + ) + { + // + XFile result = source; + + // + if (!source.IsNullOrDefault()) + { + // + result = source; + + // + if (forceClean) + { + result.References = string.Empty; + } + + // + if (!references.IsNull() && + references.HasChild()) + { + result.References = references.ToXReferenceString(); + } + } + + // + return result; + } + + /// + /// Update a Model's References by Providing References List ... + /// + /// + /// + /// + /// + public static XFileDto UpdateReferences( + this XFileDto source, + IList> references, + bool forceClean = true + ) + { + // + XFileDto result = source; + + // + if (!source.IsNullOrDefault()) + { + // + result = source; + + // + if (forceClean) + { + result.References = string.Empty; + } + + // + if (!references.IsNull() && + references.HasChild()) + { + result.References = references.ToXReferenceString(); + } + } + + // + return result; + } + } +} \ No newline at end of file diff --git a/Extensions/xFileServiceExtensions.cs b/Extensions/xFileServiceExtensions.cs deleted file mode 100644 index ae054ca..0000000 --- a/Extensions/xFileServiceExtensions.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections.Generic; -using xCommons.Extensions; -using xDataService.Extensions; -using xFileService.Models.Dtos; -using xFileService.Models.Entities; - -namespace xFileService.Extensions -{ - public static class xFileServiceExtensions - { - /// - /// Map Global Properties From XFile to XFile Dto ... - /// - /// - /// - public static XFileDto ToDto(this XFile source) - { - // - XFileDto result = null; - - // - if (!source.IsNullOrDefault()) - { - // - result = new XFileDto(); - result = result.UpdateData( - updateWith: source, - propertyBlackList: new List - { - nameof(XFileDto.Owner), - nameof(XFile.Deleted), - nameof(XFile.References), - } - ); - - - // - // Preparing List ... - if (!source.References.IsNullOrEmpty()) - { - result.References = source.References.ParseXReferenceList(); - } - } - - // - return result; - } - - /// - /// Converts a Dto to Entity Representation ... - /// Ignore ID Property ... - /// - /// - /// - public static XFile FromDto(this XFileDto source) - { - // - var result = new XFile(); - - // - if (!source.IsNull()) - { - // - result = result.UpdateData( - updateWith: source, - propertyBlackList: new List - { - nameof(XFile.Deleted), - nameof(XFile.References), - } - ); - - // - if (!source.References.IsNull() && source.References.HasChild()) - { - result.References = source.References.ToXReferenceString(); - } - } - - // - return result; - - } - } -} \ No newline at end of file diff --git a/Helpers/.gitkeep b/Helpers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/Helpers/XFileServiceHelper.cs b/Helpers/XFileServiceHelper.cs new file mode 100644 index 0000000..84c6bdd --- /dev/null +++ b/Helpers/XFileServiceHelper.cs @@ -0,0 +1,280 @@ +using System; +using GraphQL.Types; +using xDataService.Db; +using xDataService.Models; +using xDataService.Providers; +using xFileService.Interfaces; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; +using xFileService.Providers.Entities; +using xFileService.Providers.GraphQL; + +namespace xFileService.Helpers +{ + public static class XFileServiceHelper + { + // + #region EF Repository Descriptor Provider(s) ... + public static XEFRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileEFRepository, + TContext + > GetXFileEFRepositoryDescriptor() + where TContext : XDbContext + { + // + var result = new XEFRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileEFRepository, + TContext + >(); + + // + return result; + } + + public static XEFRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileEFRepository, + TContext, + IXFileSeeder, + TSeederImplementation + > GetXFileEFRepositoryDescriptor() + where TContext : XDbContext + where TSeederImplementation : XBaseDbSeeder + { + // + var result = new XEFRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileEFRepository, + TContext, + IXFileSeeder, + TSeederImplementation + >(); + + // + return result; + } + #endregion + + // + #region Mongo Repository Descriptor Provider(s) ... + public static XMongoRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileMongoRepository + > GetXFileMongoRepositoryDescriptor() + { + // + var result = new XMongoRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileMongoRepository + >(); + + // + return result; + } + + public static XMongoRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileMongoRepository, + IXFileSeeder, + TSeederImplementation + > GetXFileMongoRepositoryDescriptor() + where TSeederImplementation : XBaseDbSeeder + { + // + var result = new XMongoRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileMongoRepository, + IXFileSeeder, + TSeederImplementation + >(); + + // + return result; + } + #endregion + + // + #region InMemory Repository Descriptor Provider(s) ... + public static XInMemoryRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileInMemoryRepository + > GetXFileInMemoryRepositoryDescriptor() + { + // + var result = new XInMemoryRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileInMemoryRepository + >(); + + // + return result; + } + + public static XInMemoryRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileInMemoryRepository, + IXFileSeeder, + TSeederImplementation + > GetXFileInMemoryRepositoryDescriptor() + where TSeederImplementation : XBaseDbSeeder + { + // + var result = new XInMemoryRepositoryDescriptor< + XFile, + Guid, + IXFileKeyGenerator, + XFileKeyGenerator, + IXFileRepositoryEvents, + XFileRepositoryEvents, + XFileGraphType, + GuidGraphType, + XFileGraphQuery, + IXFileGraphQLTypeHelper, + XFileGraphQLTypeHelper, + XFileGraphSchema, + IXFileRepository, + XFileInMemoryRepository, + IXFileSeeder, + TSeederImplementation + >(); + + // + return result; + } + #endregion + } +} \ No newline at end of file diff --git a/Hubs/XFileEntityHub.cs b/Hubs/XFileEntityHub.cs deleted file mode 100644 index 2b0e4ed..0000000 --- a/Hubs/XFileEntityHub.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; -using xFileService.Models.Entities; -using xPushService.Base; - -namespace xFileService.Hubs -{ - public class XFileEntityHub : XBaseEntityHub - { - // - #region Constructor ... - public XFileEntityHub(ILogger logger) : base(logger) - { } - #endregion - } -} \ No newline at end of file diff --git a/Interfaces/Dtos/IXFileDtoHub.cs b/Interfaces/Dtos/IXFileDtoHub.cs new file mode 100644 index 0000000..4b40a32 --- /dev/null +++ b/Interfaces/Dtos/IXFileDtoHub.cs @@ -0,0 +1,10 @@ +using System; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; +using xPushService.Interfaces; + +namespace xFileService.Interfaces.Dtos +{ + public interface IXFileDtoHub : IXBaseDtoHub + { } +} \ No newline at end of file diff --git a/Interfaces/Dtos/IXFileRepositoryService.cs b/Interfaces/Dtos/IXFileRepositoryService.cs new file mode 100644 index 0000000..ed560b4 --- /dev/null +++ b/Interfaces/Dtos/IXFileRepositoryService.cs @@ -0,0 +1,10 @@ +using System; +using xDataService.Interfaces; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; + +namespace xFileService.Interfaces.Dtos +{ + public interface IXFileRepositoryService : IXBaseRepositoryService + { } +} \ No newline at end of file diff --git a/Interfaces/Dtos/IXFileServiceProvider.cs b/Interfaces/Dtos/IXFileServiceProvider.cs new file mode 100644 index 0000000..cdce883 --- /dev/null +++ b/Interfaces/Dtos/IXFileServiceProvider.cs @@ -0,0 +1,11 @@ +using System; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; +using xFileService.Providers.Dtos; +using xPushService.Interfaces; + +namespace xFileService.Interfaces.Dtos +{ + public interface IXFileServiceProvider : IXBaseDtoProvider + { } +} \ No newline at end of file diff --git a/Interfaces/Entities/IXFileEntityHub.cs b/Interfaces/Entities/IXFileEntityHub.cs new file mode 100644 index 0000000..c2b1b8c --- /dev/null +++ b/Interfaces/Entities/IXFileEntityHub.cs @@ -0,0 +1,9 @@ +using System; +using xFileService.Models.Entities; +using xPushService.Interfaces; + +namespace xFileService.Interfaces.Entities +{ + public interface IXFileEntityHub : IXBaseEntityHub + { } +} \ No newline at end of file diff --git a/Interfaces/Entities/IXFileKeyGenerator.cs b/Interfaces/Entities/IXFileKeyGenerator.cs new file mode 100644 index 0000000..302ac92 --- /dev/null +++ b/Interfaces/Entities/IXFileKeyGenerator.cs @@ -0,0 +1,9 @@ +using System; +using xDataService.Interfaces; +using xFileService.Models.Entities; + +namespace xFileService.Interfaces.Entities +{ + public interface IXFileKeyGenerator : IXKeyGenerator + { } +} \ No newline at end of file diff --git a/Interfaces/Entities/IXFileEvents.cs b/Interfaces/Entities/IXFileRepositoryEvents.cs similarity index 61% rename from Interfaces/Entities/IXFileEvents.cs rename to Interfaces/Entities/IXFileRepositoryEvents.cs index 923d3d8..d562c95 100644 --- a/Interfaces/Entities/IXFileEvents.cs +++ b/Interfaces/Entities/IXFileRepositoryEvents.cs @@ -3,6 +3,6 @@ using xFileService.Models.Entities; namespace xFileService.Interfaces.Entities { - public interface IXFileEvents : IXBaseRepositoryEvents + public interface IXFileRepositoryEvents : IXBaseRepositoryEvents { } } \ No newline at end of file diff --git a/Interfaces/Entities/IXFileRepositoryProvider.cs b/Interfaces/Entities/IXFileRepositoryProvider.cs new file mode 100644 index 0000000..35e9b2d --- /dev/null +++ b/Interfaces/Entities/IXFileRepositoryProvider.cs @@ -0,0 +1,10 @@ +using System; +using xFileService.Models.Entities; +using xFileService.Providers.Entities; +using xPushService.Interfaces; + +namespace xFileService.Interfaces.Entities +{ + public interface IXFileRepositoryProvider : IXBaseEntityProvider + { } +} \ No newline at end of file diff --git a/Interfaces/IXBaseFileProvider.cs b/Interfaces/IXBaseFileProvider.cs deleted file mode 100644 index 06bae52..0000000 --- a/Interfaces/IXBaseFileProvider.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using xFileService.Models.Dtos; -using xIdentityModels.Models; -using xIdentityService.Interfaces; -using XFileDto = xFileService.Models.Dtos.XFileDto; - -namespace xFileService.Interfaces -{ - /// - /// Implementing XBaseFileProvider ... - /// - /// - public interface IXBaseFileProvider : IXIdentityBaseReferencedProvider - { - // - #region Props ... - /// - /// Specified Provider Repositroy ... - /// - IXFileProvider FileProvider { get; } - #endregion - - // - #region Tools ... - /// - /// Stream Specified File ... - /// - /// - /// - Task Stream(Guid id); - - /// - /// Stream Specified File ... - /// - /// - /// - Task Stream(string fileName); - - /// - /// Download Specified File ... - /// - /// - /// - Task Download(Guid id); - - /// - /// Download Specified File ... - /// - /// - /// - Task Download(string fileName); - - /// - /// Upload Files ... - /// - /// - /// - /// - /// - /// - Task> Upload( - TKey forProvidedId, - IFormFileCollection files, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ); - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - Task GetFileDescriptor(Guid id); - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - Task GetFileDescriptor(string fileName); - #endregion - } -} \ No newline at end of file diff --git a/Interfaces/IXFileProvider.cs b/Interfaces/IXFileProvider.cs index 82e2f8a..4e47948 100644 --- a/Interfaces/IXFileProvider.cs +++ b/Interfaces/IXFileProvider.cs @@ -1,398 +1,12 @@ using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SignalR; -using xDataService.Configuration; -using xFileService.Hubs; -using xFileService.Interfaces.Entities; using xFileService.Models.Dtos; using xFileService.Models.Entities; -using xIdentityModels.Models; +using xFileService.Providers.Dtos; using xIdentityService.Interfaces; -using xModels.Dtos; -using xStorageService.Interfaces; -using XFileDto = xFileService.Models.Dtos.XFileDto; +using xTagService.Interfaces; namespace xFileService.Interfaces { - public interface IXFileProvider - { - // - #region Props ... - IXFileTagProvider TagProvider { get; } - IHubContext Hub { get; } - IXFileRepository FileRepository { get; } - IXStorageProvider StorageProvider { get; } - IXIdentityProvider IdentityProvider { get; } - XDataServiceConfiguration DataSercviceConfiguration { get; } - #endregion - - // - #region Helpers ... - /// - /// Converts an Entity to Dto ... - /// - /// - /// - Task ToDto(XFile model); - - /// - /// Convert a List of Entities to Dto ... - /// - /// - /// - Task> ToDtoList(IEnumerable list); - - /// - /// Converts an Entity Query Result to Dto ... - /// - /// - /// - Task> ToDtoQueryResult(XQueryResult queryResult); - #endregion - - // - #region Tags ... - /// - /// Attach Tag to Specified File ... - /// - /// - /// - /// - /// - /// - Task AttachTag( - Guid id, - string tag, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Detach Tag fro Specified File ... - /// - /// - /// - /// - /// - /// - Task DetachTag( - Guid id, - string tag, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Attach Tags for Specified File ... - /// - /// - /// - /// - /// - /// - Task AttachTags( - Guid id, - IEnumerable tags, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Detach Tags for Specified File ... - /// - /// - /// - /// - /// - /// - Task DetachTags( - Guid id, - IEnumerable tags, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Detach all Attached Tags for Specified File ... - /// - /// - /// - /// - /// - Task DetachTags( - Guid id, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Get Specified Model's Tag ... - /// - /// - /// - Task> GetTags(Guid id); - #endregion - - // - #region Tools ... - /// - /// Stream Specified File ... - /// - /// - /// - Task Stream(Guid id); - - /// - /// Stream Specified File ... - /// - /// - /// - Task Stream(string fileName); - - /// - /// Download Specified File ... - /// - /// - /// - Task Download(Guid id); - - /// - /// Download Specified File ... - /// - /// - /// - Task Download(string fileName); - - /// - /// Upload Files ... - /// - /// - /// - /// - /// - Task> Upload( - IFormFileCollection files, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Remove Specified Files ... - /// - /// - /// - /// - /// - Task> Remove( - string ids, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - Task GetFileDescriptor(Guid id); - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - Task GetFileDescriptor(string fileName); - #endregion - - // - #region Reference ... - /// - /// Get Reference Identifier for Specified Provider and Specified File ... - /// - /// - /// - /// - string GetIdentifier( - string providedFor, - TKey forProvidedId - ); - - /// - /// Check Specified File has Refernce to Provider ... - /// - /// - /// - /// - /// - Task IsProvidedFor( - string providedFor, - TKey forProvidedId, - Guid id - ); - - /// - /// Add Specified Reference to Specified File ... - /// - /// - /// - /// - /// - /// - /// - /// - Task AddReference( - string providedFor, - TKey forProvidedId, - Guid id, - int forIndex = 0, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// Remove Specified Reference from Specified File ... - /// - /// - /// - /// - /// - /// - /// - /// - Task RemoveReference( - string providedFor, - TKey forProvidedId, - Guid id, - int forIndex = 0, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - #endregion - - // - #region Data Model ... - /// - /// Get Specified File Model ... - /// - /// - /// - /// - Task Get( - Guid id - ); - - /// - /// Get All Exists File Models ... - /// - /// - /// - Task> GetAll(); - - /// - /// find an Entity by providing a Conditional Expression ... - /// - /// - Task FindOne(Expression> whereClause); - - /// - /// find a collection of Entities by proving a Conditional Expression ... - /// - /// - /// - Task> FindMany( - Expression> whereClause - ); - - /// - /// retrieve Entities based on XQuery Pagination structure ... - /// - /// - /// - Task> Query( - XQuery query - ); - - /// - /// retrieve Owned Entities based on XQuery Pagination structure ... - /// - /// - /// - /// - Task> QueryOwned( - XQuery query, - XUserClaimsInfoDto userInfo = null - ); - - /// - /// retrieve Entities based on XQuery Pagination structure by providing a Conditional Expression ... - /// - /// - /// - /// - Task> ConditionalQuery( - Expression> whereClause, - XQuery query - ); - - /// - /// retrieve Owned Entities based on XQuery Pagination structure by providing a Conditional Expression ... - /// - /// - /// - /// - /// - Task> ConditionalQueryOwned( - Expression> whereClause, - XQuery query, - XUserClaimsInfoDto userInfo = null - ); - - /// - /// Update an Entity values ... - /// - /// - /// - /// - /// - /// - Task Update( - Guid id, - XFileDto item, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// remove an Entity ... - /// - /// - /// - /// - /// - Task Remove( - Guid id, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ); - - /// - /// count all exists Entities ... - /// - /// - Task Count(); - - /// - /// Check an Entity exists or not ... - /// - /// - /// - Task IsExists( - Guid id - ); - #endregion - } + public interface IXFileProvider : IXBaseProvidedHasTag, IXBaseReferenced + {} } \ No newline at end of file diff --git a/Interfaces/IXFileProviderController.cs b/Interfaces/IXFileProviderController.cs new file mode 100644 index 0000000..0dd108a --- /dev/null +++ b/Interfaces/IXFileProviderController.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace xFileService.Interfaces +{ + public interface IXFileProviderController + { + + } +} \ No newline at end of file diff --git a/Interfaces/IXFileSeeder.cs b/Interfaces/IXFileSeeder.cs new file mode 100644 index 0000000..93d494a --- /dev/null +++ b/Interfaces/IXFileSeeder.cs @@ -0,0 +1,9 @@ +using System; +using xDataService.Interfaces; +using xFileService.Models.Entities; + +namespace xFileService.Interfaces +{ + public interface IXFileSeeder : IXBaseDbSeeder + { } +} \ No newline at end of file diff --git a/Interfaces/IXFileServiceControllerActions.cs b/Interfaces/IXFileServiceControllerActions.cs deleted file mode 100644 index 5cb7908..0000000 --- a/Interfaces/IXFileServiceControllerActions.cs +++ /dev/null @@ -1,181 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using xFileService.Models.Dtos; -using xModels.Dtos; -using XFileDto = xFileService.Models.Dtos.XFileDto; - -namespace xFileService.Interfaces -{ - public interface IXFileServiceControllerActions - { - // - #region Tags ... - /// - /// Attach Tag to Specified Model ... - /// - /// - /// - /// - Task AttachTag( - [FromRoute] Guid id, - [FromQuery] string tag - ); - - /// - /// Detach Tag From Specified Model ... - /// - /// - /// - /// - Task DetachTag( - [FromRoute] Guid id, - [FromQuery] string tag - ); - - /// - /// Attach Tags to Specified Model ... - /// - /// - /// - /// - Task AttachTags( - [FromRoute] Guid id, - [FromQuery] string tags - ); - - /// - /// Detach Tags From Specified Model ... - /// - /// - /// - /// - Task DetachTags( - [FromRoute] Guid id, - [FromQuery] string tags - ); - - /// - /// Retrieve Tags of Specified File ... - /// - /// - /// - Task>> GetTags( - [FromRoute] Guid id - ); - #endregion - - // - #region Tools ... - /// - /// Stream Specified File ... - /// - /// - /// - Task Stream( - [FromRoute] Guid id - ); - - /// - /// Stream Specified File ... - /// - /// - /// - Task Stream( - [FromRoute] string fileName - ); - - /// - /// Download Specified File ... - /// - /// - /// - Task Download( - [FromRoute] Guid id - ); - - /// - /// Download Specified File ... - /// - /// - /// - Task Download( - [FromRoute] string name - ); - - /// - /// Upload Files ... - /// - /// - /// - Task>> Upload( - [FromForm] IFormFileCollection files - ); - - /// - /// Remove Specified Files ... - /// - /// - /// - Task>> Remove( - [FromQuery] string ids - ); - #endregion - - // - #region Model ... - /// - /// Get Specified File Model ... - /// - /// - /// - /// - Task> Get( - [FromRoute] Guid id - ); - - /// - /// Get All Exists File Models ... - /// - /// - /// - Task>> GetAll(); - - /// - /// retrieve Entities based on XQuery Pagination structure ... - /// - /// - /// - Task>> Query( - [FromQuery] XQuery query - ); - - /// - /// retrieve Owned Entities based on XQuery Pagination structure ... - /// - /// - /// - Task>> QueryOwned( - [FromQuery] XQuery query - ); - - /// - /// count all exists Entities ... - /// - /// - Task> Count(); - - /// - /// Check an Entity exists or not ... - /// - /// - /// - Task> IsExists( - [FromRoute] Guid id - ); - #endregion - } -} \ No newline at end of file diff --git a/Models/Dtos/XFileDto.cs b/Models/Dtos/XFileDto.cs index 322b8b0..c0be460 100644 --- a/Models/Dtos/XFileDto.cs +++ b/Models/Dtos/XFileDto.cs @@ -1,16 +1,12 @@ using System; -using System.Collections.Generic; using xCommons.Constants; -using xDataService.Models; using xModels.Base; using xModels.Dtos; namespace xFileService.Models.Dtos { - public class XFileDto : XBaseDto + public class XFileDto : XBaseGuidIDEntityDto { - public Guid Id { get; set; } - public XFileType Type { get; set; } public string Name { get; set; } public string Thumb { get; set; } @@ -22,6 +18,6 @@ namespace xFileService.Models.Dtos public string OwnerId { get; set; } public XPersonDto Owner { get; set; } - public IList> References = new List>(); + public string References { get; set; } } } \ No newline at end of file diff --git a/Providers/Dtos/XFileDtoHub.cs b/Providers/Dtos/XFileDtoHub.cs new file mode 100644 index 0000000..e7ded08 --- /dev/null +++ b/Providers/Dtos/XFileDtoHub.cs @@ -0,0 +1,17 @@ +using System; +using Microsoft.Extensions.Logging; +using xFileService.Interfaces.Dtos; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; +using xPushService.Base; + +namespace xFileService.Providers.Dtos +{ + public class XFileDtoHub : XBaseDtoHub, IXFileDtoHub + { + public XFileDtoHub( + ILogger logger + ) : base(logger) + { } + } +} \ No newline at end of file diff --git a/Providers/Dtos/XFileRepositoryService.cs b/Providers/Dtos/XFileRepositoryService.cs new file mode 100644 index 0000000..5c6ca2f --- /dev/null +++ b/Providers/Dtos/XFileRepositoryService.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using AutoMapper; +using xDataService.Providers; +using xFileService.Interfaces.Dtos; +using xFileService.Interfaces.Entities; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; + +namespace xFileService.Providers.Dtos +{ + public class XFileRepositoryService : XBaseRepositoryService, IXFileRepositoryService + { + public XFileRepositoryService( + IXFileRepository repository, + IEnumerable mapperProfiles = null + ) : base( + repository, + mapperProfiles + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Dtos/XFileServiceProvider.cs b/Providers/Dtos/XFileServiceProvider.cs new file mode 100644 index 0000000..a89c0a6 --- /dev/null +++ b/Providers/Dtos/XFileServiceProvider.cs @@ -0,0 +1,27 @@ +using System; +using Microsoft.AspNetCore.SignalR; +using xDataService.Configuration; +using xFileService.Interfaces.Dtos; +using xFileService.Models.Dtos; +using xFileService.Models.Entities; +using xIdentityService.Interfaces; +using xPushService.Base; + +namespace xFileService.Providers.Dtos +{ + public class XFileServiceProvider : XBaseDtoProvider, IXFileServiceProvider + { + public XFileServiceProvider( + IHubContext hub, + XDataServiceConfiguration dataConfiguration, + IXFileRepositoryService service, + IXIdentityProvider identityProvider = null + ) : base( + hub, + dataConfiguration, + service, + identityProvider + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XFileEFRepository.cs b/Providers/Entities/XFileEFRepository.cs new file mode 100644 index 0000000..e5edccd --- /dev/null +++ b/Providers/Entities/XFileEFRepository.cs @@ -0,0 +1,27 @@ +using System; +using xDataService.Configuration; +using xDataService.Db; +using xDataService.Interfaces; +using xDataService.Providers; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Providers.Entities +{ + public class XFileEFRepository : XBaseEFRepository, IXFileRepository + where TContext : XDbContext + { + public XFileEFRepository( + IXUnitOfWorks unitOfWorks, + XDataServiceConfiguration configuration, + IXFileKeyGenerator keyGenerator = null, + IXFileRepositoryEvents baseRepositoryEvents = null + ) : base( + unitOfWorks, + configuration, + keyGenerator, + baseRepositoryEvents + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XFileEntityHub.cs b/Providers/Entities/XFileEntityHub.cs new file mode 100644 index 0000000..a9bed0f --- /dev/null +++ b/Providers/Entities/XFileEntityHub.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.Extensions.Logging; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; +using xPushService.Base; + +namespace xFileService.Providers.Entities +{ + public class XFileEntityHub : XBaseEntityHub, IXFileEntityHub + { + public XFileEntityHub( + ILogger logger + ) : base(logger) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XFileInMemoryRepository.cs b/Providers/Entities/XFileInMemoryRepository.cs new file mode 100644 index 0000000..ee3651c --- /dev/null +++ b/Providers/Entities/XFileInMemoryRepository.cs @@ -0,0 +1,22 @@ +using System; +using xDataService.Configuration; +using xDataService.Providers; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Providers.Entities +{ + public class XFileInMemoryRepository : XBaseInMemoryRepository, IXFileRepository + { + public XFileInMemoryRepository( + XDataServiceConfiguration configuration, + IXFileKeyGenerator keyGenerator = null, + IXFileRepositoryEvents baseRepositoryEvents = null + ) : base( + configuration, + keyGenerator, + baseRepositoryEvents + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XFileKeyGenerator.cs b/Providers/Entities/XFileKeyGenerator.cs new file mode 100644 index 0000000..c964025 --- /dev/null +++ b/Providers/Entities/XFileKeyGenerator.cs @@ -0,0 +1,9 @@ +using xDataService.Providers; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Providers.Entities +{ + public class XFileKeyGenerator : XGuidKeyGenerator, IXFileKeyGenerator + { } +} \ No newline at end of file diff --git a/Providers/Entities/XFileMongoRepository.cs b/Providers/Entities/XFileMongoRepository.cs new file mode 100644 index 0000000..a6317b5 --- /dev/null +++ b/Providers/Entities/XFileMongoRepository.cs @@ -0,0 +1,26 @@ +using System; +using xDataService.Configuration; +using xDataService.Providers; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Providers.Entities +{ + public class XFileMongoRepository : XBaseMongoRepository, IXFileRepository + { + public XFileMongoRepository( + XDataBaseConfiguration dbConfiguration, + XDataServiceConfiguration configuration, + string collectionName = null, + IXFileKeyGenerator keyGenerator = null, + IXFileRepositoryEvents baseRepositoryEvents = null + ) : base( + dbConfiguration, + configuration, + collectionName, + keyGenerator, + baseRepositoryEvents + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XFileRepositoryEvents.cs b/Providers/Entities/XFileRepositoryEvents.cs new file mode 100644 index 0000000..c5c126f --- /dev/null +++ b/Providers/Entities/XFileRepositoryEvents.cs @@ -0,0 +1,9 @@ +using xDataService.Providers; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Providers.Entities +{ + public class XFileRepositoryEvents : XBaseRepositoryEvents, IXFileRepositoryEvents + { } +} \ No newline at end of file diff --git a/Providers/Entities/XFileRepositoryProvider.cs b/Providers/Entities/XFileRepositoryProvider.cs new file mode 100644 index 0000000..5278a96 --- /dev/null +++ b/Providers/Entities/XFileRepositoryProvider.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.AspNetCore.SignalR; +using xDataService.Configuration; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; +using xIdentityService.Interfaces; +using xPushService.Base; + +namespace xFileService.Providers.Entities +{ + public class XFileRepositoryProvider : XBaseEntityProvider, IXFileRepositoryProvider + { + public XFileRepositoryProvider( + IHubContext hub, + IXFileRepository repository, + XDataServiceConfiguration dataConfiguration, + IXIdentityProvider identityProvider = null + ) : base( + hub, + repository, + dataConfiguration, + identityProvider + ) + { } + } +} \ No newline at end of file diff --git a/DataHelper/GraphQL/XFileGraphQLTypeHelper.cs b/Providers/GraphQL/XFileGraphQLTypeHelper.cs similarity index 93% rename from DataHelper/GraphQL/XFileGraphQLTypeHelper.cs rename to Providers/GraphQL/XFileGraphQLTypeHelper.cs index 1a7122c..2454d2f 100644 --- a/DataHelper/GraphQL/XFileGraphQLTypeHelper.cs +++ b/Providers/GraphQL/XFileGraphQLTypeHelper.cs @@ -4,7 +4,7 @@ using xDataService.GraphQL; using xFileService.Interfaces.Entities; using xFileService.Models.Entities; -namespace xFileService.DataHelper.GraphQL +namespace xFileService.Providers.GraphQL { public class XFileGraphQLTypeHelper : XBaseGraphQLTypeHelper, IXFileGraphQLTypeHelper { diff --git a/DataHelper/GraphQL/XFileGraphQuery.cs b/Providers/GraphQL/XFileGraphQuery.cs similarity index 93% rename from DataHelper/GraphQL/XFileGraphQuery.cs rename to Providers/GraphQL/XFileGraphQuery.cs index e89f05e..5c7074f 100644 --- a/DataHelper/GraphQL/XFileGraphQuery.cs +++ b/Providers/GraphQL/XFileGraphQuery.cs @@ -5,7 +5,7 @@ using xDataService.GraphQL; using xFileService.Interfaces.Entities; using xFileService.Models.Entities; -namespace xFileService.DataHelper.GraphQL +namespace xFileService.Providers.GraphQL { public class XFileGraphQuery : XBaseGraphQLQuery { diff --git a/DataHelper/GraphQL/XFileGraphSchema.cs b/Providers/GraphQL/XFileGraphSchema.cs similarity index 86% rename from DataHelper/GraphQL/XFileGraphSchema.cs rename to Providers/GraphQL/XFileGraphSchema.cs index 8231c53..033bd80 100644 --- a/DataHelper/GraphQL/XFileGraphSchema.cs +++ b/Providers/GraphQL/XFileGraphSchema.cs @@ -1,7 +1,7 @@ using System; using GraphQL.Types; -namespace xFileService.DataHelper.GraphQL +namespace xFileService.Providers.GraphQL { public class XFileGraphSchema : Schema { @@ -9,5 +9,6 @@ namespace xFileService.DataHelper.GraphQL { Query = (XFileGraphQuery)services.GetService(typeof(XFileGraphQuery)); } + } } \ No newline at end of file diff --git a/DataHelper/GraphQL/XFileGraphType.cs b/Providers/GraphQL/XFileGraphType.cs similarity index 86% rename from DataHelper/GraphQL/XFileGraphType.cs rename to Providers/GraphQL/XFileGraphType.cs index 7d81a9a..0e3ac90 100644 --- a/DataHelper/GraphQL/XFileGraphType.cs +++ b/Providers/GraphQL/XFileGraphType.cs @@ -2,20 +2,21 @@ using System; using xDataService.GraphQL; using xFileService.Models.Entities; -namespace xFileService.DataHelper.GraphQL +namespace xFileService.Providers.GraphQL { public class XFileGraphType : XBaseGraphObjectType { public XFileGraphType() : base() { Field(x => x.Type); - Field(x => x.OwnerId); Field(x => x.Name); Field(x => x.Path); Field(x => x.Thumb); + Field(x => x.OwnerId); + Field(x => x.FileName); Field(x => x.ThumbPath); Field(x => x.UploadedOn); - Field(x => x.FileName); + Field(x => x.References); } } } \ No newline at end of file diff --git a/Providers/XBaseFileProvider.cs b/Providers/XBaseFileProvider.cs deleted file mode 100644 index a9520b2..0000000 --- a/Providers/XBaseFileProvider.cs +++ /dev/null @@ -1,1011 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using xCommons.Extensions; -using xDataService.Extensions; -using xDataService.Models; -using xExceptions.Constants; -using xFileService.Interfaces; -using xFileService.Models.Dtos; -using xIdentityModels.Models; -using xModels.Dtos; -using XFileDto = xFileService.Models.Dtos.XFileDto; - -namespace xFileService.Providers -{ - public abstract class XBaseFileProvider : IXBaseFileProvider - { - // - #region Props ... - /// - /// Provider Identifier ... - /// - public string Provider { get; } - - /// - /// Tag Provider for Maipulating Tags ... - /// - public IXFileProvider FileProvider { get; } - #endregion - - // - #region Constructor ... - public XBaseFileProvider( - string providedFor, - IXFileProvider fileProvider - ) - { - // - Provider = providedFor; - FileProvider = fileProvider; - } - #endregion - - // - #region Tools ... - /// - /// Stream Specified File ... - /// - /// - /// - public async Task Stream(Guid id) - { - // - // Check Validation and Owning ... - var isValid = await IsOwned(id); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var result = await FileProvider.Stream(id); - return result; - } - - /// - /// Stream Specified File ... - /// - /// - /// - public async Task Stream(string fileName) - { - // - // Validate ... - var isValid = !fileName.IsNullOrEmpty(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Retrieve Dto and also Checking Owned ... - var dto = await GetDto(fileName); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var result = await FileProvider.Stream(fileName); - return result; - } - - /// - /// Download Specified File ... - /// - /// - /// - public async Task Download(Guid id) - { - // - // Validate ... - var isValid = await IsOwned(id); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var result = await FileProvider.Download(id); - return result; - } - - /// - /// Download Specified File ... - /// - /// - /// - public async Task Download(string fileName) - { - // - // Validate ... - var isValid = !fileName.IsNullOrEmpty(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Retrieve Dto and also Checking Owned ... - var dto = await GetDto(fileName); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var result = await FileProvider.Download(fileName); - return result; - } - - /// - /// Upload Files ... - /// - /// - /// - /// - /// - /// - public async Task> Upload( - TKey providedForId, - IFormFileCollection files, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ) - { - // - // Validate ... - var isValid = !providedForId.IsNull(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Here we are Following Custom Senario ... - var dtos = await FileProvider.Upload( - files: files, - userInfo: userInfo, - connectionId: connectionId - ); - - // - // Validate Dtos ... - isValid = !dtos.IsNull() && dtos.HasChild(); - if (isValid) - { - // - var isReferenced = false; - foreach (var dto in dtos) - { - // - // Try to Add Reference to Specified DTO ... - isReferenced = await AddReference( - model: dto, - userInfo: userInfo, - connectionId: connectionId, - providedForId: providedForId - ); - } - } - - // - var result = new List(); - - // - isValid = !dtos.IsNull() && dtos.HasChild(); - if (isValid) - { - // - foreach (var dto in dtos) - { - // - var idto = await FileProvider.Get(dto.Id); - isValid = !idto.IsNullOrDefault() && - await IsOwned(idto.Id); - if (isValid) - { - result.Add(idto); - } - } - } - - // - return result; - } - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - public async Task GetFileDescriptor(Guid id) - { - // - // Validate ... - var isValid = !id.IsNull() && !id.IsDefaultGuid(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Owned ... - isValid = await IsOwned(id); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var result = await FileProvider.GetFileDescriptor(id); - return result; - } - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - public async Task GetFileDescriptor(string fileName) - { - // - // Validate ... - var isValid = !fileName.IsNullOrEmpty(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Owned ... - var dto = GetDto(fileName); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var result = await FileProvider.GetFileDescriptor(fileName); - return result; - } - #endregion - - // - #region Referenced Actions ... - /// - /// Get Specified Indexed Reference for Specific Provided ID ... - /// - /// - /// - /// - public async Task GetReference( - TKey providedForId, - int forIndex = 0 - ) - { - // - // Validate ... - if (providedForId.IsNull()) - { - XException.InvalidArgs.Throw(); - } - - // - // Normalize ... - if (forIndex < 0) - { - forIndex = 0; - } - - // - // Retrieve Last Index ... - var maxIndex = (await GetReferencingIndexes(providedForId)).Max(); - if (forIndex > maxIndex) - { - XException.NotFound.Throw(); - } - - // - var indexedIdentifier = GetIndexedProvidedID( - forIndex: forIndex, - providedForId: providedForId - ); - var entity = FileProvider.FileRepository - .AsQueryable() - .Where(t => t.References.Contains(indexedIdentifier)) - .FirstOrDefault(); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - var result = await FileProvider.ToDto(entity); - return result; - } - - /// - /// Retrieve all Exists References of Specific Provided ID ... - /// - /// - /// - public async Task> GetAllReferences(TKey providedForId) - { - // - // Validate ... - if (providedForId.IsNull()) - { - XException.InvalidArgs.Throw(); - } - - // - var identifier = GetProvidedID(providedForId); - var entities = FileProvider.FileRepository - .AsQueryable() - .Where(t => t.References.Contains(identifier)) - .AsEnumerable(); - - // - var result = new List(); - foreach (var entity in entities) - { - // - var dto = await FileProvider.ToDto(entity); - if (!dto.IsNullOrDefault()) - { - result.Add(dto); - } - } - - // - return await Task.FromResult(result); - } - - /// - /// Extract all Referencing Models for Specified Key ... - /// - /// - /// - public async Task>> GetAllReferencings(TKey providedForId) - { - // - // Validate ... - var isValid = - !providedForId.IsNull(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - var identifier = GetProvidedID(providedForId); - - // - var result = FileProvider.FileRepository - .AsQueryable() - .Where(te => te.References.Contains(identifier)) - .Select(te => te.References) - .ToList() - .SelectMany(tr => tr.ParseXReferenceList()) - .Where(tr => tr.ProvidedFor == Provider && $"{tr.ReferencedTo}" == $"{providedForId}") - .OrderBy(tr => tr.Index) - .AsEnumerable() - ; - - // - return await Task.FromResult(result); - } - - /// - /// Count References ... - /// - /// - /// - public async Task CountReferences(TKey providedForId) - { - // - // Validate ... - if (providedForId.IsNull()) - { - XException.InvalidArgs.Throw(); - } - - // - var identifier = GetProvidedID(providedForId); - var result = FileProvider.FileRepository - .AsQueryable() - .Where(t => t.References.Contains(identifier)) - .Count(); - - // - return await Task.FromResult(result); - } - - /// - /// Retrieve References of Specific Provided ID as Query ... - /// - /// - /// - public async Task> QueryReferences( - XQuery query, - TKey providedForId - ) - { - // - // Validate ... - if (query.IsNull() || providedForId.IsNull()) - { - XException.InvalidArgs.Throw(); - } - - // - // Normalize ... - query = query.NormalizeQuery(FileProvider.DataSercviceConfiguration); - - // - var items = await GetAllReferences(providedForId); - var totalItemsCount = items.Count(); - - // - // Apply Filter ... - if (!query.Filter.IsNullOrEmpty()) - { - // - items = items - .ApplyFilter(query.Filter); - } - int filteredItemsCount = items.Count(); - - // - // Count Pages ... - var totalPagesCount = query.CountPages(totalItemsCount); - var filteredPagesCount = query.CountPages(filteredItemsCount); - - // - // Apply Paging and Sorting ... - if (totalItemsCount > 0 && - filteredItemsCount > 0) - { - // - // Apply Sorting ... - items = items - .ToList() - .ApplySorting( - query.SortBy, - query.IsAscending - ); - - // - // Apply Paging ... - items = items - .ToList() - .ApplyPaging( - query.Page, - query.PageSize - ); - } - - // - // Prepare Result ... - var result = new XQueryResult - { - Page = query.Page, - Items = items.ToList(), - PageSize = query.PageSize, - TotalPages = totalPagesCount, - TotalItems = totalItemsCount, - TotalFilteredPages = filteredPagesCount, - TotalFilteredItems = filteredItemsCount - }; - - // - return result; - } - - /// - /// Add Reference a Model to Specific Provided ID ... - /// - /// - /// - /// - /// - /// - /// - public async Task AddReference( - XFileDto model, - TKey providedForId, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ) - { - // - var result = false; - - // - // Validate ... - result = - !model.Id.IsNull() && - !providedForId.IsNull() && - !model.IsNullOrDefault() && - !model.Id.IsDefaultGuid() && - !model.Name.IsNullOrEmpty(); - if (!result) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Model Exists ... - result = await FileProvider.IsExists(model.Id); - if (!result) - { - XException.NotFound.Throw(); - } - - // - // Update Model by Retrieving ... - model = await FileProvider.Get(model.Id); - - // - // Retrieve all References ... - var references = await GetAllReferences(providedForId); - - // - // Check isReferenced or not ... - result = references.Any(r => r.Id == model.Id && - r.References.Any(rf => rf.ProvidedFor == Provider && - rf.ReferencedTo == $"{providedForId}")); - if (result) - { - return result; - } - - // - int forIndex = await CountReferences(providedForId); - model.References.Add(new XReference - { - Index = forIndex, - ProvidedFor = Provider, - ReferencedTo = $"{providedForId}" - }); - - // - // Update Data Base ... - model = await FileProvider - .Update( - item: model, - id: model.Id, - userInfo: userInfo, - connectionId: connectionId - ); - result = !model.IsNullOrDefault(); - - // - return result; - } - - /// - /// Add Reference a Model to Specific XRefence ... - /// - /// - /// - /// - /// - /// - public async Task AddReference( - XFileDto model, - XReference reference, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ) - { - // - // Validate ... - // Since other Validations Handled in Calling, we Ignore them here ... - var result = - !model.IsNullOrDefault() && - !model.Id.IsNull() && - !model.Id.IsDefaultGuid() && - !reference.IsNullOrDefault() && - !reference.ReferencedTo.IsNull() && - reference.ProvidedFor == Provider && - !reference.ProvidedFor.IsNullOrEmpty(); - if (!result) - { - XException.InvalidArgs.Throw(); - } - - // - result = await AddReference( - model: model, - userInfo: userInfo, - connectionId: connectionId, - providedForId: reference.ReferencedTo - ); - - // - return result; - } - - /// - /// Remove Reference a Model for Specific Provided ID ... - /// - /// - /// - /// if null, removes all - /// - /// - /// - public async Task RemoveReference( - XFileDto model, - TKey providedForId, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ) - { - // - // Validate ... - var result = - !model.Id.IsNull() && - !providedForId.IsNull() && - !model.IsNullOrDefault() && - !model.Id.IsDefaultGuid(); - if (!result) - { - XException.InvalidArgs.Throw(); - } - - // - // Retrieve Model ... - model = await FileProvider.Get(model.Id); - if (model.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - // Reading Referencing Indexes ... - var indexes = await GetReferencingIndexes(providedForId); - - // - // Check Model Reference to ID ... - var referencesCount = await CountReferences(providedForId); - result = referencesCount == 0; - if (result) - { - // - // There is not any Reference to Remove ... - return result; - } - - // - // Check Model is Trully Referenced to ProvidedForId or not ... - var reference = model.References - .FirstOrDefault(r => r.ProvidedFor == Provider && - r.ReferencedTo == $"{providedForId}"); - result = !reference.IsNullOrDefault(); - if (!result) - { - XException.ActionFailed.Throw(); - } - - // - // Remove Referenced Item from Model ... - model.References = model.References - .Where(r => !(r.ProvidedFor == Provider && - r.ReferencedTo == $"{providedForId}")) - .ToList(); - - // - // Update DataBase ... - model = await FileProvider.Update( - id: model.Id, - item: model, - userInfo: userInfo, - connectionId: connectionId - ); - - // - result = !model.IsNullOrDefault(); - if (!result) - { - XException.ActionFailed.Throw(); - } - - // - // Get Max Exists Indexes ... - var maxIndex = indexes.Max(); - - // - // Here We Have to Re Arrange Indexed ... - if (reference.Index < maxIndex) - { - // - var startIndex = reference.Index + 1; - for (int i = startIndex; i <= maxIndex; i++) - { - // - var dto = await GetReference( - forIndex: i, - providedForId: providedForId - ); - if (!dto.IsNullOrDefault()) - { - // - dto.References - .ToList() - .ForEach(iref => - { - // - if ( - iref.Index == i && - iref.ProvidedFor == Provider && - iref.ReferencedTo == reference.ReferencedTo - ) - { - iref.Index = i - 1; - } - }); - - // - dto = await FileProvider.Update( - item: dto, - id: dto.Id, - userInfo: userInfo, - connectionId: connectionId - ); - } - } - } - - // - return result; - } - - /// - /// Remove Reference a Model for Specific XRefence ... - /// - /// - /// - /// - /// - /// - public async Task RemoveReference( - XFileDto model, - XReference reference, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ) - { - // - if (model.IsNullOrDefault() || - reference.IsNullOrDefault() || - reference.ReferencedTo.IsNull() || - reference.ProvidedFor != Provider) - { - XException.InvalidArgs.Throw(); - } - - // - var result = await RemoveReference( - model: model, - userInfo: userInfo, - connectionId: connectionId, - providedForId: reference.ReferencedTo - ); - - // - return result; - } - - /// - /// Remove All References to Specified Key ... - /// - /// - /// - /// - /// - public async Task RemoveReferences( - TKey providedForId, - string connectionId = null, - XUserClaimsInfoDto userInfo = null - ) - { - // - // Validate ... - if (providedForId.IsNull()) - { - XException.InvalidArgs.Throw(); - } - - // - var result = false; - var references = await GetAllReferences(providedForId); - if (!references.IsNull() && references.HasChild()) - { - // - foreach (var reference in references) - { - // - // Remove Reference ... - reference.References = reference.References - .Where(r => - r.ProvidedFor != Provider || - (r.ProvidedFor == Provider && - r.ReferencedTo != $"{providedForId}")) - .ToList(); - var updatedModel = await FileProvider.Update( - item: reference, - id: reference.Id, - userInfo: userInfo, - connectionId: connectionId - ); - if (!updatedModel.IsNullOrDefault()) - { - result = true; - } - } - } - - // - return result; - } - #endregion - - // - #region Private ... - private string GetProvidedID( - TKey providedForId, - char splitter = '_' - ) - { - // - // Validate ... - if (providedForId.IsNull()) - { - XException.InvalidArgs.Throw(); - } - - // - var result = $"{Provider}{splitter}{providedForId}"; - return result; - } - - private string GetIndexedProvidedID( - TKey providedForId, - int forIndex, - char splitter = '_' - ) - { - // - var result = $"{GetProvidedID(providedForId, splitter)}{splitter}{forIndex}"; - - // - return result; - } - - private async Task> GetReferencingIndexes(TKey providedForId) - { - // - // Validate ... - var isValid = - !providedForId.IsNull(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - var result = new List(); - var referencings = await GetAllReferencings(providedForId); - isValid = !referencings.IsNull() && - referencings.HasChild(); - if (!isValid) - { - return result; - } - - // - result = - referencings - .OrderBy(r => r.Index) - .Select(r => r.Index) - .ToList(); - - // - return result; - } - - /// - /// Check Specified Dto is Has Reference to Provider ... - /// - /// - /// - private async Task IsOwned(Guid id) - { - // - // Validate ... - var result = !id.IsNull() && !id.IsDefaultGuid(); - if (!result) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Exists ... - result = await FileProvider.IsExists(id); - if (!result) - { - XException.NotFound.Throw(); - } - - // - // Retrieve Dto ... - var dto = await FileProvider.Get(id); - result = !dto.IsNullOrDefault(); - if (!result) - { - XException.ActionFailed.Throw(); - } - - // - result = !dto.References.IsNull() && - dto.References.HasChild() && - dto.References.Any(r => r.ProvidedFor == Provider); - - // - return result; - } - - /// - /// Get Specified Owned Dto by File Name ... - /// - /// - /// - private async Task GetDto(string fileName) - { - // - XFileDto result = null; - - // - if (!fileName.IsNullOrEmpty()) - { - // - try - { - // - result = await FileProvider.FindOne(d => - d.Name == fileName || - d.Thumb == fileName || - d.FileName == fileName || - d.Path.Contains(fileName) || - d.ThumbPath.Contains(fileName) - ); - if (!result.IsNullOrDefault()) - { - // - // Check Owning ... - var isOwned = await IsOwned(result.Id); - if (!isOwned) - { - result = null; - } - } - } - catch { } - } - - // - return result; - } - #endregion - } -} \ No newline at end of file diff --git a/Providers/XFileEntityRegisterar.cs b/Providers/XFileEntityRegisterar.cs new file mode 100644 index 0000000..2b287df --- /dev/null +++ b/Providers/XFileEntityRegisterar.cs @@ -0,0 +1,28 @@ +using System; +using Microsoft.EntityFrameworkCore; +using xDataService.Interfaces; +using xDataService.Providers; +using xFileService.Models.Entities; + +namespace xFileService.Providers +{ + public class XFileEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar + { + public XFileEntityRegisterar() + : base(nameof(XFileEntityRegisterar)) + { + // + // Add XFile Entity ... + AddEntity(); + } + + /// + /// Configure Entities ... + /// + /// + public override void ConfigureEntities(ModelBuilder modelBuilder) + { + base.ConfigureEntities(modelBuilder); + } + } +} \ No newline at end of file diff --git a/Providers/XFileProvider.cs b/Providers/XFileProvider.cs index 2533d4c..de594ba 100644 --- a/Providers/XFileProvider.cs +++ b/Providers/XFileProvider.cs @@ -1,1028 +1,69 @@ using System; -using System.Collections.Generic; -using System.Linq.Expressions; +using System.Linq; +using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SignalR; using xCommons.Extensions; -using xDataService.Configuration; +using xDataService.Models; using xExceptions.Constants; using xFileService.Extensions; -using xFileService.Hubs; using xFileService.Interfaces; -using xFileService.Interfaces.Entities; +using xFileService.Interfaces.Dtos; using xFileService.Models.Dtos; using xFileService.Models.Entities; +using xFileService.Providers.Dtos; using xIdentityModels.Models; -using xIdentityService.Interfaces; -using xModels.Dtos; -using xIdentityService.Extensions; -using XFileDto = xFileService.Models.Dtos.XFileDto; -using xStorageService.Interfaces; -using System.IO; -using Microsoft.Extensions.FileProviders; -using Microsoft.AspNetCore.StaticFiles; -using System.Linq; -using xPushService.Constants; -using xDataService.Models; +using xTagService.Providers; namespace xFileService.Providers { - public class XFileProvider : IXFileProvider + public class XFileProvider : XBaseProvidedHasTag, IXFileProvider { - // - #region Props ... - public IXFileTagProvider TagProvider { get; } - public IHubContext Hub { get; } - public IXFileRepository FileRepository { get; } - public IXStorageProvider StorageProvider { get; } - public IXIdentityProvider IdentityProvider { get; } - public XDataServiceConfiguration DataSercviceConfiguration { get; } - #endregion - - // - #region Constructor ... public XFileProvider( IXFileTagProvider tagProvider, - IXFileRepository fileRepository, - IXStorageProvider storageProvider, - IXIdentityProvider identityProvider, - XDataServiceConfiguration dataSercviceConfiguration, - IHubContext hub = null + IXFileServiceProvider provider + ) : base( + provider: provider, + tagProvider: tagProvider, + permittedRoles: new string[] { "admin" } + ) + { } + + public override bool IsOwned( + XFile item, + XUserClaimsInfoDto userInfo ) { // - Hub = hub; - TagProvider = tagProvider; - FileRepository = fileRepository; - StorageProvider = storageProvider; - IdentityProvider = identityProvider; - DataSercviceConfiguration = dataSercviceConfiguration; + var result = + !item.IsNullOrDefault() && + !userInfo.IsNullOrDefault() && + !item.OwnerId.IsNullOrEmpty() && + userInfo.UserId == item.OwnerId; + + // + return result; + } + + public override bool IsOwned( + XFileDto item, + XUserClaimsInfoDto userInfo + ) + { + // + var result = + !item.IsNullOrDefault() && + !userInfo.IsNullOrDefault() && + !item.OwnerId.IsNullOrEmpty() && + userInfo.UserId == item.OwnerId; + + // + return result; } - #endregion // - #region Helpers ... + #region Referenced Actions ... /// - /// Converts an Entity to Dto ... - /// - /// - /// - public async Task ToDto(XFile model) - { - // - XFileDto result = null; - - // - if (!model.IsNullOrDefault()) - { - // - result = model.ToDto(); - - // - // Prepare Inner API Providers Device Dto ... - var device = IdentityProvider.GetDevice(); - var userInfo = await IdentityProvider.GetUserInfo( - device: device, - userSelectByParam: model.OwnerId - ); - if (userInfo.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - result.Owner = userInfo.ToXPersonDto(); - } - - // - return result; - } - - /// - /// Convert a List of Entities to Dto ... - /// - /// - /// - public async Task> ToDtoList(IEnumerable list) - { - // - var result = new List(); - - // - if (!list.IsNull() && list.HasChild()) - { - // - foreach (var item in list) - { - // - var dto = await ToDto(item); - if (!dto.IsNullOrDefault()) - { - result.Add(dto); - } - } - } - - // - return result; - } - - /// - /// Converts an Entity Query Result to Dto ... - /// - /// - /// - public async Task> ToDtoQueryResult(XQueryResult queryResult) - { - // - var result = new XQueryResult(); - - // - if (!queryResult.IsNullOrDefault()) - { - // - result.Page = queryResult.Page; - result.PageSize = queryResult.PageSize; - result.TotalItems = queryResult.TotalItems; - result.TotalPages = queryResult.TotalPages; - result.TotalFilteredItems = queryResult.TotalFilteredItems; - result.TotalFilteredPages = queryResult.TotalFilteredPages; - - // - if (!queryResult.Items.IsNull() && queryResult.Items.HasChild()) - { - result.Items = await ToDtoList(queryResult.Items); - } - else - { - result.Items = new List(); - } - } - - // - return result; - } - - /// - /// Check Specified User Info Has Permissions for Specified File ... - /// - /// - /// - /// - private async Task HasPermission( - Guid id, - XUserClaimsInfoDto userInfo = null - ) - { - // - var result = false; - - // - // Validate ... - result = !id.IsNull() && - !id.IsDefaultGuid() && - !userInfo.IsNullOrDefault(); - if (!result) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Item Exists ... - result = await IsExists(id); - if (!result) - { - XException.NotFound.Throw(); - } - - // - // Retrieve Dto ... - var dto = await Get(id); - result = !dto.IsNullOrDefault(); - if (!result) - { - XException.ActionFailed.Throw(); - } - - // - result = - dto.OwnerId == userInfo.UserId || - userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - - // - return result; - } - #endregion - - // - #region Tags ... - /// - /// Attach Tag to Specified File ... - /// - /// - /// - /// - /// - /// - public async Task AttachTag( - Guid id, - string tag, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - var isValid = !tag.IsNullOrEmpty() && - !id.IsNull() && - !id.IsDefaultGuid() && - !userInfo.IsNullOrDefault(); - if (isValid) - { - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - try - { - // - await TagProvider.AddReference( - tag: tag, - providedForId: id, - connectionId: connectionId - ); - } - catch { } - } - } - - /// - /// Detach Tag fro Specified File ... - /// - /// - /// - /// - /// - /// - public async Task DetachTag( - Guid id, - string tag, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - var isValid = !tag.IsNullOrEmpty() && - !id.IsNull() && - !id.IsDefaultGuid(); - if (isValid) - { - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - try - { - // - await TagProvider.RemoveReference( - tag: tag, - providedForId: id, - connectionId: connectionId - ); - } - catch { } - } - } - - /// - /// Attach Tags for Specified File ... - /// - /// - /// - /// - /// - /// - public async Task AttachTags( - Guid id, - IEnumerable tags, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - var isValid = !tags.IsNull() && - tags.HasChild() && - !id.IsNull() && - !id.IsDefaultGuid(); - if (isValid) - { - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - try - { - // - foreach (var tag in tags) - { - // - await AttachTag( - id: id, - tag: tag, - userInfo: userInfo, - connectionId: connectionId - ); - } - } - catch { } - } - } - - /// - /// Detach Tags for Specified File ... - /// - /// - /// - /// - /// - /// - public async Task DetachTags( - Guid id, - IEnumerable tags, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - var isValid = !tags.IsNull() && - tags.HasChild() && - !id.IsNull() && - !id.IsDefaultGuid(); - if (isValid) - { - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - try - { - // - foreach (var tag in tags) - { - // - await DetachTag( - id: id, - tag: tag, - userInfo: userInfo, - connectionId: connectionId - ); - } - } - catch { } - } - } - - /// - /// Detach all Attached Tags for Specified File ... - /// - /// - /// - /// - /// - public async Task DetachTags( - Guid id, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - var isValid = !id.IsNull() && !id.IsDefaultGuid(); - if (isValid) - { - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - try - { - // - await TagProvider.RemoveReferences( - providedForId: id, - connectionId: connectionId - ); - } - catch { } - } - } - - /// - /// Get Specified Model's Tag ... - /// - /// - /// - public async Task> GetTags(Guid id) - { - // - // Validate ... - var isValid = !id.IsNull() && - !id.IsDefaultGuid(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Model Exists ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - var tags = await TagProvider.GetAllReferences(id); - - // - var result = new List(); - isValid = !tags.IsNull() && tags.HasChild(); - if (isValid) - { - // - result = tags.Select(t => t.Tag) - .ToList(); - } - - // - return result; - } - #endregion - - // - #region Tools ... - /// - /// Stream Specified File ... - /// - /// - /// - public async Task Stream(Guid id) - { - // - // Validate Args ... - var isValid = !id.IsNull() && - !id.IsDefaultGuid(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Generate Stream Info and Validate it ... - var stream = await GetFileDescriptor(id); - if (stream.IsNull()) - { - XException.NotFound.Throw(); - } - - // - // Generate Result Model ... - var result = new FileStreamResult( - stream.Stream, - stream.MIMEType - ) - { - FileDownloadName = stream.Name - }; - - // - return result; - } - - /// - /// Stream Specified File ... - /// - /// - /// - public async Task Stream(string fileName) - { - // - // Validate Args ... - var isValid = !fileName.IsNullOrEmpty(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Generate Stream Info and Validate it ... - var stream = await GetFileDescriptor(fileName); - if (stream.IsNull()) - { - XException.NotFound.Throw(); - } - - // - // Generate Result Model ... - var result = new FileStreamResult( - stream.Stream, - stream.MIMEType - ) - { - FileDownloadName = stream.Name - }; - - // - return result; - } - - /// - /// Download Specified File ... - /// - /// - /// - public async Task Download(Guid id) - { - // - // Validate Args ... - var isValid = !id.IsNull() && - !id.IsDefaultGuid(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Generate Stream Info and Validate it ... - var stream = await GetFileDescriptor(id); - if (stream.IsNull()) - { - XException.NotFound.Throw(); - } - - // - // Generate Result Model ... - var result = new PhysicalFileResult( - stream.Path, - stream.MIMEType - ) - { - FileDownloadName = stream.Name - }; - - // - return result; - } - - /// - /// Download Specified File ... - /// - /// - /// - public async Task Download(string fileName) - { - // - // Validate Args ... - var isValid = !fileName.IsNullOrEmpty(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Generate Stream Info and Validate it ... - var stream = await GetFileDescriptor(fileName); - if (stream.IsNull()) - { - XException.NotFound.Throw(); - } - - // - // Generate Result Model ... - var result = new PhysicalFileResult( - stream.Path, - stream.MIMEType - ) - { - FileDownloadName = stream.Name - }; - - // - return result; - } - - /// - /// Upload Files ... - /// - /// - /// - /// - /// - public async Task> Upload( - IFormFileCollection files, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate Args ... - var isValid = !files.IsNull() && - files.HasChild() && - !userInfo.IsNullOrDefault(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Save Files On Server Side Physically ... - // and Validate it ... - var uploadResults = await StorageProvider.HandleFilesSave(files); - isValid = uploadResults.HasChild(); - if (!isValid) - { - XException.ActionFailed.Throw(); - } - - // - // Prepare Result ... - var entities = new List(); - foreach (var ur in uploadResults) - { - // - var fileType = StorageProvider.GetFileType(ur.FileName); - - // - // Create Entity Model ... - var entity = new XFile - { - Type = fileType, - FileName = ur.Name, - Name = ur.FileName, - Path = ur.FilePath, - Thumb = ur.Thmbnail, - OwnerId = userInfo.UserId, - ThumbPath = ur.ThmbnailPath, - UploadedOn = DateTime.UtcNow, - }; - - // - try - { - // - // Add Entity Model to DB ... - entity = await FileRepository.AddAsync(entity); - - // - if (!entity.IsNullOrDefault()) - { - // - await SendPush( - action: XBaseEntityHubAction.Add.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - - // - entities.Add(entity); - } - } - catch { } - } - - // - // Preparing Result ... - var result = await ToDtoList(entities); - - // - return result; - } - - /// - /// Remove Specified Files ... - /// - /// - /// - /// - /// - public async Task> Remove( - string ids, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate Args ... - var isValid = !ids.IsNullOrEmpty() && - !userInfo.IsNullOrDefault(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Parse ID(s) List ... - var idsList = ids.ParseListGuid(); - isValid = !idsList.IsNull() && - idsList.HasChild(); - if (!isValid) - { - XException.ActionFailed.Throw(); - } - - // - // Loop Through Parsed Ids and Try to Remove ... - var result = new List(); - foreach (var id in idsList) - { - // - // Retrieve XFileDto and Validate it ... - var model = await Get(id); - isValid = !model.IsNull() && !model.Id.IsNull() && !model.Id.IsDefaultGuid(); - if (!isValid) - { - continue; - } - - // - // Check Physical File Exists or not ... - var fileFullPath = StorageProvider.GetFileFullPath(model.Name); - var thumbFullPath = model.Thumb.IsNullOrEmpty() - ? "" - : StorageProvider.GetThumbnailFileFullPath(model.Thumb); - var isFileExists = StorageProvider.IsFileExists(fileFullPath); - var isThumbExists = model.Thumb.IsNullOrEmpty() - ? false - : StorageProvider.IsFileExists(thumbFullPath); - - // - // Remove Physical Thumbnail File ... - if (isThumbExists) - { - // - try - { - // - // Removed Stored Thumbnail ... - StorageProvider.DeleteFile( - fileFullPath: thumbFullPath, - forceFileExists: false - ); - } - catch { } - } - - // - // Remove Pgysical File ... - if (isFileExists) - { - // - try - { - // - // Remove Stored File ... - StorageProvider.DeleteFile( - fileFullPath: fileFullPath, - forceFileExists: false - ); - - - // - // Remove Tags ... - await DetachTags( - id: id, - userInfo: userInfo, - connectionId: connectionId - ); - } - catch { } - } - - // - // Remove File Entty ... - var entity = await FileRepository.RemoveAsync(model.Id); - result.Add(model.Id); - - // - await SendPush( - action: XBaseEntityHubAction.Delete.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - } - - // - return result; - } - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - public async Task GetFileDescriptor(Guid id) - { - // - // Check File Model Exists or not ... - var isExists = await IsExists( - id: id - ); - if (!isExists) - { - XException.NotFound.Throw(); - } - - // - // Retrieve Entity and Validate it ... - var entity = await Get( - id: id - ); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - // Generate Physical File Path and Validate it ... - var fileFullPath = StorageProvider.GetFileFullPath(entity.Name); - isExists = StorageProvider.IsFileExists(fileFullPath); - var filePath = StorageProvider.FilePathResolver(fileFullPath); - filePath = Path.Combine("wwwroot", filePath); - if (!isExists) - { - XException.NotFound.Throw(); - } - - // - // Generate Physical File Info ... - IFileInfo fileInfo = StorageProvider.FileProvider.GetFileInfo(filePath); - - // - // Prepare Default Streaming Requirements ... - var mimeType = "application/octetstream"; - var readStream = fileInfo.CreateReadStream(); - var fileMimeProvider = new FileExtensionContentTypeProvider(); - var fileName = entity.Name; - - // - // Try to Find Physical File's Content Type ... - fileMimeProvider.TryGetContentType(filePath, out mimeType); - - // - // Prepare Result Model ... - var result = new XFileStreamDescriptorDto - { - Stream = readStream, - MIMEType = mimeType, - Name = fileName, - Path = fileFullPath - }; - - // - return result; - } - - /// - /// Retrieve Specified File Streaming Info ... - /// - /// - /// - public async Task GetFileDescriptor(string fileName) - { - // - if (fileName.IsNullOrEmpty()) - { - XException.InvalidArgs.Throw(); - } - var entity = await FindOne(e => - e.Name.Contains(fileName) || - e.Path.Contains(fileName) || - e.Thumb.Contains(fileName) || - e.FileName.Contains(fileName) || - e.ThumbPath.Contains(fileName) - ); - var isExists = !entity.IsNullOrDefault(); - if (!isExists) - { - XException.NotFound.Throw(); - } - - // - // Extract File Name ... - fileName = Path.GetFileName(fileName); - - // - // Check File is Thumbnail or File ... - var isThumb = fileName.StartsWith(StorageProvider.Configuration.ThumbPrefix); - var isFile = fileName.StartsWith(StorageProvider.Configuration.FilePrefix); - - // - // Check File Type is Valid ... - isExists = isThumb || isFile; - if (!isExists) - { - XException.UnsupportedFileType.Throw(); - } - - // - // Extract File Full Path ... - var fileFullPath = ""; - if (isThumb) - { - fileFullPath = StorageProvider.GetThumbnailFileFullPath(fileName); - } - else - { - fileFullPath = StorageProvider.GetFileFullPath(fileName); - } - - // - // Check Physical File Exists or Not ... - isExists = StorageProvider.IsFileExists(fileFullPath); - if (!isExists) - { - XException.NotFound.Throw(); - } - - // - // Generate Physical File Info ... - var filePath = StorageProvider.FilePathResolver(fileFullPath); - filePath = Path.Combine("wwwroot", filePath); - IFileInfo fileInfo = StorageProvider.FileProvider.GetFileInfo(filePath); - - // - // Prepare Default Streaming Requirements ... - var mimeType = "application/octetstream"; - var readStream = fileInfo.CreateReadStream(); - var fileMimeProvider = new FileExtensionContentTypeProvider(); - - // - // Try to Find Physical File's Content Type ... - fileMimeProvider.TryGetContentType(filePath, out mimeType); - - // - // Prepare Result Model ... - var result = new XFileStreamDescriptorDto - { - Stream = readStream, - MIMEType = mimeType, - Name = fileName, - Path = fileFullPath - }; - - // - return result; - } - #endregion - - // - #region Reference ... - /// - /// Get Reference Identifier for Specified Provider and Specified File ... + /// Get Reference Identifier for Specified Provider and Specified Item ... /// /// /// @@ -1032,29 +73,35 @@ namespace xFileService.Providers TKey forProvidedId ) { - return $"{providedFor}_{forProvidedId}"; + // + var result = $"{providedFor}_{forProvidedId}"; + + // + return result; } /// - /// Check Specified File has Refernce to Provider ... + /// Check Specified Item has Refernce to Provider ... /// /// /// /// + /// /// public async Task IsProvidedFor( string providedFor, TKey forProvidedId, - Guid id + Guid id, + CancellationToken cancellationToken = default ) { // // Validate ... var isValid = - !providedFor.IsNullOrEmpty() && !id.IsNull() && !id.IsDefaultGuid() && - !forProvidedId.IsNull(); + !forProvidedId.IsNull() && + !providedFor.IsNullOrEmpty(); if (!isValid) { XException.InvalidArgs.Throw(); @@ -1062,33 +109,43 @@ namespace xFileService.Providers // // Check Exists ... - isValid = await IsExists(id); + isValid = await IsExists( + id: id, + cancellationToken: cancellationToken + ); if (!isValid) { XException.NotFound.Throw(); } // - var dto = await Get(id); - isValid = !dto.IsNullOrDefault(); + var item = await Get( + id: id, + includeBuilder: null, + cancellationToken: cancellationToken + ); + isValid = !item.IsNullOrDefault(); if (!isValid) { XException.ActionFailed.Throw(); } // + var references = item.GetReferences(); var result = - dto.References.IsNull() && - dto.References.HasChild() && - dto.References.Any(r => r.ProvidedFor == providedFor && - r.ReferencedTo == $"{forProvidedId}"); + references.IsNull() && + references.HasChild() && + references.Any(r => + r.ProvidedFor == providedFor && + r.ReferencedTo == $"{forProvidedId}" + ); // return result; } /// - /// Add Specified Reference to Specified File ... + /// Add Specified Reference to Specified Item ... /// /// /// @@ -1096,6 +153,7 @@ namespace xFileService.Providers /// /// /// + /// /// public async Task AddReference( string providedFor, @@ -1103,7 +161,8 @@ namespace xFileService.Providers Guid id, int forIndex = 0, XUserClaimsInfoDto userInfo = null, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -1122,57 +181,55 @@ namespace xFileService.Providers // // Check Has Reference or not ... isValid = await IsProvidedFor( + id: id, providedFor: providedFor, forProvidedId: forProvidedId, - id: id + cancellationToken: cancellationToken ); - if (!isValid) + if (isValid) { // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var dto = await Get(id); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.ActionFailed.Throw(); - } - - // - var reference = new XReference - { - Index = forIndex, - ProvidedFor = providedFor, - ReferencedTo = $"{forProvidedId}" - }; - dto.References.Add(reference); - - // - dto = await Update( - item: dto, - id: dto.Id, - userInfo: userInfo, - connectionId: connectionId - ); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.ActionFailed.Throw(); - } + // Prevent Moving Forward Since Reference Exists ... + return; } + + // + // Check Permissions ... + var item = await Get( + id: id, + includeBuilder: null, + cancellationToken: cancellationToken + ); + isValid = + !item.IsNullOrDefault() && + (IsOwned(item, userInfo) || + HasPermision(userInfo)); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + var reference = new XReference + { + Index = forIndex, + ProvidedFor = providedFor, + ReferencedTo = $"{forProvidedId}" + }; + var references = item.GetReferences(); + references.Add(reference); + item = item.UpdateReferences(references); + item = await Update( + id: id, + item: item, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); } /// - /// Remove Specified Reference from Specified File ... + /// Remove Specified Reference from Specified Item ... /// /// /// @@ -1180,6 +237,7 @@ namespace xFileService.Providers /// /// /// + /// /// public async Task RemoveReference( string providedFor, @@ -1187,17 +245,18 @@ namespace xFileService.Providers Guid id, int forIndex = 0, XUserClaimsInfoDto userInfo = null, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // // Validate ... var isValid = - !providedFor.IsNullOrEmpty() && !id.IsNull() && !id.IsDefaultGuid() && !forProvidedId.IsNull() && - !userInfo.IsNullOrDefault(); + !userInfo.IsNullOrDefault() && + !providedFor.IsNullOrEmpty(); if (!isValid) { XException.InvalidArgs.Throw(); @@ -1206,542 +265,57 @@ namespace xFileService.Providers // // Check Has Reference or not ... isValid = await IsProvidedFor( + id: id, providedFor: providedFor, forProvidedId: forProvidedId, - id: id + cancellationToken: cancellationToken ); - if (isValid) + if (!isValid) { // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } + // Prevent Moving Forward Since Reference not Exists ... + return; + } - // - // Retrieve Dto ... - var dto = await Get(id); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.ActionFailed.Throw(); - } + // + // Check Permissions ... + var item = await Get( + id: id, + includeBuilder: null, + cancellationToken: cancellationToken + ); + isValid = + !item.IsNullOrDefault() && + (IsOwned(item, userInfo) || + HasPermision(userInfo)); + if (!isValid) + { + XException.NotAllowed.Throw(); + } - // - var identifier = GetIdentifier( - providedFor: providedFor, - forProvidedId: forProvidedId - ); - dto.References = dto.References + // + var identifier = GetIdentifier( + providedFor: providedFor, + forProvidedId: forProvidedId + ); + var references = item.GetReferences(); + references = references .Where(r => r.Index != forIndex && r.ProvidedFor != providedFor && r.ReferencedTo != $"{forProvidedId}" ) .ToList(); - dto = await Update( - item: dto, - id: dto.Id, - userInfo: userInfo, - connectionId: connectionId - ); - isValid = !dto.IsNullOrDefault(); - if (!isValid) - { - XException.ActionFailed.Throw(); - } - } - } - #endregion - - // - #region Data Model ... - /// - /// Get Specified File Model ... - /// - /// - /// - /// - public async Task Get( - Guid id - ) - { - // - // Validate ... - if (id.IsNull() || id.IsDefaultGuid()) - { - XException.InvalidArgs.Throw(); - } + item = item.UpdateReferences(references); // - var entity = await FileRepository.GetAsync(id); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - var result = await ToDto(entity); - if (result.IsNullOrDefault()) - { - XException.ActionFailed.Throw(); - } - - // - return result; - } - - /// - /// Get All Exists File Models ... - /// - /// - /// - public async Task> GetAll() - { - // - var result = new List(); - - // - var entities = await FileRepository.GetAllAsync(); - if (!entities.IsNull() && entities.HasChild()) - { - // - result = (await ToDtoList(entities)) - .ToList(); - } - - // - return result; - } - - /// - /// find an Entity by providing a Conditional Expression ... - /// - /// - public async Task FindOne(Expression> whereClause) - { - // - var result = new XFileDto(); - - // - var entity = await FileRepository.FindOneAsync(whereClause); - if (!entity.IsNullOrDefault()) - { - result = await ToDto(entity); - } - - // - return result; - } - - /// - /// find a collection of Entities by proving a Conditional Expression ... - /// - /// - /// - public async Task> FindMany( - Expression> whereClause - ) - { - // - var result = new List(); - - // - var entities = await FileRepository.FindManyAsync(whereClause); - if (!entities.IsNull() && entities.HasChild()) - { - // - result = (await ToDtoList(entities)) - .ToList(); - } - - // - return result; - } - - /// - /// retrieve Entities based on XQuery Pagination structure ... - /// - /// - /// - public async Task> Query( - XQuery query - ) - { - // - var result = new XQueryResult(); - - // - var queryResult = await FileRepository.QueryAsync(query); - if (!queryResult.IsNullOrDefault()) - { - result = await ToDtoQueryResult(queryResult); - } - - // - return result; - } - - /// - /// retrieve Owned Entities based on XQuery Pagination structure ... - /// - /// - /// - /// - public async Task> QueryOwned( - XQuery query, - XUserClaimsInfoDto userInfo = null - ) - { - // - // Validate ... - var isValid = !userInfo.IsNullOrDefault(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Create Where Clause ... - Expression> whereClause = e => e.OwnerId == userInfo.UserId; - var result = await ConditionalQuery( - query: query, - whereClause: whereClause + item = await Update( + item: item, + id: item.Id, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken ); - - // - return result; - } - - /// - /// retrieve Entities based on XQuery Pagination structure by providing a Conditional Expression ... - /// - /// - /// - /// - public async Task> ConditionalQuery( - Expression> whereClause, - XQuery query - ) - { - // - var result = new XQueryResult(); - - // - var queryResult = await FileRepository.ConditionalQueryAsync( - query: query, - whereClause: whereClause - ); - if (!queryResult.IsNullOrDefault()) - { - result = await ToDtoQueryResult(queryResult); - } - - // - return result; - } - - /// - /// retrieve Owned Entities based on XQuery Pagination structure by providing a Conditional Expression ... - /// - /// - /// - /// - /// - public async Task> ConditionalQueryOwned( - Expression> whereClause, - XQuery query, - XUserClaimsInfoDto userInfo = null - ) - { - // - // Validate ... - var isValid = !whereClause.IsNull() && - !userInfo.IsNullOrDefault(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Compile Where Clause ... - var whereFunc = whereClause.Compile(); - - // - // Create new Where Clause ... - Expression> condition = - e => whereFunc(e) && e.OwnerId == userInfo.UserId; - - // - var result = await ConditionalQuery( - query: query, - whereClause: condition - ); - - // - return result; - } - - /// - /// Update an Entity values ... - /// - /// - /// - /// - /// - /// - public async Task Update( - Guid id, - XFileDto item, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - bool isValid = !id.IsNull() && - !id.IsDefaultGuid() && - !item.IsNullOrDefault() && - !userInfo.IsNullOrDefault(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check entity Exists and Retrieve it ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - // Retrieve Entity ... - var entity = await FileRepository.GetAsync(id); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - // Fill Data for Update ... - var itemEntity = item.FromDto(); - entity = entity.UpdateData( - updateWith: item, - propertyBlackList: new List - { - nameof(XFile.Id), - nameof(XFile.Deleted), - nameof(XFileDto.Owner), - nameof(XFile.References), - } - ); - - // - if (!itemEntity.IsNullOrDefault()) - { - entity.References = itemEntity.References; - } - - // - if (entity.IsNullOrDefault()) - { - XException.InvalidData.Throw(); - } - - // - entity = await FileRepository.UpdateAsync(id, entity); - if (entity.IsNullOrDefault()) - { - XException.ActionFailed.Throw(); - } - - // - // Converts to Dto ... - var result = await ToDto(entity); - - // - if (!result.IsNullOrDefault()) - { - // - await SendPush( - action: XBaseEntityHubAction.Update.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - } - - // - return result; - } - - /// - /// remove an Entity ... - /// - /// - /// - /// - /// - public async Task Remove( - Guid id, - XUserClaimsInfoDto userInfo = null, - string connectionId = null - ) - { - // - // Validate ... - var isValid = !id.IsNull() && - !id.IsDefaultGuid() && - !userInfo.IsNullOrDefault(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Entity Exists and Retrieve it ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - var result = await Get(id); - isValid = !result.IsNullOrDefault(); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - // Check Permissions ... - isValid = await HasPermission( - id: id, - userInfo: userInfo - ); - if (!isValid) - { - XException.NotAllowed.Throw(); - } - - // - var entity = await FileRepository.RemoveAsync(id); - if (entity.IsNullOrDefault()) - { - XException.ActionFailed.Throw(); - } - - // - result = await ToDto(entity); - if (result.IsNullOrDefault()) - { - XException.ActionFailed.Throw(); - } - - // - // Removing Tags ... - await TagProvider.RemoveReferences(result.Id); - - // - await SendPush( - action: XBaseEntityHubAction.Delete.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - - // - return result; - } - - /// - /// count all exists Entities ... - /// - /// - public async Task Count() - { - return await FileRepository.CountAsync(); - } - - /// - /// Check an Entity exists or not ... - /// - /// - /// - public async Task IsExists( - Guid id - ) - { - return await FileRepository.IsExistsAsync(id); - } - #endregion - - // - #region Hub Actions ... - /// - /// Send Custom Push Message ... - /// - /// - /// - /// - /// - public async Task SendPush( - string action, - string payLoad, - string connectionId = null - ) - { - // - var actions = new List - { - XBaseEntityHubAction.Add.GetStringValue(), - XBaseEntityHubAction.Update.GetStringValue(), - XBaseEntityHubAction.Delete.GetStringValue(), - XBaseEntityHubAction.AddMany.GetStringValue(), - XBaseEntityHubAction.DeleteMany.GetStringValue(), - XBaseEntityHubAction.UpdateMany.GetStringValue(), - XBaseEntityHubAction.AddOrUpdate.GetStringValue(), - }; - - // - // Validate ... - var isValid = - !Hub.IsNull() && - !action.IsNullOrEmpty() && - actions.Contains(action); - if (!isValid) - { - return; - } - - // - var clients = Hub.Clients.All; - if (!connectionId.IsNullOrEmpty()) - { - clients = Hub.Clients.AllExcept(connectionId); - } - try - { - await clients.SendAsync(action, payLoad, connectionId); - } - catch { } } #endregion } diff --git a/Providers/XFileSeederBase.cs b/Providers/XFileSeederBase.cs new file mode 100644 index 0000000..5bbf589 --- /dev/null +++ b/Providers/XFileSeederBase.cs @@ -0,0 +1,25 @@ +using System; +using xDataService.Configuration; +using xDataService.Providers; +using xFileService.Interfaces; +using xFileService.Interfaces.Entities; +using xFileService.Models.Entities; + +namespace xFileService.Providers +{ + public abstract class XFileSeederBase : XBaseDbSeeder, IXFileSeeder + { + protected XFileSeederBase( + string entity, + string database, + IXFileRepository repository, + XDataServiceConfiguration dataServiceConfiguration + ) : base( + entity, + database, + repository, + dataServiceConfiguration + ) + { } + } +} \ No newline at end of file diff --git a/Providers/XFileTagProvider.cs b/Providers/XFileTagProvider.cs index d3eb296..5810890 100644 --- a/Providers/XFileTagProvider.cs +++ b/Providers/XFileTagProvider.cs @@ -1,7 +1,7 @@ using System; using xFileService.Interfaces; using xFileService.Models.Entities; -using xTagService.Interfaces; +using xTagService.Interfaces.Dtos; using xTagService.Providers; namespace xFileService.Providers @@ -9,9 +9,10 @@ namespace xFileService.Providers public class XFileTagProvider : XBaseTagProvider, IXFileTagProvider { public XFileTagProvider( - IXTagProvider tagProvider + string providedFor, + IXTagServiceProvider tagProvider ) : base( - providedFor: nameof(XFile), + providedFor: nameof(XFile), tagProvider: tagProvider ) { } diff --git a/nuget.config b/nuget.config index 632defe..c6fd40c 100644 --- a/nuget.config +++ b/nuget.config @@ -1,7 +1,8 @@ + - + \ No newline at end of file diff --git a/xFileService.csproj b/xFileService.csproj index 30b4167..2fece05 100644 --- a/xFileService.csproj +++ b/xFileService.csproj @@ -24,7 +24,7 @@ - + @@ -32,13 +32,10 @@ - - + - +