Add Contract interface for airport lookup functionality (#365)

* Add Contract interface for airport lookup functionality

* style ci fixes
This commit is contained in:
Nabeel S
2019-08-22 14:32:49 -04:00
committed by GitHub
parent 94ba5d8680
commit 6018a6dcaa
9 changed files with 138 additions and 37 deletions

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Contracts;
use App\Models\Airport;
abstract class AirportLookup
{
/**
* Lookup the information for an airport. Needs to return an instance of the
* Airport model, or an array with the properties listed in the Airport model.
*
* The in-use implementation can be changed in the config/phpvms.php file, so
* different services can be used, in-case vaCentral one isn't working or there
* is a better one available. Don't handle any caching in this layer, that happens
* at the service layer
*
* Return null if there's an error or nothing was found
*
* @example App\Services\AirportLookup\VaCentralLookup
*
* @param string $icao
*
* @return Airport|null
*/
abstract public function getAirport($icao);
}

View File

@@ -5,10 +5,8 @@ namespace App\Http\Controllers\Api;
use App\Contracts\Controller; use App\Contracts\Controller;
use App\Http\Resources\Airport as AirportResource; use App\Http\Resources\Airport as AirportResource;
use App\Repositories\AirportRepository; use App\Repositories\AirportRepository;
use App\Services\AirportService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Log;
use VaCentral\Airport as AirportLookup;
/** /**
* Class AirportController * Class AirportController
@@ -16,16 +14,20 @@ use VaCentral\Airport as AirportLookup;
class AirportController extends Controller class AirportController extends Controller
{ {
private $airportRepo; private $airportRepo;
private $airportSvc;
/** /**
* AirportController constructor. * AirportController constructor.
* *
* @param AirportRepository $airportRepo * @param AirportRepository $airportRepo
* @param AirportService $airportSvc
*/ */
public function __construct( public function __construct(
AirportRepository $airportRepo AirportRepository $airportRepo,
AirportService $airportSvc
) { ) {
$this->airportRepo = $airportRepo; $this->airportRepo = $airportRepo;
$this->airportSvc = $airportSvc;
} }
/** /**
@@ -88,19 +90,7 @@ class AirportController extends Controller
*/ */
public function lookup($id) public function lookup($id)
{ {
$airport = Cache::remember( $airport = $this->airportSvc->lookupAirport($id);
config('cache.keys.AIRPORT_VACENTRAL_LOOKUP.key').$id,
config('cache.keys.AIRPORT_VACENTRAL_LOOKUP.time'),
function () use ($id) {
try {
return AirportLookup::get($id);
} catch (\VaCentral\HttpException $e) {
Log::error($e);
return [];
}
}
);
return new AirportResource(collect($airport)); return new AirportResource(collect($airport));
} }
} }

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Providers;
use App\Contracts\AirportLookup;
use App\Contracts\Metar;
use Illuminate\Support\ServiceProvider;
class BindServiceProviders extends ServiceProvider
{
public function boot(): void
{
/*
* Bind the class used to fullfill the Metar class contract
*/
$this->app->bind(
Metar::class,
config('phpvms.metar_lookup')
);
/*
* Bind the class used to fullfill the AirportLookup class contract
*/
$this->app->bind(
AirportLookup::class,
config('phpvms.airport_lookup')
);
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace App\Providers;
use App\Contracts\Metar;
use Illuminate\Support\ServiceProvider;
class WeatherServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->app->bind(
Metar::class,
config('phpvms.metar')
);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Services\AirportLookup;
use App\Contracts\AirportLookup;
use Illuminate\Support\Facades\Log;
use VaCentral\Airport;
use VaCentral\HttpException;
class VaCentralLookup extends AirportLookup
{
/**
* Lookup the information for an airport
*
* @param string $icao
*
* @return array
*/
public function getAirport($icao)
{
try {
return Airport::get($icao);
} catch (HttpException $e) {
Log::error($e);
return;
}
}
}

View File

@@ -2,20 +2,27 @@
namespace App\Services; namespace App\Services;
use App\Contracts\AirportLookup as AirportLookupProvider;
use App\Contracts\Metar as MetarProvider; use App\Contracts\Metar as MetarProvider;
use App\Contracts\Service; use App\Contracts\Service;
use App\Support\Metar; use App\Support\Metar;
use Illuminate\Support\Facades\Cache;
use VaCentral\Airport;
/** /**
* Class AnalyticsService * Class AnalyticsService
*/ */
class AirportService extends Service class AirportService extends Service
{ {
private $lookupProvider;
private $metarProvider; private $metarProvider;
public function __construct( public function __construct(
AirportLookupProvider $lookupProvider,
MetarProvider $metarProvider MetarProvider $metarProvider
) { ) {
$this->lookupProvider = $lookupProvider;
$this->metarProvider = $metarProvider; $this->metarProvider = $metarProvider;
} }
@@ -38,4 +45,35 @@ class AirportService extends Service
return new Metar($raw_metar); return new Metar($raw_metar);
} }
} }
/**
* Lookup an airport's information from a remote provider. This handles caching
* the data internally
*
* @param string $icao ICAO
*
* @return Airport|array
*/
public function lookupAirport($icao)
{
$key = config('cache.keys.AIRPORT_VACENTRAL_LOOKUP.key').$icao;
$airport = Cache::get($key);
if ($airport) {
return $airport;
}
$airport = $this->lookupProvider->getAirport($icao);
if ($airport === null) {
return [];
}
Cache::add(
$key,
$airport,
config('cache.keys.AIRPORT_VACENTRAL_LOOKUP.time')
);
return $airport;
}
} }

View File

@@ -87,7 +87,7 @@ return [
App\Providers\vaCentralServiceProvider::class, App\Providers\vaCentralServiceProvider::class,
App\Providers\ExtendedTimezonelistProvider::class, App\Providers\ExtendedTimezonelistProvider::class,
App\Providers\MeasurementsProvider::class, App\Providers\MeasurementsProvider::class,
App\Providers\WeatherServiceProvider::class, App\Providers\BindServiceProviders::class,
], ],
'aliases' => [ 'aliases' => [

View File

@@ -47,7 +47,13 @@ return [
* Point to the class to use to retrieve the METAR string. If this * Point to the class to use to retrieve the METAR string. If this
* goes inactive at some date, it can be replaced * goes inactive at some date, it can be replaced
*/ */
'metar' => App\Services\Metar\AviationWeather::class, 'metar_lookup' => App\Services\Metar\AviationWeather::class,
/*
* Point to the class used to retrieve the airport information.
* If this goes inactive at some date, it can be replaced
*/
'airport_lookup' => App\Services\AirportLookup\VaCentralLookup::class,
/* /*
* Your vaCentral API key * Your vaCentral API key

View File

@@ -26,7 +26,7 @@
<env name="APP_ENV" value="unittest"/> <env name="APP_ENV" value="unittest"/>
<env name="APP_KEY" value="base64:ve66Z5Kt/zTN3p++0zOPu854PHfZkwJE5VuoFAlzHtI="/> <env name="APP_KEY" value="base64:ve66Z5Kt/zTN3p++0zOPu854PHfZkwJE5VuoFAlzHtI="/>
<env name="APP_DEBUG" value="true"/> <env name="APP_DEBUG" value="true"/>
<env name="APP_LOG_LEVEL" value="info"/> <env name="APP_LOG_LEVEL" value="error"/>
<env name="DB_CONNECTION" value="memory"/> <env name="DB_CONNECTION" value="memory"/>
<env name="CACHE_DRIVER" value="array"/> <env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/>