Commit c3c74c56 authored by Andreas Muttscheller's avatar Andreas Muttscheller

Load urls from config file or use mockserver if we are using sbt-it stage

parent 4ab1bf46
......@@ -50,6 +50,8 @@ lazy val root = (project in file("."))
"com.amazonaws" % "aws-java-sdk-lambda" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-elasticsearch" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-api-gateway" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-ecs" % "1.11.492",
"com.amazonaws" % "aws-java-sdk-ec2" % "1.11.492",
"com.amazonaws" % "aws-lambda-java-events" % "2.2.5",
"com.amazonaws" % "aws-lambda-java-core" % "1.2.0",
......
......@@ -37,6 +37,9 @@ package:
custom:
default_stage: dev
scheduleEnabled:
sbt-it: false
other: true
functions:
ScheduledPlannedTimetableFetchService:
......@@ -45,7 +48,9 @@ functions:
iamRoleStatementsInherit: true
events:
# Monday to Friday - once at 3am
- schedule: cron(0 3 ? * MON-FRI *)
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0 3 ? * MON-FRI *)
ScheduledPlannedTimetableFetchWorker:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.ScheduledPlannedTimetableFetchWorker::handleRequest
reservedConcurrency: 1 # Only one instance may run at a time
......@@ -56,7 +61,9 @@ functions:
# UTC !!!
#- schedule: cron(0/2 5-10 ? * MON-FRI *)
#- schedule: cron(0/2 14-19 ? * MON-FRI *)
- schedule: cron(0/1 5-19 ? * MON-FRI *)
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0/1 5-19 ? * MON-FRI *)
SlackChangeReporter:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.SNSChangeSlackReporter::handleRequest
reservedConcurrency: 1 # Only one instance may run at a time
......@@ -67,7 +74,9 @@ functions:
iamRoleStatementsInherit: true
timeout: 30
events:
- schedule: cron(0/2 6-18 ? * MON-FRI *)
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0/2 6-18 ? * MON-FRI *)
- http:
path: slack/event
method: post
......@@ -75,7 +84,9 @@ functions:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.APISlackBotEventHandlerWorker::handleRequest
reservedConcurrency: 1 # Only one instance may run at a time
events:
- schedule: cron(0/2 6-18 ? * MON-FRI *)
- schedule:
enabled: ${self:custom.scheduleEnabled.${opt:stage}, self:custom.scheduleEnabled.other}
rate: cron(0/2 6-18 ? * MON-FRI *)
APIStationQuery:
handler: de.codecentric.amuttsch.bahndelayinfo.aws.lambda.APIStationQuery::handleRequest
iamRoleStatementsInherit: true
......
......@@ -4,10 +4,15 @@ import com.amazonaws.regions.DefaultAwsRegionProviderChain
import com.amazonaws.services.apigateway.AmazonApiGatewayClientBuilder
import com.amazonaws.services.apigateway.model.GetRestApisRequest
import com.amazonaws.services.dynamodbv2.document.{Item, ItemCollection, ScanOutcome}
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder
import com.amazonaws.services.ec2.model.DescribeNetworkInterfacesRequest
import com.amazonaws.services.ecs.AmazonECSClientBuilder
import com.amazonaws.services.ecs.model.{DescribeTasksRequest, ListTasksRequest, Task}
import com.amazonaws.services.elasticsearch.AWSElasticsearchClientBuilder
import com.amazonaws.services.elasticsearch.model.DescribeElasticsearchDomainRequest
import com.sksamuel.elastic4s.aws.Aws4ElasticClient
import com.sksamuel.elastic4s.http.{ElasticClient, ElasticProperties}
import com.typesafe.config.{Config, ConfigFactory}
import scala.collection.JavaConverters._
import scala.collection.mutable
......@@ -61,4 +66,52 @@ package object aws {
throw new RuntimeException(s"Environment variables SERVERLESS_SERVICE ($service) or SERVERLESS_STAGE ($stage) missing!")
}
}
def getExternalApiUrl(apiConfigPath: String): String = {
val stageOpt = scala.util.Properties.envOrNone("SERVERLESS_STAGE")
stageOpt match {
case Some("sbt-it") | Some("mock") =>
// Mock server api
val runningMockServers = getRunningMockServerTasks()
if (runningMockServers.isEmpty) {
throw new RuntimeException(s"No mock servers running! Start with sbt startECSMockServer")
}
val attachmentsDetails = runningMockServers.head.getAttachments.get(0).getDetails.asScala
val networkInterfaceId = attachmentsDetails.find(kvp => kvp.getName == "networkInterfaceId").get
getIpForNetworkInterfaceId(networkInterfaceId.getValue) + s"/$apiConfigPath"
case Some(_) =>
// Prod apis
val apiConf: Config = ConfigFactory.load("api")
apiConf.getString(s"$apiConfigPath.url")
case None =>
throw new RuntimeException(s"Environment variables SERVERLESS_STAGE missing!")
}
}
private def getIpForNetworkInterfaceId(networkInterfaceId: String): String = {
val client = AmazonEC2ClientBuilder.standard.build
val request = new DescribeNetworkInterfacesRequest()
.withNetworkInterfaceIds(networkInterfaceId)
val describeNetworkInterfaceResponse = client.describeNetworkInterfaces(request)
describeNetworkInterfaceResponse.getNetworkInterfaces.get(0).getAssociation.getPublicIp
}
private def getRunningMockServerTasks(): List[Task] = {
val client = AmazonECSClientBuilder.standard.build
val res = client.listTasks(new ListTasksRequest().withCluster("mockserver-cluster"))
if (res.getTaskArns.isEmpty) {
List.empty
} else {
val tasks = client.describeTasks(new DescribeTasksRequest()
.withCluster("mockserver-cluster")
.withTasks(res.getTaskArns)
)
tasks.getTasks.asScala
.filter(_.getStartedBy == "sbt")
.filter(_.getLastStatus == "RUNNING")
.toList
}
}
}
package de.codecentric.amuttsch.bahndelayinfo.fetcher
import com.softwaremill.sttp._
import com.typesafe.config.Config
import de.codecentric.amuttsch.bahndelayinfo.models.TimetableInformation
class DBChangedTimetableFetcher extends DBFetcher {
override def fetchUrl(ttr: TimetableRequest)(implicit apiConf: Config): Uri = {
uri"${apiConf.getString("dbapi.url")}/timetables/v1/rchg/${ttr.eva}"
override def fetchUrl(ttr: TimetableRequest): Uri = {
uri"$baseApiUrl/timetables/v1/rchg/${ttr.eva}"
}
override def fetchTimetablesForEvas(evaToFetch: List[String]): Seq[TimetableInformation] = {
......
......@@ -3,6 +3,7 @@ package de.codecentric.amuttsch.bahndelayinfo.fetcher
import com.softwaremill.sttp._
import com.typesafe.config.{Config, ConfigFactory}
import com.typesafe.scalalogging.Logger
import de.codecentric.amuttsch.bahndelayinfo.aws
import de.codecentric.amuttsch.bahndelayinfo.models.TimetableInformation
import org.xml.sax.SAXParseException
......@@ -15,10 +16,12 @@ private case class TimetableResponse(request: TimetableRequest, isValid: Boolean
private[fetcher] trait DBFetcher {
private implicit val backend: SttpBackend[Id, Nothing] = HttpURLConnectionBackend()
implicit val apiConf: Config = ConfigFactory.load("api")
implicit val logger: Logger = Logger(this.getClass)
val apiConf: Config = ConfigFactory.load("api")
val logger: Logger = Logger(this.getClass)
def fetchUrl(ttr: TimetableRequest)(implicit apiConf: Config): Uri
val baseApiUrl: String = aws.getExternalApiUrl("dbapi")
def fetchUrl(ttr: TimetableRequest): Uri
def fetchTimetablesForEvas(evas: List[String]): Seq[TimetableInformation]
......
......@@ -4,13 +4,12 @@ import java.text.SimpleDateFormat
import java.util.Calendar
import com.softwaremill.sttp._
import com.typesafe.config.Config
import de.codecentric.amuttsch.bahndelayinfo.models.TimetableInformation
class DBPlannedTimetableFetcher extends DBFetcher {
override def fetchUrl(ttr: TimetableRequest)(implicit apiConf: Config): Uri = {
uri"${apiConf.getString("dbapi.url")}/timetables/v1/plan/${ttr.eva}/${ttr.date}/${ttr.hour}"
override def fetchUrl(ttr: TimetableRequest): Uri = {
uri"$baseApiUrl/timetables/v1/plan/${ttr.eva}/${ttr.date}/${ttr.hour}"
}
override def fetchTimetablesForEvas(evaToFetch: List[String]): Seq[TimetableInformation] = {
......
package de.codecentric.amuttsch.bahndelayinfo.slackbot
import com.softwaremill.sttp._
import de.codecentric.amuttsch.bahndelayinfo.aws
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization.write
import org.json4s.{DefaultFormats, Formats, _}
import scala.util.Properties
class SlackClient(token: String) {
private implicit val backend: SttpBackend[Id, Nothing] = HttpURLConnectionBackend()
private implicit val jsonFormats: Formats = DefaultFormats
val slackApiBaseUri: String = Properties.envOrElse("SLACK_API_URL", "https://slack.com/api/")
val slackApiBaseUri: String = aws.getExternalApiUrl("slack")
def postMessage(
channel: String,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment