Skip to content

Commit

Permalink
Merge branch '#2-add-getting-data-from-github-api' of https://github.…
Browse files Browse the repository at this point in the history
…com/blumilksoftware/gha-analyzer into #51-getting-and-displaying-data-from-db
  • Loading branch information
Wiktor-Wojciechowski committed Jul 9, 2024
2 parents 3ee6aa6 + 3da145c commit 1d9fbaa
Show file tree
Hide file tree
Showing 17 changed files with 208 additions and 22 deletions.
20 changes: 20 additions & 0 deletions app/Http/Controllers/GithubController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

namespace App\Http\Controllers;

use App\Http\Integrations\GithubConnector;
use App\Jobs\FetchDataFromApi;
use App\Models\User;
use App\Services\AssignUserToOrganizationsService;
use App\Services\FetchRepositoriesService;
use App\Services\FetchWorkflowJobsService;
use App\Services\FetchWorkflowRunsService;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use Symfony\Component\HttpFoundation\RedirectResponse;
Expand Down Expand Up @@ -40,4 +45,19 @@ public function callback(): RedirectResponse

return redirect("/");
}

public function fetchData($organizationId): RedirectResponse
{
$userId = Auth::user()->id;

FetchDataFromApi::dispatch(
(int)$organizationId,
$githubConnector = new GithubConnector(),
new FetchRepositoriesService($githubConnector, $userId),
new FetchWorkflowRunsService($githubConnector, $userId),
new FetchWorkflowJobsService($githubConnector, $userId),
);

return redirect()->back();
}
}
31 changes: 31 additions & 0 deletions app/Http/Integrations/GithubConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@

namespace App\Http\Integrations;

use Illuminate\Support\Facades\Cache;
use Saloon\Http\Connector;
use Saloon\Http\Response;
use Saloon\RateLimitPlugin\Contracts\RateLimitStore;
use Saloon\RateLimitPlugin\Helpers\RetryAfterHelper;
use Saloon\RateLimitPlugin\Limit;
use Saloon\RateLimitPlugin\Stores\LaravelCacheStore;
use Saloon\RateLimitPlugin\Traits\HasRateLimits;
use Saloon\Traits\Plugins\AlwaysThrowOnErrors;

class GithubConnector extends Connector
{
use AlwaysThrowOnErrors;
use HasRateLimits;

public function resolveBaseUrl(): string
{
Expand All @@ -23,4 +31,27 @@ protected function defaultHeaders(): array
"Accept" => "application/json",
];
}

protected function resolveLimits(): array
{
return [
Limit::allow(config("services.rate_limit"))->everyHour(),
];
}

protected function resolveRateLimitStore(): RateLimitStore
{
return new LaravelCacheStore(Cache::store("redis"));
}

protected function handleTooManyAttempts(Response $response, Limit $limit): void
{
if ($response->status() !== 429 && $response->status() !== 403) {
return;
}

$limit->exceeded(
releaseInSeconds: RetryAfterHelper::parse($response->header("Retry-After")),
);
}
}
7 changes: 4 additions & 3 deletions app/Http/Integrations/Requests/GetRepositoriesRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use App\DTO\OrganizationDTO;
use App\DTO\RepositoryDTO;
use App\Models\Organization;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
Expand All @@ -19,11 +19,12 @@ class GetRepositoriesRequest extends Request

public function __construct(
protected OrganizationDTO $organizationDto,
protected User $user,
) {}

public function resolveEndpoint(): string
{
return "/orgs" . $this->organizationDto->name . "/repos";
return "/orgs/" . $this->organizationDto->name . "/repos";
}

public function createDtoFromResponse(Response $response): Collection
Expand All @@ -49,7 +50,7 @@ public function createDtoFromResponse(Response $response): Collection
protected function defaultHeaders(): array
{
return [
"Authorization" => "Bearer " . Auth::user()->github_token,
"Authorization" => "Bearer " . $this->user->github_token,
];
}
}
5 changes: 3 additions & 2 deletions app/Http/Integrations/Requests/GetWorkflowJobsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

use App\DTO\WorkflowJobDTO;
use App\DTO\WorkflowRunDTO;
use App\Models\User;
use App\Models\WorkflowRun;
use App\Services\CalculateJobTimeService;
use App\Services\GetRunnerDataService;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
Expand All @@ -23,6 +23,7 @@ public function __construct(
protected WorkflowRunDTO $workflowRunDto,
protected string $organizationName,
protected string $repositoryName,
protected User $user,
) {}

public function resolveEndpoint(): string
Expand Down Expand Up @@ -62,7 +63,7 @@ public function createDtoFromResponse(Response $response): Collection
protected function defaultHeaders(): array
{
return [
"Authorization" => "Bearer " . Auth::user()->github_token,
"Authorization" => "Bearer " . $this->user->github_token,
];
}
}
5 changes: 3 additions & 2 deletions app/Http/Integrations/Requests/GetWorkflowRunsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
use App\DTO\WorkflowRunDTO;
use App\Models\Organization;
use App\Models\Repository;
use App\Models\User;
use DateTime;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Http\Response;
Expand All @@ -21,6 +21,7 @@ class GetWorkflowRunsRequest extends Request

public function __construct(
protected RepositoryDTO $repositoryDto,
protected User $user,
) {}

public function resolveEndpoint(): string
Expand Down Expand Up @@ -55,7 +56,7 @@ public function createDtoFromResponse(Response $response): Collection
protected function defaultHeaders(): array
{
return [
"Authorization" => "Bearer " . Auth::user()->github_token,
"Authorization" => "Bearer " . $this->user->github_token,
];
}
}
63 changes: 63 additions & 0 deletions app/Jobs/FetchDataFromApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace App\Jobs;

use App\DTO\OrganizationDTO;
use App\Http\Integrations\GithubConnector;
use App\Models\Organization;
use App\Services\FetchRepositoriesService;
use App\Services\FetchWorkflowJobsService;
use App\Services\FetchWorkflowRunsService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Saloon\RateLimitPlugin\Helpers\ApiRateLimited;

class FetchDataFromApi implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;

public function __construct(
protected int $organizationId,
protected GithubConnector $githubConnector,
protected FetchRepositoriesService $fetchRepositoriesService,
protected FetchWorkflowRunsService $fetchWorkflowRunsService,
protected FetchWorkflowJobsService $fetchWorkflowJobsService,
) {}

public function handle(): void
{
$organization = Organization::query()->where("id", $this->organizationId)->firstOrFail();
$organizationDto = new OrganizationDTO(
$organization->name,
$organization->github_id,
$organization->avatar_url,
);

$repositories = collect();
$repositories = $this->fetchRepositoriesService->fetchRepositories($organizationDto);

$workflowRuns = collect();

foreach ($repositories as $repositoryDto) {
$workflowRuns = $workflowRuns->union($this->fetchWorkflowRunsService->fetchWorkflowRuns($repositoryDto));
}

foreach ($workflowRuns as $workflowRunDto) {
$this->fetchWorkflowJobsService->fetchWorkflowJobs($workflowRunDto);
}
}

public function middleware(): array
{
return [new ApiRateLimited()];
}
}
10 changes: 6 additions & 4 deletions app/Services/FetchRepositoriesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@
use App\Models\User;
use Exception;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\UnauthorizedException;

class FetchRepositoriesService
{
public function __construct(
protected GithubConnector $githubConnector,
protected int $userId,
) {}

public function fetchRepositories(OrganizationDTO $organizationDto): void
public function fetchRepositories(OrganizationDTO $organizationDto): Collection
{
$organization = Organization::query()->where("github_id", $organizationDto->githubId)->firstOrFail();
$user = User::query()->where("id", Auth::user()->id)->firstOrFail();
$user = User::query()->where("id", $this->userId)->firstOrFail();

$userOrganizationExists = $user->organizations()
->where("organization_id", $organization->id)
Expand All @@ -34,11 +34,13 @@ public function fetchRepositories(OrganizationDTO $organizationDto): void

if ($userOrganizationExists) {
try {
$request = new GetRepositoriesRequest($organizationDto);
$request = new GetRepositoriesRequest($organizationDto, $user);

$response = $this->githubConnector->send($request);

$this->storeRepositories($response->dto());

return $response->dto();
} catch (Exception $exception) {
throw new FetchingRepositoriesErrorException(
message: "Error ocurred while fetching repositories",
Expand Down
6 changes: 3 additions & 3 deletions app/Services/FetchWorkflowJobsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
use App\Models\WorkflowRun;
use Exception;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\UnauthorizedException;

class FetchWorkflowJobsService
{
public function __construct(
protected GithubConnector $githubConnector,
protected int $userId,
) {}

public function fetchWorkflowJobs(WorkflowRunDTO $workflowRunDto): void
Expand All @@ -40,7 +40,7 @@ public function fetchWorkflowJobs(WorkflowRunDTO $workflowRunDto): void
->where("id", $repository->organization_id)
->firstOrFail();

$user = User::query()->where("id", Auth::user()->id)->firstOrFail();
$user = User::query()->where("id", $this->userId)->firstOrFail();

$userOrganizationExists = $user->organizations()
->where("organization_id", $organization->id)
Expand All @@ -49,7 +49,7 @@ public function fetchWorkflowJobs(WorkflowRunDTO $workflowRunDto): void

if ($userOrganizationExists) {
try {
$request = new GetWorkflowJobsRequest($workflowRunDto, $organization->name, $repository->name);
$request = new GetWorkflowJobsRequest($workflowRunDto, $organization->name, $repository->name, $user);

$response = $this->githubConnector->send($request);

Expand Down
10 changes: 6 additions & 4 deletions app/Services/FetchWorkflowRunsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@
use App\Models\WorkflowRun;
use Exception;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\UnauthorizedException;

class FetchWorkflowRunsService
{
public function __construct(
protected GithubConnector $githubConnector,
protected int $userId,
) {}

public function fetchWorkflowRuns(RepositoryDTO $repositoryDto): void
public function fetchWorkflowRuns(RepositoryDTO $repositoryDto): Collection
{
$organization = Organization::query()->where("id", $repositoryDto->organizationId)->firstOrFail();
$user = User::query()->where("id", Auth::user()->id)->firstOrFail();
$user = User::query()->where("id", $this->userId)->firstOrFail();

$userOrganizationExists = $user->organizations()
->where("organization_id", $organization->id)
Expand All @@ -34,11 +34,13 @@ public function fetchWorkflowRuns(RepositoryDTO $repositoryDto): void

if ($userOrganizationExists) {
try {
$request = new GetWorkflowRunsRequest($repositoryDto);
$request = new GetWorkflowRunsRequest($repositoryDto, $user);

$response = $this->githubConnector->send($request);

$this->storeWorkflowRuns($response->dto());

return $response->dto();
} catch (Exception $exception) {
throw new FetchingWorkflowRunsErrorException(
message: "Error ocurred while fetching workflow runs",
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"laravel/socialite": "^5.14",
"laravel/tinker": "^2.9",
"nesbot/carbon": "^3.6",
"saloonphp/rate-limit-plugin": "^2.0",
"saloonphp/saloon": "^3.0"
},
"require-dev": {
Expand Down
Loading

0 comments on commit 1d9fbaa

Please sign in to comment.