aboutsummaryrefslogtreecommitdiff
path: root/core-init/src/main/scala/xyz/driver/core/init/CloudServices.scala
diff options
context:
space:
mode:
Diffstat (limited to 'core-init/src/main/scala/xyz/driver/core/init/CloudServices.scala')
-rw-r--r--core-init/src/main/scala/xyz/driver/core/init/CloudServices.scala89
1 files changed, 89 insertions, 0 deletions
diff --git a/core-init/src/main/scala/xyz/driver/core/init/CloudServices.scala b/core-init/src/main/scala/xyz/driver/core/init/CloudServices.scala
new file mode 100644
index 0000000..857dd4c
--- /dev/null
+++ b/core-init/src/main/scala/xyz/driver/core/init/CloudServices.scala
@@ -0,0 +1,89 @@
+package xyz.driver.core
+package init
+
+import java.nio.file.Paths
+
+import xyz.driver.core.messaging.{CreateOnDemand, GoogleBus, QueueBus, StreamBus}
+import xyz.driver.core.reporting._
+import xyz.driver.core.rest.DnsDiscovery
+import xyz.driver.core.storage.{BlobStorage, FileSystemBlobStorage, GcsBlobStorage}
+
+import scala.collection.JavaConverters._
+
+/** Mixin trait that provides essential cloud utilities. */
+trait CloudServices extends AkkaBootable { self =>
+
+ /** The platform that this application is running on.
+ * @group config
+ */
+ def platform: Platform = Platform.current
+
+ /** Service discovery for the current platform.
+ * @group utilities
+ */
+ lazy val discovery: DnsDiscovery = {
+ def getOverrides(): Map[String, String] = {
+ val block = config.getObject("services.dev-overrides").unwrapped().asScala
+ for ((key, value) <- block) yield {
+ require(value.isInstanceOf[String], s"Service URL override for '$key' must be a string. Found '$value'.")
+ key -> value.toString
+ }
+ }.toMap
+ val overrides = platform match {
+ case Platform.Dev => getOverrides()
+ // TODO: currently, deployed services must be configured via Kubernetes DNS resolver. Maybe we may want to
+ // provide a way to override deployed services as well.
+ case _ => Map.empty[String, String]
+ }
+ new DnsDiscovery(clientTransport, overrides)
+ }
+
+ /* 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
+ * is first accessed. This in turn leads to somewhat convoluted code,
+ * since we can't log when the platform being is determined.
+ * A potential fix would be to make the log format independent of the platform, and always log
+ * as JSON for example.
+ */
+ override lazy val reporter: Reporter with ScalaLoggingCompat = {
+ Console.println("determining platform") // scalastyle:ignore
+ val r = platform match {
+ case p @ Platform.GoogleCloud(_, _) =>
+ new GoogleReporter(p.credentials, p.namespace) with ScalaLoggingCompat with GoogleMdcLogger {
+ val logger = ScalaLoggingCompat.defaultScalaLogger(true)
+ }
+ case Platform.Dev =>
+ new NoTraceReporter with ScalaLoggingCompat {
+ val logger = ScalaLoggingCompat.defaultScalaLogger(false)
+ }
+ }
+ r.info(s"application started on platform '${platform}'")(SpanContext.fresh())
+ r
+ }
+
+ /** Object storage.
+ *
+ * When running on a cloud platform, prepends `$project-` to bucket names, where `$project`
+ * is the project ID (for example 'driverinc-production` or `driverinc-sandbox`).
+ *
+ * @group utilities
+ */
+ def storage(bucketName: String): BlobStorage =
+ platform match {
+ case p @ Platform.GoogleCloud(keyfile, _) =>
+ GcsBlobStorage.fromKeyfile(keyfile, s"${p.project}-$bucketName")
+ case Platform.Dev =>
+ new FileSystemBlobStorage(Paths.get(s".data-$bucketName"))
+ }
+
+ /** Message bus.
+ * @group utilities
+ */
+ def messageBus: StreamBus = platform match {
+ case p @ Platform.GoogleCloud(_, namespace) =>
+ new GoogleBus(p.credentials, namespace) with StreamBus with CreateOnDemand
+ case Platform.Dev =>
+ new QueueBus()(self.system) with StreamBus
+ }
+
+}