diff --git a/app/Jobs/RestoreFederation.php b/app/Jobs/RestoreFederation.php new file mode 100644 index 0000000..ebfee11 --- /dev/null +++ b/app/Jobs/RestoreFederation.php @@ -0,0 +1,49 @@ +membership = $membership; + } + + /** + * Execute the job. + */ + public function handle(): void + { + if ($this->batch()->cancelled()) { + $this->fail(new Exception('batch was cancelled')); + } + try { + $federation = $this->membership->federation; + $entity = $this->membership->entity; + EntityFacade::saveMetadataToFederationFolder($entity->id, $federation->id); + + } catch (Exception $e) { + $this->fail($e); + } + + } +} diff --git a/app/Models/Federation.php b/app/Models/Federation.php index b535496..4f6da9a 100644 --- a/app/Models/Federation.php +++ b/app/Models/Federation.php @@ -43,6 +43,11 @@ public function entities() ->withTimestamps(); } + public function memberships() + { + return $this->hasMany(Membership::class); + } + public function scopeVisibleTo($query, User $user) { if ($user->admin) { diff --git a/app/Observers/FederationObserver.php b/app/Observers/FederationObserver.php index 6990d02..65f667a 100644 --- a/app/Observers/FederationObserver.php +++ b/app/Observers/FederationObserver.php @@ -2,8 +2,14 @@ namespace App\Observers; +use App\Jobs\DeleteFederation; +use App\Jobs\RestoreFederation; +use App\Jobs\RunMdaScript; use App\Models\Federation; use App\Services\FederationService; +use Illuminate\Support\Facades\Bus; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; class FederationObserver @@ -34,7 +40,9 @@ public function updated(Federation $federation): void */ public function deleted(Federation $federation): void { - // + if ($federation->approved) { + DeleteFederation::dispatch($federation); + } } /** @@ -42,7 +50,37 @@ public function deleted(Federation $federation): void */ public function restored(Federation $federation): void { - // + $memberships = $federation->memberships; + if ($memberships->count() == 0) { + return; + } + + $jobs = []; + $diskName = config('storageCfg.name'); + $pathToDirectory = Storage::disk($diskName)->path($federation->name); + + foreach ($memberships as $membership) { + $jobs[] = new RestoreFederation($membership); + } + FederationService::createFederationFolder($federation->xml_id); + $lockKey = 'directory-'.md5($pathToDirectory).'-lock'; + $lock = Cache::lock($lockKey, 120); + + Log::info('Branch Start'); + try { + $lock->block(120); + Bus::batch($jobs)->then(function () use ($federation, $lock) { + Log::info('Federation restored'); + RunMdaScript::dispatch($federation, $lock->owner()); + })->dispatch(); + } catch (\Exception $e) { + Log::error($e->getMessage()); + } finally { + if ($lock->isOwnedByCurrentProcess()) { + $lock->release(); + } + } + } /** diff --git a/database/migrations/2024_07_26_083341_create_job_batches_table.php b/database/migrations/2024_07_26_083341_create_job_batches_table.php new file mode 100644 index 0000000..50e38c2 --- /dev/null +++ b/database/migrations/2024_07_26_083341_create_job_batches_table.php @@ -0,0 +1,35 @@ +string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->longText('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('job_batches'); + } +}; diff --git a/tests/Feature/Http/Controllers/FederationControllerTest.php b/tests/Feature/Http/Controllers/FederationControllerTest.php index bbcd19a..f46f041 100644 --- a/tests/Feature/Http/Controllers/FederationControllerTest.php +++ b/tests/Feature/Http/Controllers/FederationControllerTest.php @@ -1126,6 +1126,7 @@ public function an_admin_can_change_an_existing_federations_entities() public function an_admin_can_purge_an_existing_federation() { Notification::fake(); + Queue::fake(); $admin = User::factory()->create(['admin' => true]); User::factory()->create(['admin' => true]);