From 9c36ff4f9e43857e2f73ebadad9942d85017e5c0 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Mon, 3 Sep 2018 23:40:35 -0700 Subject: Move platform back into init and use a configurable DNS discovery --- .../scala/xyz/driver/core/init/CloudServices.scala | 47 ++++++++++++---------- src/main/scala/xyz/driver/core/init/Platform.scala | 31 ++++++++++++++ 2 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 src/main/scala/xyz/driver/core/init/Platform.scala (limited to 'src/main/scala/xyz/driver/core/init') diff --git a/src/main/scala/xyz/driver/core/init/CloudServices.scala b/src/main/scala/xyz/driver/core/init/CloudServices.scala index 9f4ab5c..c492add 100644 --- a/src/main/scala/xyz/driver/core/init/CloudServices.scala +++ b/src/main/scala/xyz/driver/core/init/CloudServices.scala @@ -3,12 +3,14 @@ package init import java.nio.file.Paths -import xyz.driver.core.discovery.CanDiscoverService +import com.typesafe.config.ConfigValueType import xyz.driver.core.messaging.{GoogleBus, QueueBus, StreamBus} import xyz.driver.core.reporting._ import xyz.driver.core.reporting.ScalaLoggerLike.defaultScalaLogger +import xyz.driver.core.rest.{DnsDiscovery, ServiceDescriptor} import xyz.driver.core.storage.{BlobStorage, FileSystemBlobStorage, GcsBlobStorage} +import scala.collection.JavaConverters._ import scala.concurrent.ExecutionContext /** Mixin trait that provides essential cloud utilities. */ @@ -21,28 +23,29 @@ trait CloudServices extends AkkaBootable { self => /** Service discovery for the current platform. * - * Define a service trait and companion object: - * {{{ - * trait MyService { - * def call(): Int - * } - * object MyService { - * implicit val isDiscoverable = new xyz.driver.core.discovery.CanDiscoverService[MyService] { - * def discover(p: xyz.driver.core.Platform): MyService = new MyService { - * def call() = 42 - * } - * } - * } - * }}} - * - * Then discover and use it: - * {{{ - * discover[MyService].call() - * }}} - * - * @group utilities */ - def discover[A](implicit cds: CanDiscoverService[A]): A = cds.discover(platform) + private lazy val discovery = { + def getOverrides(): Map[String, String] = + (for { + obj <- config.getObjectList("services.dev-overrides").asScala + entry <- obj.entrySet().asScala + } yield { + val tpe = entry.getValue.valueType() + require( + tpe == ConfigValueType.STRING, + s"URL override for '${entry.getKey}' must be a " + + s"string. Found '${entry.getValue.unwrapped}', which is of type $tpe.") + entry.getKey -> entry.getValue.unwrapped.toString + }).toMap + + val overrides = platform match { + case Platform.Dev => getOverrides() + case _ => Map.empty[String, String] // TODO we may want to provide a way to override deployed services as well + } + new DnsDiscovery(clientTransport, overrides) + } + + def discover[A: ServiceDescriptor]: A = discovery.discover[A] /* TODO: this reporter uses the platform to determine if JSON logging should be enabled. * Since the default logger uses slf4j, its settings must be specified before a logger diff --git a/src/main/scala/xyz/driver/core/init/Platform.scala b/src/main/scala/xyz/driver/core/init/Platform.scala new file mode 100644 index 0000000..2daa2c8 --- /dev/null +++ b/src/main/scala/xyz/driver/core/init/Platform.scala @@ -0,0 +1,31 @@ +package xyz.driver.core +package init + +import java.nio.file.{Files, Path, Paths} + +import com.google.auth.oauth2.ServiceAccountCredentials + +sealed trait Platform +object Platform { + case class GoogleCloud(keyfile: Path, namespace: String) extends Platform { + def credentials: ServiceAccountCredentials = ServiceAccountCredentials.fromStream( + Files.newInputStream(keyfile) + ) + def project: String = credentials.getProjectId + } + // case object AliCloud extends Platform + case object Dev extends Platform + + lazy val fromEnv: Platform = { + def isGoogle = sys.env.get("GOOGLE_APPLICATION_CREDENTIALS").map { value => + val keyfile = Paths.get(value) + require(Files.isReadable(keyfile), s"Google credentials file $value is not readable.") + val namespace = sys.env.getOrElse("SERVICE_NAMESPACE", sys.error("Namespace not set")) + GoogleCloud(keyfile, namespace) + } + isGoogle.getOrElse(Dev) + } + + def current: Platform = fromEnv + +} -- cgit v1.2.3