Add job for inserting members
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Philipp Lang 2023-02-13 15:56:20 +01:00
parent 69451cb8ee
commit c463af3937
24 changed files with 1023 additions and 504 deletions

View File

@ -1,52 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Initialize\Initializer;
use Illuminate\Console\Command;
use Zoomyboy\LaravelNami\NamiException;
class NamiInitializeCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'nami:initialize {--mglnr=} {--password=} {--group_id=}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Initializes nami';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
try {
app(Initializer::class)->run();
} catch (NamiException $e) {
$e->outputToConsole($this);
return 1;
}
return 0;
}
}

View File

@ -14,7 +14,7 @@ class Kernel extends ConsoleKernel
/**
* The Artisan commands provided by your application.
*
* @var array
* @var array<int, class-string>
*/
protected $commands = [
LetterSendAction::class,

View File

@ -11,7 +11,7 @@ class Kernel extends HttpKernel
*
* These middleware are run during every request to your application.
*
* @var array
* @var array<int, string>
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
@ -25,7 +25,7 @@ class Kernel extends HttpKernel
/**
* The application's route middleware groups.
*
* @var array
* @var array<string, array<int, string>>
*/
protected $middlewareGroups = [
'web' => [
@ -51,7 +51,7 @@ class Kernel extends HttpKernel
*
* These middleware may be assigned to groups or used individually.
*
* @var array
* @var array<string, string>
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,

View File

@ -9,7 +9,7 @@ class CheckForMaintenanceMode extends Middleware
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
* @var array<int, string>
*/
protected $except = [
];

View File

@ -9,7 +9,7 @@ class EncryptCookies extends Middleware
/**
* The names of the cookies that should not be encrypted.
*
* @var array
* @var array<int, string>
*/
protected $except = [
];

View File

@ -8,6 +8,9 @@ use Closure;
class RedirectIfNotInitializedMiddleware
{
/**
* @var array<int, string>
*/
public array $dontRedirect = ['initialize.form', 'initialize.store'];
/**

View File

@ -9,7 +9,7 @@ class TrimStrings extends Middleware
/**
* The names of the attributes that should not be trimmed.
*
* @var array
* @var array<int, string>
*/
protected $except = [
'password',

View File

@ -10,7 +10,7 @@ class TrustProxies extends Middleware
/**
* The trusted proxies for this application.
*
* @var array|string
* @var array<int, string>|string|null
*/
protected $proxies;

View File

@ -9,7 +9,7 @@ class VerifyCsrfToken extends Middleware
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
* @var array<int, string>
*/
protected $except = [
];

View File

@ -2,11 +2,12 @@
namespace App\Http\Resources;
use App\User;
use Illuminate\Http\Resources\Json\JsonResource;
use Storage;
/**
* @mixin \App\User
* @mixin User
*/
class UserResource extends JsonResource
{
@ -15,9 +16,9 @@ class UserResource extends JsonResource
*
* @param \Illuminate\Http\Request $request
*
* @return array
* @return array<string, mixed>
*/
public function toArray($request)
public function toArray($request): array
{
return [
'name' => $this->name,

View File

@ -2,13 +2,23 @@
namespace App\Initialize\Actions;
use App\Initialize\InitializeJob;
use App\Initialize\InitializeActivities;
use App\Initialize\InitializeConfessions;
use App\Initialize\InitializeCountries;
use App\Initialize\InitializeCourses;
use App\Initialize\InitializeFees;
use App\Initialize\InitializeGenders;
use App\Initialize\InitializeGroups;
use App\Initialize\InitializeMembers;
use App\Initialize\InitializeNationalities;
use App\Initialize\InitializeRegions;
use App\Setting\NamiSettings;
use Illuminate\Console\Command;
use Illuminate\Http\RedirectResponse;
use Illuminate\Validation\ValidationException;
use Lorisleiva\Actions\ActionRequest;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\LaravelNami\Api;
use Zoomyboy\LaravelNami\Nami;
class InitializeAction
@ -17,9 +27,29 @@ class InitializeAction
public string $commandSignature = 'initialize {--mglnr=} {--password=} {--group=}';
/**
* @var array<int, class-string>
*/
public array $initializers = [
InitializeGroups::class,
InitializeNationalities::class,
InitializeFees::class,
InitializeActivities::class,
InitializeConfessions::class,
InitializeCountries::class,
InitializeGenders::class,
InitializeRegions::class,
InitializeCourses::class,
InitializeMembers::class,
];
private Api $api;
public function handle(int $mglnr, string $password, int $groupId): void
{
InitializeJob::dispatch();
foreach ($this->initializers as $initializer) {
app($initializer)->handle($this->api);
}
}
/**
@ -46,9 +76,9 @@ class InitializeAction
public function asController(ActionRequest $request, NamiSettings $settings): RedirectResponse
{
$api = Nami::login($request->input('mglnr'), $request->input('password'));
$this->api = Nami::login($request->input('mglnr'), $request->input('password'));
if (!$api->hasGroup($request->input('group_id'))) {
if (!$this->api->hasGroup($request->input('group_id'))) {
throw ValidationException::withMessages(['nami' => 'Gruppierung nicht gefunden.']);
}
@ -71,7 +101,7 @@ class InitializeAction
$mglnr = (int) $command->option('mglnr');
$password = $command->option('password');
$group = (int) $command->option('group');
$api = Nami::login($mglnr, $password);
$this->api = Nami::login($mglnr, $password);
$settings->mglnr = $mglnr;
$settings->password = $password;
$settings->default_group_id = $group;

View File

@ -0,0 +1,34 @@
<?php
namespace App\Initialize\Actions;
use App\Actions\InsertCoursesAction;
use App\Actions\InsertMemberAction;
use App\Actions\InsertMembershipsAction;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\LaravelNami\Data\Course as NamiCourse;
use Zoomyboy\LaravelNami\Data\Member as NamiMember;
use Zoomyboy\LaravelNami\Data\MembershipEntry as NamiMembershipEntry;
class ProcessRedisAction
{
use AsAction;
public string $jobQueue = 'single';
/**
* @param array{member: array<string, mixed>, memberships: array<string, mixed>, courses: array<string, mixed>} $data
*/
public function handle(array $data): void
{
$localMember = InsertMemberAction::run(NamiMember::from($data['member']));
InsertMembershipsAction::run(
$localMember,
collect($data['memberships'])->map(fn ($membership) => NamiMembershipEntry::from($membership)),
);
InsertCoursesAction::run(
$localMember,
collect($data['courses'])->map(fn ($course) => NamiCourse::from($course)),
);
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Initialize;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Throwable;
class InitializeJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public function __construct()
{
$this->onQueue('long');
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
app(Initializer::class)->run();
}
public function failed(Throwable $e): void
{
app(Initializer::class)->restore();
}
}

View File

@ -1,57 +0,0 @@
<?php
namespace App\Initialize;
use App\Actions\InsertMemberAction;
use App\Actions\PullCoursesAction;
use App\Actions\PullMembershipsAction;
use App\Nami\Api\MemberAction;
use App\Setting\NamiSettings;
use DB;
use Illuminate\Console\Command;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\LaravelNami\Api;
use Zoomyboy\LaravelNami\Data\MemberEntry as NamiMember;
use Zoomyboy\LaravelNami\Exceptions\Skippable;
class InitializeMember
{
use AsAction;
public function handle(Api $api): void
{
$allMembers = collect([]);
$jobs = $api->search([])->map(function (NamiMember $member) use ($api) {
return MemberAction::makeJob($api, $member->groupId, $member->id);
})->toArray();
$batch = Bus::batch($jobs)
// ->then(function (Batch $batch) {
// $localMember = InsertMemberAction::run();
// })->catch(function (Batch $batch, Throwable $e) {
// // First batch job failure detected...
// })->finally(function (Batch $batch) {
// // The batch has finished executing...
// })
->dispatch();
try {
} catch (Skippable $e) {
return;
}
// app(PullMembershipsAction::class)->handle($localMember);
// app(PullCoursesAction::class)->handle($localMember);
});
$batch = Bus::batch([
new ImportCsv(1, 100),
new ImportCsv(101, 200),
new ImportCsv(201, 300),
new ImportCsv(301, 400),
new ImportCsv(401, 500),
}
}

View File

@ -2,9 +2,7 @@
namespace App\Initialize;
use App\Actions\InsertCoursesAction;
use App\Actions\InsertMemberAction;
use App\Actions\InsertMembershipsAction;
use App\Initialize\Actions\ProcessRedisAction;
use App\Nami\Api\CompleteMemberToRedisJob;
use App\Setting\NamiSettings;
use DB;
@ -12,12 +10,10 @@ use Illuminate\Bus\Batch;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Redis;
use Log;
use Lorisleiva\Actions\Concerns\AsAction;
use Zoomyboy\LaravelNami\Api;
use Zoomyboy\LaravelNami\Data\Course as NamiCourse;
use Zoomyboy\LaravelNami\Data\Member as NamiMember;
use Zoomyboy\LaravelNami\Data\MemberEntry as NamiMemberEntry;
use Zoomyboy\LaravelNami\Data\MembershipEntry as NamiMembershipEntry;
class InitializeMembers
{
@ -37,24 +33,13 @@ class InitializeMembers
$batch = Bus::batch($jobs)
->finally(function (Batch $batch) {
Log::debug('Complete Member count: '.count(Redis::lrange('members', 0, -1)));
foreach (Redis::lrange('members', 0, -1) as $data) {
try {
$data = json_decode($data, true);
$localMember = InsertMemberAction::run(NamiMember::from($data['member']));
InsertMembershipsAction::run(
$localMember,
collect($data['memberships'])->map(fn ($membership) => NamiMembershipEntry::from($membership)),
);
InsertCoursesAction::run(
$localMember,
collect($data['courses'])->map(fn ($course) => NamiCourse::from($course)),
);
} catch (Skippable $e) {
continue;
}
ProcessRedisAction::dispatch(json_decode($data, true));
}
})
->onQueue('long')
->allowFailures()
->dispatch();
}

View File

@ -1,51 +0,0 @@
<?php
namespace App\Initialize;
use App\Setting\NamiSettings;
class Initializer
{
public NamiSettings $settings;
/**
* @var array<int, class-string>
*/
public array $initializers = [
InitializeGroups::class,
InitializeNationalities::class,
InitializeFees::class,
InitializeActivities::class,
InitializeConfessions::class,
InitializeCountries::class,
InitializeGenders::class,
InitializeRegions::class,
InitializeCourses::class,
InitializeMembers::class,
];
public function __construct(NamiSettings $settings)
{
$this->settings = $settings;
}
public function run(): void
{
foreach ($this->initializers as $initializer) {
app($initializer)->handle($this->settings->login());
}
}
public function restore(): void
{
foreach (array_reverse($this->initializers) as $initializer) {
app($initializer)->restore();
}
$settings = app(NamiSettings::class);
$settings->mglnr = 0;
$settings->password = '';
$settings->default_group_id = 0;
$settings->save();
}
}

View File

@ -9,6 +9,7 @@ use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;
use Log;
use Zoomyboy\LaravelNami\Api;
class CompleteMemberToRedisJob implements ShouldQueue
@ -29,6 +30,8 @@ class CompleteMemberToRedisJob implements ShouldQueue
public function handle(): void
{
if ($this->batch()->cancelled()) {
Log::debug('Cancelling batch');
return;
}

View File

@ -12,7 +12,7 @@ class EventServiceProvider extends ServiceProvider
/**
* The event listener mappings for the application.
*
* @var array
* @var array<string, array<int, string>>
*/
protected $listen = [
Registered::class => [

View File

@ -20,14 +20,14 @@
"inertiajs/inertia-laravel": "^0.5.4",
"laravel/framework": "^9.0",
"laravel/horizon": "^5.0",
"laravel/telescope": "^4.0",
"laravel/telescope": "^4.13",
"laravel/tinker": "^2.0",
"laravel/ui": "^3.0",
"lorisleiva/laravel-actions": "^2.4",
"monicahq/laravel-sabre": "^1.6",
"nunomaduro/collision": "^6.1",
"phake/phake": "^4.2",
"spatie/laravel-data": "^2.0",
"spatie/laravel-data": "^3.0",
"spatie/laravel-ignition": "^1.0",
"spatie/laravel-medialibrary": "^10.0",
"spatie/laravel-settings": "^2.2",

1101
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -165,6 +165,13 @@ return [
'environments' => [
'production' => [
'supervisor-single' => [
'connection' => 'redis',
'queue' => ['single'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
],
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
@ -183,6 +190,13 @@ return [
],
'local' => [
'supervisor-single' => [
'connection' => 'redis',
'queue' => ['single'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
],
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],

@ -1 +1 @@
Subproject commit 927bf7a09ce5d1f3cef14e60060c7f885ef140d6
Subproject commit d48383ded42851e9f7231b49142ac31c12b8238b

View File

@ -25,11 +25,6 @@ parameters:
count: 1
path: app/Activity.php
-
message: "#^Property App\\\\Console\\\\Kernel\\:\\:\\$commands type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Console/Kernel.php
-
message: "#^Unable to resolve the template type TKey in call to function collect$#"
count: 1
@ -115,56 +110,6 @@ parameters:
count: 1
path: app/Http/Controllers/Auth/RegisterController.php
-
message: "#^Property App\\\\Http\\\\Kernel\\:\\:\\$middleware type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Kernel.php
-
message: "#^Property App\\\\Http\\\\Kernel\\:\\:\\$middlewareGroups type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Kernel.php
-
message: "#^Property App\\\\Http\\\\Kernel\\:\\:\\$routeMiddleware type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Kernel.php
-
message: "#^Property App\\\\Http\\\\Middleware\\\\CheckForMaintenanceMode\\:\\:\\$except type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Middleware/CheckForMaintenanceMode.php
-
message: "#^Property App\\\\Http\\\\Middleware\\\\EncryptCookies\\:\\:\\$except type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Middleware/EncryptCookies.php
-
message: "#^Property App\\\\Http\\\\Middleware\\\\RedirectIfNotInitializedMiddleware\\:\\:\\$dontRedirect type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Middleware/RedirectIfNotInitializedMiddleware.php
-
message: "#^Property App\\\\Http\\\\Middleware\\\\TrimStrings\\:\\:\\$except type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Middleware/TrimStrings.php
-
message: "#^Property App\\\\Http\\\\Middleware\\\\TrustProxies\\:\\:\\$proxies type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Middleware/TrustProxies.php
-
message: "#^Property App\\\\Http\\\\Middleware\\\\VerifyCsrfToken\\:\\:\\$except type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Middleware/VerifyCsrfToken.php
-
message: "#^Method App\\\\Http\\\\Resources\\\\UserResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Http/Resources/UserResource.php
-
message: "#^Method App\\\\Http\\\\Views\\\\MemberView\\:\\:index\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#"
count: 1
@ -250,11 +195,6 @@ parameters:
count: 1
path: app/Providers/AuthServiceProvider.php
-
message: "#^Property App\\\\Providers\\\\EventServiceProvider\\:\\:\\$listen type has no value type specified in iterable type array\\.$#"
count: 1
path: app/Providers/EventServiceProvider.php
-
message: "#^Property App\\\\Region\\:\\:\\$casts type has no value type specified in iterable type array\\.$#"
count: 1
@ -793,10 +733,6 @@ parameters:
message: "#^Method Zoomyboy\\\\LaravelNami\\\\Tests\\\\TestCase\\:\\:getAnnotations\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: packages/laravel-nami/tests/TestCase.php
-
message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\LazyCollection\\<int,Zoomyboy\\\\LaravelNami\\\\Data\\\\MemberEntry\\>\\:\\:each\\(\\) expects callable\\(int, int\\)\\: mixed, Closure\\(Zoomyboy\\\\LaravelNami\\\\Data\\\\MemberEntry\\)\\: void given\\.$#"
count: 1
path: app/Initialize/InitializeMembers.php
-
message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:never\\(\\)\\.$#"

View File

@ -3,10 +3,8 @@
namespace Tests\Feature\Initialize;
use App\Initialize\Actions\InitializeAction;
use App\Initialize\InitializeJob;
use App\Setting\NamiSettings;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Queue;
use Tests\RequestFactories\InitializeRequestFactory;
use Tests\TestCase;
use Zoomyboy\LaravelNami\Authentication\Auth;
@ -73,16 +71,6 @@ class InitializeActionTest extends TestCase
$this->assertErrors(['nami' => 'Gruppierung nicht gefunden.'], $response);
}
public function testItFiresJobWhenRunningInitializer(): void
{
Queue::fake();
$this->withoutExceptionHandling()->login();
app(InitializeAction::class)->handle(12345, 'secret', 185);
Queue::assertPushed(InitializeJob::class);
}
private function factory(): InitializeRequestFactory
{
return InitializeRequestFactory::new();