1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
package xyz.driver.core.app
import java.nio.file.{Files, Paths}
import java.time.Clock
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.TimeProvider
import xyz.driver.tracing.{GoogleTracer, NoTracer, Tracer}
import scala.concurrent.ExecutionContext
import scala.util.Try
import scala.language.reflectiveCalls
object init {
type RequiredBuildInfo = {
val name: String
val version: String
val gitHeadCommit: scala.Option[String]
}
case class ApplicationContext(config: Config, clock: Clock, log: Logger) {
val time: TimeProvider = clock
}
/** 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(): Unit = {
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): ActorSystem = {
val actorSystem =
ActorSystem(s"$serviceName-actors", Option(config), Option.empty[ClassLoader], Option(executionContext))
sys.addShutdownHook {
Try(actorSystem.terminate())
}
actorSystem
}
def toMdcExecutionContext(executor: Executor) =
new MdcExecutionContext(ExecutionContext.fromExecutor(executor))
def newFixedMdcExecutionContext(capacity: Int): MdcExecutionContext =
toMdcExecutionContext(Executors.newFixedThreadPool(capacity))
def defaultApplicationContext(): ApplicationContext =
ApplicationContext(
config = getEnvironmentSpecificConfig(),
clock = Clock.systemUTC(),
log = Logger(LoggerFactory.getLogger(classOf[DriverApp])))
def createDefaultApplication(
modules: Seq[Module],
buildInfo: RequiredBuildInfo,
actorSystem: ActorSystem,
tracer: Tracer,
context: ApplicationContext): DriverApp = {
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.0.0.0",
baseUrl,
scheme,
port,
tracer
)(actorSystem, actorSystem.dispatcher)
}
}
|