chore: Move volume api to abstract server provider interface

pull/213/head
NaiJi ✨ 2023-04-24 12:09:23 -03:00
parent f6591cbfc6
commit 3b49805c9c
8 changed files with 101 additions and 67 deletions

View File

@ -1,22 +1,10 @@
import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/api_factory_creator.dart';
import 'package:selfprivacy/logic/providers/provider_settings.dart'; import 'package:selfprivacy/logic/providers/provider_settings.dart';
import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart'; import 'package:selfprivacy/logic/api_maps/rest_maps/dns_providers/dns_provider_factory.dart';
import 'package:selfprivacy/logic/api_maps/rest_maps/server_providers/server_provider_factory.dart';
class ApiController { class ApiController {
static VolumeProviderApiFactory? get currentVolumeProviderApiFactory =>
_volumeProviderApiFactory;
static DnsProviderApiFactory? get currentDnsProviderApiFactory => static DnsProviderApiFactory? get currentDnsProviderApiFactory =>
_dnsProviderApiFactory; _dnsProviderApiFactory;
static ServerProviderApiFactory? get currentServerProviderApiFactory =>
_serverProviderApiFactory;
static void initVolumeProviderApiFactory(
final ServerProviderSettings settings,
) {
_volumeProviderApiFactory =
VolumeApiFactoryCreator.createVolumeProviderApiFactory(settings);
}
static void initDnsProviderApiFactory( static void initDnsProviderApiFactory(
final DnsProviderFactorySettings settings, final DnsProviderFactorySettings settings,
@ -25,20 +13,9 @@ class ApiController {
ApiFactoryCreator.createDnsProviderApiFactory(settings); ApiFactoryCreator.createDnsProviderApiFactory(settings);
} }
static void initServerProviderApiFactory(
final ServerProviderSettings settings,
) {
_serverProviderApiFactory =
ApiFactoryCreator.createServerProviderApiFactory(settings);
}
static void clearProviderApiFactories() { static void clearProviderApiFactories() {
_volumeProviderApiFactory = null;
_dnsProviderApiFactory = null; _dnsProviderApiFactory = null;
_serverProviderApiFactory = null;
} }
static VolumeProviderApiFactory? _volumeProviderApiFactory;
static DnsProviderApiFactory? _dnsProviderApiFactory; static DnsProviderApiFactory? _dnsProviderApiFactory;
static ServerProviderApiFactory? _serverProviderApiFactory;
} }

View File

@ -95,13 +95,6 @@ class DigitalOceanApi extends ServerProviderApi with VolumeProviderApi {
); );
} }
/// Hardcoded on their documentation and there is no pricing API at all
/// Probably we should scrap the doc page manually
Future<Price?> getPricePerGb() async => Price(
value: 0.10,
currency: 'USD',
);
Future<GenericResult> createVolume() async { Future<GenericResult> createVolume() async {
Response? createVolumeResponse; Response? createVolumeResponse;
final Dio client = await getClient(); final Dio client = await getClient();

View File

@ -305,7 +305,7 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
); );
} }
Future<bool> resizeVolume( Future<GenericResult<bool>> resizeVolume(
final ServerVolume volume, final ServerVolume volume,
final DiskSize size, final DiskSize size,
) async { ) async {
@ -324,11 +324,19 @@ class HetznerApi extends ServerProviderApi with VolumeProviderApi {
resizeVolumeResponse.data['action']['status'].toString() != 'error'; resizeVolumeResponse.data['action']['status'].toString() != 'error';
} catch (e) { } catch (e) {
print(e); print(e);
return GenericResult(
data: false,
success: false,
message: e.toString(),
);
} finally { } finally {
client.close(); client.close();
} }
return success; return GenericResult(
data: success,
success: true,
);
} }
Future<GenericResult> createServer({ Future<GenericResult> createServer({

View File

@ -10,6 +10,7 @@ import 'package:selfprivacy/logic/models/disk_size.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart'; import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/disk_status.dart'; import 'package:selfprivacy/logic/models/disk_status.dart';
import 'package:selfprivacy/logic/models/price.dart'; import 'package:selfprivacy/logic/models/price.dart';
import 'package:selfprivacy/logic/providers/providers_controller.dart';
part 'provider_volume_state.dart'; part 'provider_volume_state.dart';
@ -27,9 +28,7 @@ class ApiProviderVolumeCubit
} }
Future<Price?> getPricePerGb() async => Future<Price?> getPricePerGb() async =>
ApiController.currentVolumeProviderApiFactory! ProvidersController.currentServerProvider!.getPricePerGb();
.getVolumeProvider()
.getPricePerGb();
Future<void> refresh() async { Future<void> refresh() async {
emit(const ApiProviderVolumeState([], LoadingStatus.refreshing, false)); emit(const ApiProviderVolumeState([], LoadingStatus.refreshing, false));
@ -41,29 +40,31 @@ class ApiProviderVolumeCubit
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false)); return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
} }
final List<ServerVolume> volumes = await ApiController final volumesResult =
.currentVolumeProviderApiFactory! await ProvidersController.currentServerProvider!.getVolumes();
.getVolumeProvider()
.getVolumes();
if (volumes.isEmpty) { if (!volumesResult.success || volumesResult.data.isEmpty) {
return emit(const ApiProviderVolumeState([], LoadingStatus.error, false)); return emit(const ApiProviderVolumeState([], LoadingStatus.error, false));
} }
emit(ApiProviderVolumeState(volumes, LoadingStatus.success, false)); emit(
ApiProviderVolumeState(
volumesResult.data,
LoadingStatus.success,
false,
),
);
} }
Future<void> attachVolume(final DiskVolume volume) async { Future<void> attachVolume(final DiskVolume volume) async {
final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!; final ServerHostingDetails server = getIt<ApiConfigModel>().serverDetails!;
await ApiController.currentVolumeProviderApiFactory! await ProvidersController.currentServerProvider!
.getVolumeProvider()
.attachVolume(volume.providerVolume!, server.id); .attachVolume(volume.providerVolume!, server.id);
unawaited(refresh()); unawaited(refresh());
} }
Future<void> detachVolume(final DiskVolume volume) async { Future<void> detachVolume(final DiskVolume volume) async {
await ApiController.currentVolumeProviderApiFactory! await ProvidersController.currentServerProvider!
.getVolumeProvider()
.detachVolume(volume.providerVolume!); .detachVolume(volume.providerVolume!);
unawaited(refresh()); unawaited(refresh());
} }
@ -77,14 +78,13 @@ class ApiProviderVolumeCubit
'Starting resize', 'Starting resize',
); );
emit(state.copyWith(isResizing: true)); emit(state.copyWith(isResizing: true));
final bool resized = await ApiController.currentVolumeProviderApiFactory! final resizedResult =
.getVolumeProvider() await ProvidersController.currentServerProvider!.resizeVolume(
.resizeVolume( volume.providerVolume!,
volume.providerVolume!, newSize,
newSize, );
);
if (!resized) { if (!resizedResult.success || !resizedResult.data) {
getIt<NavigationService>().showSnackBar( getIt<NavigationService>().showSnackBar(
'storage.extending_volume_error'.tr(), 'storage.extending_volume_error'.tr(),
); );
@ -115,11 +115,8 @@ class ApiProviderVolumeCubit
} }
Future<void> createVolume() async { Future<void> createVolume() async {
final ServerVolume? volume = (await ApiController final ServerVolume? volume =
.currentVolumeProviderApiFactory! (await ProvidersController.currentServerProvider!.createVolume()).data;
.getVolumeProvider()
.createVolume())
.data;
final diskVolume = DiskVolume(providerVolume: volume); final diskVolume = DiskVolume(providerVolume: volume);
await attachVolume(diskVolume); await attachVolume(diskVolume);
@ -131,8 +128,7 @@ class ApiProviderVolumeCubit
} }
Future<void> deleteVolume(final DiskVolume volume) async { Future<void> deleteVolume(final DiskVolume volume) async {
await ApiController.currentVolumeProviderApiFactory! await ProvidersController.currentServerProvider!
.getVolumeProvider()
.deleteVolume(volume.providerVolume!); .deleteVolume(volume.providerVolume!);
unawaited(refresh()); unawaited(refresh());
} }

View File

@ -1,7 +1,10 @@
import 'package:selfprivacy/logic/api_maps/generic_result.dart'; import 'package:selfprivacy/logic/api_maps/generic_result.dart';
import 'package:selfprivacy/logic/models/callback_dialogue_branching.dart'; import 'package:selfprivacy/logic/models/callback_dialogue_branching.dart';
import 'package:selfprivacy/logic/models/disk_size.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/launch_installation_data.dart'; import 'package:selfprivacy/logic/models/launch_installation_data.dart';
import 'package:selfprivacy/logic/models/metrics.dart'; import 'package:selfprivacy/logic/models/metrics.dart';
import 'package:selfprivacy/logic/models/price.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart'; import 'package:selfprivacy/logic/models/server_provider_location.dart';
import 'package:selfprivacy/logic/models/server_type.dart'; import 'package:selfprivacy/logic/models/server_type.dart';
@ -26,5 +29,18 @@ abstract class ServerProvider {
final DateTime end, final DateTime end,
); );
Future<Price?> getPricePerGb();
Future<GenericResult<List<ServerVolume>>> getVolumes({final String? status});
Future<GenericResult<ServerVolume?>> createVolume();
Future<GenericResult<void>> deleteVolume(final ServerVolume volume);
Future<GenericResult<bool>> resizeVolume(
final ServerVolume volume,
final DiskSize size,
);
Future<GenericResult<bool>> attachVolume(
final ServerVolume volume,
final int serverId,
);
Future<GenericResult<bool>> detachVolume(final ServerVolume volume);
GenericResult<bool> get success => GenericResult(success: true, data: true); GenericResult<bool> get success => GenericResult(success: true, data: true);
} }

View File

@ -610,6 +610,7 @@ class DigitalOceanServerProvider extends ServerProvider {
); );
} }
@override
Future<GenericResult<List<ServerVolume>>> getVolumes({ Future<GenericResult<List<ServerVolume>>> getVolumes({
final String? status, final String? status,
}) async { }) async {
@ -658,6 +659,7 @@ class DigitalOceanServerProvider extends ServerProvider {
); );
} }
@override
Future<GenericResult<ServerVolume?>> createVolume() async { Future<GenericResult<ServerVolume?>> createVolume() async {
ServerVolume? volume; ServerVolume? volume;
@ -729,6 +731,7 @@ class DigitalOceanServerProvider extends ServerProvider {
); );
} }
@override
Future<GenericResult<void>> deleteVolume( Future<GenericResult<void>> deleteVolume(
final ServerVolume volume, final ServerVolume volume,
) async => ) async =>
@ -736,6 +739,7 @@ class DigitalOceanServerProvider extends ServerProvider {
volume.uuid!, volume.uuid!,
); );
@override
Future<GenericResult<bool>> attachVolume( Future<GenericResult<bool>> attachVolume(
final ServerVolume volume, final ServerVolume volume,
final int serverId, final int serverId,
@ -745,6 +749,7 @@ class DigitalOceanServerProvider extends ServerProvider {
serverId, serverId,
); );
@override
Future<GenericResult<bool>> detachVolume( Future<GenericResult<bool>> detachVolume(
final ServerVolume volume, final ServerVolume volume,
) async => ) async =>
@ -753,6 +758,7 @@ class DigitalOceanServerProvider extends ServerProvider {
volume.serverId!, volume.serverId!,
); );
@override
Future<GenericResult<bool>> resizeVolume( Future<GenericResult<bool>> resizeVolume(
final ServerVolume volume, final ServerVolume volume,
final DiskSize size, final DiskSize size,
@ -761,4 +767,33 @@ class DigitalOceanServerProvider extends ServerProvider {
volume.name, volume.name,
size, size,
); );
/// Hardcoded on their documentation and there is no pricing API at all
/// Probably we should scrap the doc page manually
@override
Future<Price?> getPricePerGb() async => Price(
value: 0.10,
currency: 'USD',
);
@override
Future<GenericResult<DateTime?>> powerOn(final int serverId) async {
DateTime? timestamp;
final result = await _adapter.api().powerOn(serverId);
if (!result.success) {
return GenericResult(
success: false,
data: timestamp,
code: result.code,
message: result.message,
);
}
timestamp = DateTime.now();
return GenericResult(
success: true,
data: timestamp,
);
}
} }

View File

@ -7,7 +7,6 @@ import 'package:selfprivacy/logic/models/disk_size.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart'; import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/server_domain.dart'; import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart'; import 'package:selfprivacy/logic/models/json/hetzner_server_info.dart';
import 'package:selfprivacy/logic/models/launch_installation_data.dart';
import 'package:selfprivacy/logic/models/metrics.dart'; import 'package:selfprivacy/logic/models/metrics.dart';
import 'package:selfprivacy/logic/models/price.dart'; import 'package:selfprivacy/logic/models/price.dart';
import 'package:selfprivacy/logic/models/server_basic_info.dart'; import 'package:selfprivacy/logic/models/server_basic_info.dart';
@ -434,7 +433,7 @@ class HetznerServerProvider extends ServerProvider {
); );
} }
final volume = volumeResult.data!; final volume = volumeResult.data;
final serverApiToken = StringGenerators.apiToken(); final serverApiToken = StringGenerators.apiToken();
final hostname = getHostnameFromDomain(installationData.domainName); final hostname = getHostnameFromDomain(installationData.domainName);
@ -632,6 +631,7 @@ class HetznerServerProvider extends ServerProvider {
); );
} }
@override
Future<GenericResult<ServerVolume?>> createVolume() async { Future<GenericResult<ServerVolume?>> createVolume() async {
ServerVolume? volume; ServerVolume? volume;
@ -676,6 +676,7 @@ class HetznerServerProvider extends ServerProvider {
); );
} }
@override
Future<GenericResult<List<ServerVolume>>> getVolumes({ Future<GenericResult<List<ServerVolume>>> getVolumes({
final String? status, final String? status,
}) async { }) async {
@ -724,9 +725,11 @@ class HetznerServerProvider extends ServerProvider {
); );
} }
Future<GenericResult<void>> deleteVolume(final int volumeId) async => @override
_adapter.api().deleteVolume(volumeId); Future<GenericResult<void>> deleteVolume(final ServerVolume volume) async =>
_adapter.api().deleteVolume(volume.id);
@override
Future<GenericResult<bool>> attachVolume( Future<GenericResult<bool>> attachVolume(
final ServerVolume volume, final ServerVolume volume,
final int serverId, final int serverId,
@ -736,14 +739,16 @@ class HetznerServerProvider extends ServerProvider {
serverId, serverId,
); );
@override
Future<GenericResult<bool>> detachVolume( Future<GenericResult<bool>> detachVolume(
final int volumeId, final ServerVolume volume,
) async => ) async =>
_adapter.api().detachVolume( _adapter.api().detachVolume(
volumeId, volume.id,
); );
Future<bool> resizeVolume( @override
Future<GenericResult<bool>> resizeVolume(
final ServerVolume volume, final ServerVolume volume,
final DiskSize size, final DiskSize size,
) async => ) async =>
@ -751,4 +756,7 @@ class HetznerServerProvider extends ServerProvider {
volume, volume,
size, size,
); );
@override
Future<Price?> getPricePerGb() async => _adapter.api().getPricePerGb();
} }

View File

@ -10,7 +10,8 @@
part of 'router.dart'; part of 'router.dart';
abstract class _$RootRouter extends RootStackRouter { abstract class _$RootRouter extends RootStackRouter {
_$RootRouter([GlobalKey<NavigatorState>? navigatorKey]) : super(navigatorKey); _$RootRouter([GlobalKey<NavigatorState>? navigatorKey])
: super(navigatorKey: navigatorKey);
@override @override
final Map<String, PageFactory> pagesMap = { final Map<String, PageFactory> pagesMap = {