{"id":26928320,"url":"https://github.com/suhaib-mousa/objectstorage","last_synced_at":"2025-04-02T04:19:11.245Z","repository":{"id":254598715,"uuid":"846667124","full_name":"suhaib-mousa/ObjectStorage","owner":"suhaib-mousa","description":null,"archived":false,"fork":false,"pushed_at":"2024-08-24T14:35:43.000Z","size":290,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T04:19:09.076Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/suhaib-mousa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-23T17:35:52.000Z","updated_at":"2024-12-12T13:44:52.000Z","dependencies_parsed_at":"2024-08-24T17:22:34.945Z","dependency_job_id":null,"html_url":"https://github.com/suhaib-mousa/ObjectStorage","commit_stats":null,"previous_names":["suhaib-mousa/rekaz.objectstorage","suhaib-mousa/objectstorage"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suhaib-mousa%2FObjectStorage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suhaib-mousa%2FObjectStorage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suhaib-mousa%2FObjectStorage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suhaib-mousa%2FObjectStorage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/suhaib-mousa","download_url":"https://codeload.github.com/suhaib-mousa/ObjectStorage/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246752733,"owners_count":20828012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-02T04:19:10.020Z","updated_at":"2025-04-02T04:19:11.240Z","avatar_url":"https://github.com/suhaib-mousa.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blob Storage Service Documentation\n\n## Overview\n\nThe Blob Storage Service is a versatile system designed to store and retrieve data in various storage backends, such as Amazon S3, local file systems, databases, and optionally FTP. The service provides a consistent interface, allowing you to interact with these different storage types seamlessly.\n\n### Key Features:\n- Supports multiple storage backends (Amazon S3, Local Storage, Database, FTP).\n- Configurable and extendable.\n- Implements object-oriented principles for scalability and maintainability.\n\n---\n\n## Architecture and Design\n\n### Core Concepts:\n\n- **IBlobProvider**: The main interface for storing and retrieving blobs. Each storage backend implements this interface.\n- **BlobProviderBase**: An abstract base class that provides shared functionality for all blob providers, such as handling streams.\n- **BlobStorageService**: The service that interacts with the configured provider to save and retrieve blobs.\n- **BlobStoringConfiguration**: Manages the configuration settings for different providers.\n\n### Storage Backends:\n\n#### 1. Local Storage\n- **Description**: Stores files directly on the local file system of the server.\n- **Path Calculation**: Utilizes a `BlobFilePathCalculator` to generate file paths where blobs are stored.\n  \n#### 2. Amazon S3\n- **Description**: Interacts with Amazon S3 or S3-compatible services using HTTP requests.\n- **Configuration**: Requires configuration of access keys, bucket name, and region to connect to the S3 service.\n\n#### 3. Database\n- **Description**: Stores blob data within a database, offering a centralized and persistent storage solution.\n- **Implementation**:\n  - **Provider**: The `DatabaseBlobProvider` class handles database interactions for blob storage.\n  - **Functionality**:\n    - **Saving Blobs**: Converts the blob's binary content into a byte array and saves it as a new entry in the database if it doesn't already exist.\n    - **Retrieving Blobs**: Fetches blobs from the database using a unique identifier, returning the content as a `Stream`.\n  - **Dependencies**:\n    - **`IDatabaseBlobRepository`**: Interface for CRUD operations on blob data in the database.\n  - **Error Handling**: Includes checks to prevent saving duplicate blobs and ensures data consistency.\n\n#### 4. FTP (Bonus)\n- **Description**: Utilizes the FluentFTP library to manage file operations over FTP.\n- **Functionality**: Allows for file storage and retrieval using FTP protocols, making it flexible for remote file management.\n\n### Extensibility:\nThe architecture is built with flexibility in mind. Each storage backend is configurable, and new backends can be added by implementing the `IBlobProvider` interface.\n\n---\n\n## Object-Oriented Principles and Design Patterns\n\n### Key Principles:\n\n1. **Abstraction**: The `IBlobProvider` interface and `BlobProviderBase` abstract the details of different storage mechanisms, making it easy to switch or extend the storage backends.\n2. **Single Responsibility Principle**: Each class has a specific role, such as handling configuration, calculating paths, or managing storage.\n\n### Design Patterns:\n\n- **Strategy Pattern**: Used in the way different storage providers are interchangeable and configured dynamically.\n- **Template Method Pattern**: The base class `BlobProviderBase` defines the skeleton for common operations while allowing derived classes to provide specific implementations.\n\n---\n\n## How to Use\n\n### Prerequisites\n\nBefore starting the setup, ensure that your environment meets the following prerequisites:\n\n1. **.NET 8 SDK Installed**  \n   .NET 8 is required to build and run the application. Make sure it is installed on your system. You can check the version by running:\n   ```bash\n   dotnet --version\n   ```\n   If not installed, download and install the SDK from the [official .NET website](https://dotnet.microsoft.com/).\n\n2. **ABP Framework 8.2.1**  \n   The project requires the ABP Framework version 8.2.1. Ensure all necessary packages are updated to this version. You can install or update the packages via NuGet:\n   ```bash\n   dotnet add package Volo.Abp --version 8.2.1\n   ```\n\nThese prerequisites ensure that your environment is compatible with the latest features and performance improvements provided by both .NET 8 and ABP 8.2.1.\n\nFor setting up object storage and configuring the blob storage options, the process involves selecting and configuring one storage provider at a time, depending on your requirements. Here’s a detailed breakdown of how to handle this:\n\n### 1. **Configuring Blob Storage Providers**\n\nIn the `ObjectStorageWebModule` class, under the `ConfigureBlobStorage()` method, you’ll see different blob storage configurations commented out. You can choose one provider to configure and uncomment the relevant section while commenting out or removing others.\n\n#### Example:\n```csharp\nprivate void ConfigureBlobStorage()\n{\n    Configure\u003cBlobStoringOptions\u003e(options =\u003e\n    {\n        // Example for configuring local storage:\n        options.Configuration.UseLocalStorage(f =\u003e\n        {\n            f.BasePath = Path.Combine(Directory.GetCurrentDirectory(), \"Documents\");\n        });\n\n        // Example for configuring AWS S3:\n        //options.Configuration.UseAws(aws =\u003e\n        //{\n        //    aws.AccessKeyId = \"YOUR_ACCESS_KEY\";\n        //    aws.SecretAccessKey = \"YOUR_SECRET_KEY\";\n        //    aws.BucketName = \"YOUR_BUCKET\";\n        //    aws.Region = \"YOUR_REGION\";\n        //    aws.Container = \"YOUR_CONTAINER\";\n        //});\n\n        // Example for configuring FTP:\n        //options.Configuration.UseFTP(f =\u003e\n        //{\n        //    f.ServerAddress = \"YOUR_SERVER_ADDRESS\";\n        //    f.Port = 21; // YOUR_PORT\n        //    f.Username = \"YOUR_USERNAME\";\n        //    f.Password = \"YOUR_PASSWORD\";\n        //    f.RootPath = @\"YOUR_ROOT_PATH\";\n        //});\n    });\n}\n```\nHere, you can only have **one** configuration active at a time. If you decide to switch from local storage to AWS, for instance, you must first comment out the local storage configuration and then uncomment and configure the AWS section.\n\n### 2. **Using `DependsOn` Attribute**\n\nTo ensure the correct modules are loaded, the `DependsOn` attribute in the module class needs to include only the relevant dependencies. For example:\n\n- If you’re using local storage:\n```csharp\n[DependsOn(\n    typeof(BlobStoringLocalStorageModule),\n    typeof(BlobStoringModule)\n    // Other relevant modules...\n)]\npublic class ObjectStorageApplicationContractsModule : AbpModule\n{\n    // Module implementation...\n}\n```\n\n- If you’re switching to AWS:\n```csharp\n[DependsOn(\n    typeof(BlobStoringAwsModule),\n    typeof(BlobStoringModule)\n    // Other relevant modules...\n)]\npublic class ObjectStorageApplicationContractsModule : AbpModule\n{\n    // Module implementation...\n}\n```\n\nRemember to **replace** the previous module with the new one to avoid conflicts.\n\n### 3. **Configuring the Database**\n\nIf you need to store blobs with the database provider, configure the database in the `ConfigureDatabase()` method in `OnModelCreating` of `ObjectStorageDbContext`:\n\n```csharp\nbuilder.ConfigureDatabase();\n```\n\nEnsure to do the following:\n\n1. **Enable** the following modules:\n   - `ObjectStorageDomainModule`\n   - `ObjectStorageDomainSharedModule`\n   - `ObjectStorageEntityFrameworkCoreModule`\n\n2. **Comment out** any other storage modules (e.g., Local Storage, Amazon S3, FTP) that you are not using.\n\n3. Add the `UseDatabase` in the `ObjectStorageWebModule` class, under the `ConfigureBlobStorage()` method, comment out or remove the others:\n```csharp\nprivate void ConfigureBlobStorage()\n{\n     Configure\u003cBlobStoringOptions\u003e(options =\u003e\n    {\n        options.Configuration.UseDatabase();\n    });\n}\n```\n\u003e Note: Should run the `Rekaz.ObjectStorage.DbMigrator.csproj` to apply the migrations of the database provider.\n\n## For authentication\n\nPortal Access:\n1. You can easily log in using the username `admin` and the password `1q2w3E*`. And go to `/swagger/index.html`.\n2. Navigate to `ObjectFile`:\n   ![image](https://github.com/user-attachments/assets/4dfcb83f-1d4f-4c05-8fb4-a6b39cd45751)\n   \nFor external Access:\nYou can use the postman for instance and firstly call the following API:\n![image](https://github.com/user-attachments/assets/970b300a-39ca-460d-8cc5-d151f5cf5077)\nthen will you get the `access_token`.\n\nAdd this token as a Bearer token in the Authorization header for ObjectFile API calls.\n\n### Summary\n- Choose one blob storage provider to configure at a time and comment out or remove the others.\n- Update the `DependsOn` attribute to include the correct module corresponding to the chosen provider.\n- If switching storage providers, ensure you replace the old configuration with the new one.\n- Only configure one approach for database integration at a time to avoid conflicts.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuhaib-mousa%2Fobjectstorage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuhaib-mousa%2Fobjectstorage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuhaib-mousa%2Fobjectstorage/lists"}