blob: c44360dc7089da6289bb24310e3ca3b7e0e706ea [file] [log] [blame]
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:appengine/appengine.dart';
import 'package:cocoon_service/cocoon_service.dart';
import 'package:cocoon_service/src/model/appengine/service_account_info.dart';
import 'package:cocoon_service/src/service/github_checks_service.dart';
import 'package:cocoon_service/src/service/github_status_service.dart';
import 'package:cocoon_service/src/service/luci_build_service.dart';
import 'package:gcloud/db.dart';
/// For local development, you might want to set this to true.
const String _kCocoonUseInMemoryCache = 'COCOON_USE_IN_MEMORY_CACHE';
Future<void> main() async {
await withAppEngineServices(() async {
final bool inMemoryCache =
Platform.environment[_kCocoonUseInMemoryCache] == 'true';
final CacheService cache = CacheService(inMemory: inMemoryCache);
final Config config = Config(dbService, cache);
final AuthenticationProvider authProvider = AuthenticationProvider(config);
final BuildBucketClient buildBucketClient = BuildBucketClient(
accessTokenService: AccessTokenService.defaultProvider(config),
);
final ServiceAccountInfo serviceAccountInfo =
await config.deviceLabServiceAccount;
/// LUCI service class to communicate with buildBucket service.
final LuciBuildService luciBuildService = LuciBuildService(
config,
buildBucketClient,
serviceAccountInfo,
);
/// Github status service to update the state of the build
/// in the Github UI.
final GithubStatusService githubStatusService = GithubStatusService(
config,
luciBuildService,
);
/// Github checks api service used to provide luci test execution status on the Github UI.
final GithubChecksService githubChecksService = GithubChecksService(
config,
);
final Map<String, RequestHandler<dynamic>> handlers =
<String, RequestHandler<dynamic>>{
'/api/append-log': AppendLog(config, authProvider),
'/api/authorize-agent': AuthorizeAgent(config, authProvider),
'/api/check-waiting-pull-requests':
CheckForWaitingPullRequests(config, authProvider),
'/api/create-agent': CreateAgent(config, authProvider),
'/api/get-authentication-status':
GetAuthenticationStatus(config, authProvider),
'/api/get-log': GetLog(config, authProvider),
'/api/github-webhook-pullrequest': GithubWebhook(
config,
buildBucketClient,
luciBuildService,
githubStatusService,
githubChecksService,
),
'/api/luci-status-handler': LuciStatusHandler(config, buildBucketClient),
'/api/push-build-status-to-github':
PushBuildStatusToGithub(config, authProvider),
'/api/push-gold-status-to-github':
PushGoldStatusToGithub(config, authProvider),
'/api/push-engine-build-status-to-github':
PushEngineStatusToGithub(config, authProvider),
'/api/refresh-chromebot-status':
RefreshChromebotStatus(config, authProvider),
'/api/refresh-github-commits': RefreshGithubCommits(config, authProvider),
'/api/refresh-cirrus-status': RefreshCirrusStatus(config, authProvider),
'/api/reserve-task': ReserveTask(config, authProvider),
'/api/reset-devicelab-task': ResetDevicelabTask(config, authProvider),
'/api/update-agent-health': UpdateAgentHealth(config, authProvider),
'/api/update-agent-health-history':
UpdateAgentHealthHistory(config, authProvider),
'/api/update-benchmark-targets':
UpdateBenchmarkTargets(config, authProvider),
'/api/update-task-status': UpdateTaskStatus(config, authProvider),
'/api/update-timeseries': UpdateTimeSeries(config, authProvider),
'/api/vacuum-clean': VacuumClean(config, authProvider),
'/api/public/build-status': CacheRequestHandler<Body>(
cache: cache,
config: config,
delegate: GetBuildStatus(config),
ttl: const Duration(seconds: 15),
),
'/api/public/get-benchmarks': CacheRequestHandler<Body>(
cache: cache,
config: config,
delegate: GetBenchmarks(config),
ttl: const Duration(minutes: 15),
),
'/api/public/get-status': CacheRequestHandler<Body>(
cache: cache,
config: config,
delegate: GetStatus(config),
),
'/api/public/get-timeseries-history': GetTimeSeriesHistory(config),
'/api/public/get-branches': CacheRequestHandler<Body>(
cache: cache,
config: config,
delegate: GetBranches(config),
ttl: const Duration(minutes: 15),
),
};
return await runAppEngine((HttpRequest request) async {
final RequestHandler<dynamic> handler = handlers[request.uri.path];
if (handler != null) {
await handler.service(request);
} else {
final String filePath = request.uri.toFilePath();
const List<String> indexRedirects = <String>['/build.html'];
if (indexRedirects.contains(filePath)) {
request.response.statusCode = HttpStatus.permanentRedirect;
// The separate HTML files are remnants from when Cocoon was written
// with an Angular Dart frontend.
final String flutterRouteName = filePath.replaceFirst('.html', '');
return await request.response
.redirect(Uri.parse('/#$flutterRouteName'));
}
await StaticFileHandler(filePath, config: config).service(request);
}
}, onAcceptingConnections: (InternetAddress address, int port) {
final String host = address.isLoopback ? 'localhost' : address.host;
print('Serving requests at $host:$port');
});
});
}