diff options
author | Jakob Odersky <jakob@driver.xyz> | 2018-09-03 23:40:35 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@driver.xyz> | 2018-09-12 14:17:39 -0700 |
commit | 9c36ff4f9e43857e2f73ebadad9942d85017e5c0 (patch) | |
tree | 2dffe5ec8ce2c17a63db528827db671447ce8feb /src | |
parent | adb943605e6e41d10d7b6984b515a13b7ad84de7 (diff) | |
download | driver-core-9c36ff4f9e43857e2f73ebadad9942d85017e5c0.tar.gz driver-core-9c36ff4f9e43857e2f73ebadad9942d85017e5c0.tar.bz2 driver-core-9c36ff4f9e43857e2f73ebadad9942d85017e5c0.zip |
Move platform back into init and use a configurable DNS discovery
Diffstat (limited to 'src')
-rw-r--r-- | src/main/resources/reference.conf | 5 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/discovery/CanDiscoverService.scala | 11 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/init/CloudServices.scala | 47 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/init/Platform.scala (renamed from src/main/scala/xyz/driver/core/Platform.scala) | 14 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/messaging/ReportingBus.scala | 34 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/rest/DnsDiscovery.scala | 11 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/rest/HttpRestServiceTransport.scala | 4 | ||||
-rw-r--r-- | src/main/scala/xyz/driver/core/rest/ServiceDescriptor.scala | 16 |
8 files changed, 98 insertions, 44 deletions
diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index 608262a..01dba3c 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -19,6 +19,11 @@ application { ] } +services.dev-overrides = [ + // {"service1": "http://localhost:8080"}, + // {"service2": "https://stable.sand.driver.network"} +] + # Settings about the auto-generated REST API documentation. swagger { diff --git a/src/main/scala/xyz/driver/core/discovery/CanDiscoverService.scala b/src/main/scala/xyz/driver/core/discovery/CanDiscoverService.scala deleted file mode 100644 index 8711332..0000000 --- a/src/main/scala/xyz/driver/core/discovery/CanDiscoverService.scala +++ /dev/null @@ -1,11 +0,0 @@ -package xyz.driver.core -package discovery - -import scala.annotation.implicitNotFound - -@implicitNotFound( - "Don't know how to communicate with service ${Service}. Make sure an implicit CanDiscoverService is" + - "available. A good place to put one is in the service's companion object.") -trait CanDiscoverService[Service] { - def discover(platform: Platform): Service -} 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/Platform.scala b/src/main/scala/xyz/driver/core/init/Platform.scala index aa7e711..2daa2c8 100644 --- a/src/main/scala/xyz/driver/core/Platform.scala +++ b/src/main/scala/xyz/driver/core/init/Platform.scala @@ -1,24 +1,20 @@ package xyz.driver.core +package init + import java.nio.file.{Files, Path, Paths} import com.google.auth.oauth2.ServiceAccountCredentials -sealed trait Platform { - def isKubernetes: Boolean -} - +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 - override def isKubernetes = true + def project: String = credentials.getProjectId } // case object AliCloud extends Platform - case object Dev extends Platform { - override def isKubernetes: Boolean = false - } + case object Dev extends Platform lazy val fromEnv: Platform = { def isGoogle = sys.env.get("GOOGLE_APPLICATION_CREDENTIALS").map { value => diff --git a/src/main/scala/xyz/driver/core/messaging/ReportingBus.scala b/src/main/scala/xyz/driver/core/messaging/ReportingBus.scala new file mode 100644 index 0000000..74038e4 --- /dev/null +++ b/src/main/scala/xyz/driver/core/messaging/ReportingBus.scala @@ -0,0 +1,34 @@ +package xyz.driver.core.messaging + +import xyz.driver.core.reporting.{Reporter, SpanContext} + +import scala.concurrent.Future +import scala.language.higherKinds + +trait ReportingBus extends Bus { + + def reporter: Reporter + + trait TracedMessage[A] extends BasicMessage[A] { self: Message[A] => + def spanContext: SpanContext + } + + type Message[A] <: TracedMessage[A] + + abstract override def publishMessages[A](topic: Topic[A], messages: Seq[A]): Future[Unit] = { + super.publishMessages(topic, messages) + } + + abstract override def fetchMessages[A]( + topic: Topic[A], + config: SubscriptionConfig, + maxMessages: Int): Future[Seq[Message[A]]] = { + super.fetchMessages(topic, config, maxMessages) + } + +} + +trait Topic2 +trait Bus2 { + def publishMessage[A](topic: Topic2, message: A) +} diff --git a/src/main/scala/xyz/driver/core/rest/DnsDiscovery.scala b/src/main/scala/xyz/driver/core/rest/DnsDiscovery.scala new file mode 100644 index 0000000..38880d4 --- /dev/null +++ b/src/main/scala/xyz/driver/core/rest/DnsDiscovery.scala @@ -0,0 +1,11 @@ +package xyz.driver.core +package rest + +class DnsDiscovery(transport: HttpRestServiceTransport, overrides: Map[String, String]) { + + def discover[A](implicit descriptor: ServiceDescriptor[A]): A = { + val url = overrides.getOrElse(descriptor.name, s"https://{descriptor.name}") + descriptor.connect(transport, url) + } + +} diff --git a/src/main/scala/xyz/driver/core/rest/HttpRestServiceTransport.scala b/src/main/scala/xyz/driver/core/rest/HttpRestServiceTransport.scala index e60998f..e31635b 100644 --- a/src/main/scala/xyz/driver/core/rest/HttpRestServiceTransport.scala +++ b/src/main/scala/xyz/driver/core/rest/HttpRestServiceTransport.scala @@ -17,8 +17,8 @@ import scala.util.{Failure, Success} class HttpRestServiceTransport( applicationName: Name[App], applicationVersion: String, - actorSystem: ActorSystem, - executionContext: ExecutionContext, + val actorSystem: ActorSystem, + val executionContext: ExecutionContext, reporter: Reporter) extends ServiceTransport { diff --git a/src/main/scala/xyz/driver/core/rest/ServiceDescriptor.scala b/src/main/scala/xyz/driver/core/rest/ServiceDescriptor.scala new file mode 100644 index 0000000..646fae8 --- /dev/null +++ b/src/main/scala/xyz/driver/core/rest/ServiceDescriptor.scala @@ -0,0 +1,16 @@ +package xyz.driver.core +package rest +import scala.annotation.implicitNotFound + +@implicitNotFound( + "Don't know how to communicate with service ${S}. Make sure an implicit ServiceDescriptor is" + + "available. A good place to put one is in the service's companion object.") +trait ServiceDescriptor[S] { + + /** The service's name. Must be unique among all services. */ + def name: String + + /** Get an instance of the service. */ + def connect(transport: HttpRestServiceTransport, url: String): S + +} |