From 56f7aa3b6a45d4309cc2c77fcac7e6fda5f45e55 Mon Sep 17 00:00:00 2001 From: vlad Date: Wed, 8 Nov 2017 04:09:28 -0800 Subject: App initialization convenience methods --- src/main/scala/xyz/driver/core/app/init.scala | 118 ++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/main/scala/xyz/driver/core/app/init.scala (limited to 'src/main/scala/xyz/driver/core/app/init.scala') diff --git a/src/main/scala/xyz/driver/core/app/init.scala b/src/main/scala/xyz/driver/core/app/init.scala new file mode 100644 index 0000000..36eaeda --- /dev/null +++ b/src/main/scala/xyz/driver/core/app/init.scala @@ -0,0 +1,118 @@ +package xyz.driver.core.app + +import java.nio.file.{Files, Paths} +import java.util.concurrent.{Executor, Executors} + +import akka.actor.ActorSystem +import akka.stream.ActorMaterializer +import com.typesafe.config.{Config, ConfigFactory} +import com.typesafe.scalalogging.Logger +import org.slf4j.LoggerFactory +import xyz.driver.core.logging.MdcExecutionContext +import xyz.driver.core.time.provider.{SystemTimeProvider, TimeProvider} +import xyz.driver.tracing.{GoogleTracer, NoTracer, Tracer} + +import scala.concurrent.ExecutionContext +import scala.util.Try + +object init { + + type RequiredBuildInfo = { + val name: String + val version: String + val gitHeadCommit: scala.Option[String] + } + + case class ApplicationContext(config: Config, time: TimeProvider, log: Logger) + + /** NOTE: This needs to be the first that is run when application starts. + * Otherwise if another command causes the logger to be instantiated, + * it will default to logback.xml, and not honor this configuration + */ + def configureLogging() = { + scala.sys.env.get("JSON_LOGGING") match { + case Some("true") => + System.setProperty("logback.configurationFile", "deployed-logback.xml") + case _ => + System.setProperty("logback.configurationFile", "logback.xml") + } + } + + def getEnvironmentSpecificConfig(): Config = { + scala.sys.env.get("APPLICATION_CONFIG_TYPE") match { + case Some("deployed") => + ConfigFactory.load(this.getClass.getClassLoader, "deployed-application.conf") + case _ => + xyz.driver.core.config.loadDefaultConfig + } + } + + def configureTracer(actorSystem: ActorSystem, applicationContext: ApplicationContext): Tracer = { + + val serviceAccountKeyFile = + Paths.get(applicationContext.config.getString("tracing.google.serviceAccountKeyfile")) + + if (Files.exists(serviceAccountKeyFile)) { + val materializer = ActorMaterializer()(actorSystem) + new GoogleTracer( + projectId = applicationContext.config.getString("tracing.google.projectId"), + serviceAccountFile = serviceAccountKeyFile + )(actorSystem, materializer) + } else { + applicationContext.log.warn(s"Tracing file $serviceAccountKeyFile was not found, using NoTracer!") + NoTracer + } + } + + def serviceActorSystem(serviceName: String, executionContext: ExecutionContext, config: Config) = { + val actorSystem = + ActorSystem(s"$serviceName-actors", Option(config), Option.empty[ClassLoader], Option(executionContext)) + + Runtime.getRuntime.addShutdownHook(new Thread() { + override def run(): Unit = Try(actorSystem.terminate()) + }) + + actorSystem + } + + def toMdcExecutionContext(executor: Executor) = + new MdcExecutionContext(ExecutionContext.fromExecutor(executor)) + + def newFixedMdcExecutionContext(capacity: Int): MdcExecutionContext = + toMdcExecutionContext(Executors.newFixedThreadPool(capacity)) + + def defaultApplicationContext() = { + val config = getEnvironmentSpecificConfig() + + val time = new SystemTimeProvider() + val log = Logger(LoggerFactory.getLogger(classOf[DriverApp])) + + ApplicationContext(config, time, log) + } + + def createDefaultApplication(modules: Seq[Module], + buildInfo: RequiredBuildInfo, + actorSystem: ActorSystem, + tracer: Tracer, + context: ApplicationContext) = { + val scheme = context.config.getString("application.scheme") + val baseUrl = context.config.getString("application.baseUrl") + val port = context.config.getInt("application.port") + + new DriverApp( + buildInfo.name, + buildInfo.version, + buildInfo.gitHeadCommit.getOrElse("None"), + modules = modules, + context.time, + context.log, + context.config, + interface = "::0", + baseUrl, + scheme, + port, + tracer + )(actorSystem, actorSystem.dispatcher) + } + +} -- cgit v1.2.3