diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index b5241af..585cd08 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -95,7 +95,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: none tools: phive diff --git a/.github/workflows/dependency-analysis.yml b/.github/workflows/dependency-analysis.yml index 52931a5..3ce27d5 100644 --- a/.github/workflows/dependency-analysis.yml +++ b/.github/workflows/dependency-analysis.yml @@ -46,7 +46,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: none tools: phive @@ -109,7 +109,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: none tools: phive diff --git a/.github/workflows/refactoring.yml b/.github/workflows/refactoring.yml index cad970e..0b70d10 100644 --- a/.github/workflows/refactoring.yml +++ b/.github/workflows/refactoring.yml @@ -41,7 +41,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: none diff --git a/.github/workflows/security-analysis.yml b/.github/workflows/security-analysis.yml index 56dee7d..9033fdc 100644 --- a/.github/workflows/security-analysis.yml +++ b/.github/workflows/security-analysis.yml @@ -36,7 +36,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: none diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index dcaf5ff..c9be01d 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -35,7 +35,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, opcache, pcntl, posix, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, curl, fileinfo, pdo_mysql, opcache, pcntl, posix, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: none @@ -89,7 +89,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, pdo_mysql, curl, fileinfo, opcache, pcntl, posix, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, pdo_mysql, curl, fileinfo, opcache, pcntl, posix, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: xdebug diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 9e1e995..7549f0d 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -42,7 +42,7 @@ jobs: uses: shivammathur/setup-php@2.31.1 with: php-version: ${{ matrix.php-version }} - extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, pdo_mysql, pdo_sqlite, curl, fileinfo, opcache, pcntl, posix, sockets, decimal + extensions: none, ctype, dom, json, mbstring, simplexml, tokenizer, xml, xmlwriter, pdo, pdo_mysql, pdo_sqlite, curl, fileinfo, opcache, pcntl, posix, sockets, decimal, grpc ini-values: error_reporting=E_ALL coverage: xdebug diff --git a/app/composer.json b/app/composer.json index c13f1cb..04ac20e 100644 --- a/app/composer.json +++ b/app/composer.json @@ -39,6 +39,7 @@ "ext-mbstring": "*", "ext-pdo": "*", "ext-sockets": "*", + "ext-grpc": "*", "beberlei/assert": "^3.3", "cycle/annotated": "^4.2", "cycle/database": "^2.11", @@ -52,6 +53,7 @@ "spiral-packages/laravel-validator": "^1.1", "spiral-packages/league-event": "^1.0", "spiral-packages/scheduler": "^2.3", + "spiral-packages/swagger-php": "^1.0", "spiral-packages/yii-error-handler-bridge": "^1.1", "spiral/cycle-bridge": "^2.10", "spiral/data-grid-bridge": "^3.0", diff --git a/app/composer.lock b/app/composer.lock index e5f07bb..9cc572d 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "81f7ab1a7c43ac05dcb05cbdb638f900", + "content-hash": "7bcb4528a0a751cbb7c9a2c66cd1a04e", "packages": [ { "name": "alexkart/curl-builder", @@ -5514,6 +5514,67 @@ }, "time": "2024-09-30T12:03:29+00:00" }, + { + "name": "spiral-packages/swagger-php", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/spiral-packages/swagger-php.git", + "reference": "82f937da325579f9adc55bb74ccd38ef69c77d4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spiral-packages/swagger-php/zipball/82f937da325579f9adc55bb74ccd38ef69c77d4f", + "reference": "82f937da325579f9adc55bb74ccd38ef69c77d4f", + "shasum": "" + }, + "require": { + "php": "^8.1", + "spiral/boot": "^3.5", + "spiral/cache": "^3.5", + "spiral/config": "^3.5", + "spiral/core": "^3.5", + "spiral/http": "^3.5", + "spiral/views": "^3.5", + "zircote/swagger-php": "^4.8" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.42", + "phpunit/phpunit": "^10.5", + "roave/security-advisories": "dev-latest", + "spiral/testing": "^2.6", + "vimeo/psalm": "^5.18" + }, + "type": "library", + "extra": { + "spiral": { + "bootloaders": [ + "Spiral\\OpenApi\\Bootloader\\SwaggerBootloader" + ] + } + }, + "autoload": { + "psr-4": { + "Spiral\\OpenApi\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Swagger-php integration package for Spiral Framework.", + "homepage": "https://github.com/spiral-packages/swagger-php", + "keywords": [ + "Swagger-PHP", + "api", + "spiral" + ], + "support": { + "issues": "https://github.com/spiral-packages/swagger-php/issues", + "source": "https://github.com/spiral-packages/swagger-php/tree/v1.0.0" + }, + "time": "2024-02-27T16:14:50+00:00" + }, { "name": "spiral-packages/yii-error-handler-bridge", "version": "1.1.2", @@ -9988,6 +10049,87 @@ } ], "time": "2023-12-22T07:29:39+00:00" + }, + { + "name": "zircote/swagger-php", + "version": "4.11.1", + "source": { + "type": "git", + "url": "https://github.com/zircote/swagger-php.git", + "reference": "7df10e8ec47db07c031db317a25bef962b4e5de1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/7df10e8ec47db07c031db317a25bef962b4e5de1", + "reference": "7df10e8ec47db07c031db317a25bef962b4e5de1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.2", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2 || ^3", + "symfony/finder": ">=2.2", + "symfony/yaml": ">=3.3" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11", + "doctrine/annotations": "^1.7 || ^2.0", + "friendsofphp/php-cs-fixer": "^2.17 || 3.62.0", + "phpstan/phpstan": "^1.6", + "phpunit/phpunit": ">=8", + "vimeo/psalm": "^4.23" + }, + "suggest": { + "doctrine/annotations": "^1.7 || ^2.0" + }, + "bin": [ + "bin/openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "OpenApi\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Robert Allen", + "email": "zircote@gmail.com" + }, + { + "name": "Bob Fanger", + "email": "bfanger@gmail.com", + "homepage": "https://bfanger.nl" + }, + { + "name": "Martin Rademacher", + "email": "mano@radebatz.net", + "homepage": "https://radebatz.net" + } + ], + "description": "swagger-php - Generate interactive documentation for your RESTful API using phpdoc annotations", + "homepage": "https://github.com/zircote/swagger-php/", + "keywords": [ + "api", + "json", + "rest", + "service discovery" + ], + "support": { + "issues": "https://github.com/zircote/swagger-php/issues", + "source": "https://github.com/zircote/swagger-php/tree/4.11.1" + }, + "time": "2024-10-15T19:20:02+00:00" } ], "packages-dev": [ @@ -16275,7 +16417,8 @@ "ext-decimal": "*", "ext-mbstring": "*", "ext-pdo": "*", - "ext-sockets": "*" + "ext-sockets": "*", + "ext-grpc": "*" }, "platform-dev": [], "platform-overrides": { diff --git a/app/src/Application/Transfer/DTO/TransferDetails.php b/app/src/Application/Transfer/DTO/TransferDetails.php new file mode 100644 index 0000000..e735f5c --- /dev/null +++ b/app/src/Application/Transfer/DTO/TransferDetails.php @@ -0,0 +1,39 @@ +transferId = $transferId; + $this->fromUserId = $fromUserId; + $this->toUserId = $toUserId; + $this->fromDomain = $fromDomain; + $this->toDomain = $toDomain; + } +} diff --git a/app/src/Bridge/Spiral/Console/TransferCommand.php b/app/src/Bridge/Spiral/Console/TransferCommand.php new file mode 100644 index 0000000..236be8c --- /dev/null +++ b/app/src/Bridge/Spiral/Console/TransferCommand.php @@ -0,0 +1,33 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/AttachDomainActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/AttachDomainActivity.php new file mode 100644 index 0000000..745939c --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/AttachDomainActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/DestinationStub.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/DestinationStub.php new file mode 100644 index 0000000..7c3b83f --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/DestinationStub.php @@ -0,0 +1,74 @@ +withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function restoreFiles(): ActivityProxy|RestoreFilesActivity + { + return Workflow::newActivityStub( + RestoreFilesActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function allocateSpace(): ActivityProxy|AllocateSpaceActivity + { + return Workflow::newActivityStub( + AllocateSpaceActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function attachDomain(): ActivityProxy|AttachDomainActivity + { + return Workflow::newActivityStub( + AttachDomainActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function reConfigureWebsite(): ActivityProxy|ReConfigureWebsiteActivity + { + return Workflow::newActivityStub( + ReConfigureWebsiteActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/ReConfigureWebsiteActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/ReConfigureWebsiteActivity.php new file mode 100644 index 0000000..db9c811 --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/ReConfigureWebsiteActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/RestoreDatabaseActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/RestoreDatabaseActivity.php new file mode 100644 index 0000000..1f3c7e1 --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/RestoreDatabaseActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/RestoreFilesActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/RestoreFilesActivity.php new file mode 100644 index 0000000..aecfe37 --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Destination/RestoreFilesActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Source/InitiateDatabaseBackupActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/InitiateDatabaseBackupActivity.php new file mode 100644 index 0000000..4d0c5b6 --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/InitiateDatabaseBackupActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Source/InitiateFilesBackupActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/InitiateFilesBackupActivity.php new file mode 100644 index 0000000..2c4684b --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/InitiateFilesBackupActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Source/ReleaseDomainActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/ReleaseDomainActivity.php new file mode 100644 index 0000000..c2bb7e8 --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/ReleaseDomainActivity.php @@ -0,0 +1,22 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Source/SourceStub.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/SourceStub.php new file mode 100644 index 0000000..9da80c0 --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/SourceStub.php @@ -0,0 +1,62 @@ +withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function initiateDatabaseBackup(): ActivityProxy|InitiateDatabaseBackupActivity + { + return Workflow::newActivityStub( + InitiateDatabaseBackupActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function releaseDomain(): ActivityProxy|ReleaseDomainActivity + { + return Workflow::newActivityStub( + ReleaseDomainActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } + + public static function transferBackup(): ActivityProxy|TransferBackupActivity + { + return Workflow::newActivityStub( + TransferBackupActivity::class, + ActivityOptions::new() + ->withStartToCloseTimeout(CarbonInterval::minute()) + ->withRetryOptions( + RetryOptions::new()->withMaximumAttempts(1), + ), + ); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Activities/Source/TransferBackupActivity.php b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/TransferBackupActivity.php new file mode 100644 index 0000000..91893fb --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Activities/Source/TransferBackupActivity.php @@ -0,0 +1,23 @@ +toString(); + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Workflows/TransferWebsiteWorkflow.php b/app/src/Infrastructure/Temporal/Transfer/Workflows/TransferWebsiteWorkflow.php new file mode 100644 index 0000000..9254c8f --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Workflows/TransferWebsiteWorkflow.php @@ -0,0 +1,40 @@ +actions[] = SourceStub::initiateFilesBackup(); + $this->actions[] = SourceStub::releaseDomain(); + $this->actions[] = SourceStub::initiateDatabaseBackup(); + $this->actions[] = SourceStub::transferBackup(); + $this->actions[] = DestinationStub::allocateSpace(); + $this->actions[] = DestinationStub::restoreDatabase(); + $this->actions[] = DestinationStub::restoreFiles(); + $this->actions[] = DestinationStub::attachDomain(); + } + + public function handle(TransferDetails $transferDetails) + { + foreach ($this->actions as $action) { + try { + yield $action->handle($transferDetails); // Execute each activity sequentially + } catch (Throwable $e) { + // Handle or log the error + // todo: Log error + } + } + } +} diff --git a/app/src/Infrastructure/Temporal/Transfer/Workflows/TransferWebsiteWorkflowStub.php b/app/src/Infrastructure/Temporal/Transfer/Workflows/TransferWebsiteWorkflowStub.php new file mode 100644 index 0000000..9e6e28e --- /dev/null +++ b/app/src/Infrastructure/Temporal/Transfer/Workflows/TransferWebsiteWorkflowStub.php @@ -0,0 +1,23 @@ +newWorkflowStub( + TransferWebsiteWorkflow::class, + ); + + return $client->start($workflow, $transferDetails); + } +} diff --git a/docker-compose.temporal.yaml b/docker-compose.temporal.yaml index 24b9d4d..0eae7d0 100644 --- a/docker-compose.temporal.yaml +++ b/docker-compose.temporal.yaml @@ -25,7 +25,7 @@ services: driver: ${DOCKER_TEMPORAL_DATABASE_LOG_DRIVER:-json-file} temporal: - image: temporalio/auto-setup:1.24.2 + image: temporalio/auto-setup:1.25.2 container_name: ${COMPOSE_PROJECT_NAME}-temporal restart: on-failure networks: @@ -54,7 +54,7 @@ services: driver: ${DOCKER_TEMPORAL_LOG_DRIVER:-json-file} temporal-ui: - image: temporalio/ui:2.29.2 + image: temporalio/ui:2.31.2 container_name: ${COMPOSE_PROJECT_NAME}-temporal-ui restart: on-failure networks: diff --git a/docker-compose.yaml b/docker-compose.yaml index e52f018..c517756 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,7 +2,7 @@ services: app: - image: wayofdev/php-dev:8.3-cli-alpine-latest + image: ghcr.io/wayofdev/docker-php-dev:8.3-cli-alpine-latest container_name: ${COMPOSE_PROJECT_NAME}-app restart: on-failure networks: