From 22a02a05df391597ee04f2524b7d975d07e76bd8 Mon Sep 17 00:00:00 2001 From: vlad Date: Tue, 23 May 2017 20:18:49 -0700 Subject: Passing User-Agent in outgoing HTTP requests, Returning services' dependencies in /version --- src/main/scala/xyz/driver/core/app.scala | 31 +++++++++++++------ .../scala/xyz/driver/core/file/S3Storage.scala | 12 ++++---- src/main/scala/xyz/driver/core/rest.scala | 35 ++++++++++++++++++++-- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/main/scala/xyz/driver/core/app.scala b/src/main/scala/xyz/driver/core/app.scala index e35c300..4603e5a 100644 --- a/src/main/scala/xyz/driver/core/app.scala +++ b/src/main/scala/xyz/driver/core/app.scala @@ -16,9 +16,8 @@ import com.typesafe.config.Config import com.typesafe.scalalogging.Logger import io.swagger.models.Scheme import org.slf4j.{LoggerFactory, MDC} -import spray.json.DefaultJsonProtocol import xyz.driver.core -import xyz.driver.core.rest.{ContextHeaders, Swagger} +import xyz.driver.core.rest._ import xyz.driver.core.stats.SystemStats import xyz.driver.core.time.Time import xyz.driver.core.time.provider.{SystemTimeProvider, TimeProvider} @@ -26,6 +25,7 @@ import xyz.driver.core.time.provider.{SystemTimeProvider, TimeProvider} import scala.compat.Platform.ConcurrentModificationException import scala.concurrent.duration._ import scala.concurrent.{Await, ExecutionContext, Future} +import scala.util.Try import scalaz.Scalaz.stringInstance import scalaz.syntax.equal._ @@ -145,6 +145,7 @@ object app { } protected def versionRoute(version: String, gitHash: String, startupTime: Time): Route = { + import spray.json._ import DefaultJsonProtocol._ import SprayJsonSupport._ @@ -152,17 +153,27 @@ object app { val currentTime = time.currentTime().millis complete( Map( - "version" -> version, - "gitHash" -> gitHash, - "modules" -> modules.map(_.name).mkString(", "), - "startupTime" -> startupTime.millis.toString, - "serverTime" -> currentTime.toString, - "uptime" -> (currentTime - startupTime.millis).toString - )) + "version" -> version.toJson, + "gitHash" -> gitHash.toJson, + "modules" -> modules.map(_.name).toJson, + "dependencies" -> collectAppDependencies().toJson, + "startupTime" -> startupTime.millis.toString.toJson, + "serverTime" -> currentTime.toString.toJson, + "uptime" -> (currentTime - startupTime.millis).toString.toJson + ).toJson) } } + protected def collectAppDependencies(): Map[String, String] = { + + def serviceWithLocation(serviceName: String): (String, String) = + serviceName -> Try(config.getString(s"services.$serviceName.baseUrl")).getOrElse("not-detected") + + modules.flatMap(module => module.serviceDiscovery.getUsedServices.map(serviceWithLocation).toSeq).toMap + } + protected def healthRoute: Route = { + import spray.json._ import DefaultJsonProtocol._ import SprayJsonSupport._ import spray.json._ @@ -240,6 +251,8 @@ object app { def route: Route def routeTypes: Seq[Type] + val serviceDiscovery: ServiceDiscovery with SavingUsedServiceDiscovery = new NoServiceDiscovery() + def activate(): Unit = {} def deactivate(): Unit = {} } diff --git a/src/main/scala/xyz/driver/core/file/S3Storage.scala b/src/main/scala/xyz/driver/core/file/S3Storage.scala index 50bfe85..933b01a 100644 --- a/src/main/scala/xyz/driver/core/file/S3Storage.scala +++ b/src/main/scala/xyz/driver/core/file/S3Storage.scala @@ -53,11 +53,13 @@ class S3Storage(s3: AmazonS3, bucket: Name[Bucket], executionContext: ExecutionC result.isTruncated } flatMap { result => result.getObjectSummaries.asScala.toList.map { summary => - FileLink(Name[File](summary.getKey), - Paths.get(path.toString + "/" + summary.getKey), - Revision[File](summary.getETag), - Time(summary.getLastModified.getTime), - summary.getSize) + FileLink( + Name[File](summary.getKey), + Paths.get(path.toString + "/" + summary.getKey), + Revision[File](summary.getETag), + Time(summary.getLastModified.getTime), + summary.getSize + ) } filterNot isInSubFolder(path) } toList }) diff --git a/src/main/scala/xyz/driver/core/rest.scala b/src/main/scala/xyz/driver/core/rest.scala index f1eab45..c13cce9 100644 --- a/src/main/scala/xyz/driver/core/rest.scala +++ b/src/main/scala/xyz/driver/core/rest.scala @@ -9,6 +9,9 @@ import akka.http.scaladsl.server.Directive0 import com.typesafe.scalalogging.Logger import akka.http.scaladsl.unmarshalling.Unmarshal import akka.http.scaladsl.unmarshalling.Unmarshaller +import akka.http.scaladsl.settings.ClientConnectionSettings +import akka.http.scaladsl.settings.ConnectionPoolSettings +import akka.http.scaladsl.model.headers.`User-Agent` import akka.stream.ActorMaterializer import akka.stream.scaladsl.Flow import akka.util.ByteString @@ -251,7 +254,26 @@ package rest { def discover[T <: Service](serviceName: Name[Service]): T } - class HttpRestServiceTransport(actorSystem: ActorSystem, + class NoServiceDiscovery extends ServiceDiscovery with SavingUsedServiceDiscovery { + + def discover[T <: Service](serviceName: Name[Service]): T = + throw new IllegalArgumentException(s"Service with name $serviceName is unknown") + } + + trait SavingUsedServiceDiscovery { + + private val usedServices = new scala.collection.mutable.HashSet[String]() + + def saveServiceUsage(serviceName: Name[Service]): Unit = usedServices.synchronized { + usedServices += serviceName.value + } + + def getUsedServices: Set[String] = usedServices.synchronized { usedServices.toSet } + } + + class HttpRestServiceTransport(applicationName: Name[App], + applicationVersion: String, + actorSystem: ActorSystem, executionContext: ExecutionContext, log: Logger, time: TimeProvider) @@ -260,6 +282,15 @@ package rest { protected implicit val materializer = ActorMaterializer()(actorSystem) protected implicit val execution = executionContext + private val client = Http()(actorSystem) + + private val clientConnectionSettings: ClientConnectionSettings = + ClientConnectionSettings(actorSystem).withUserAgentHeader( + Option(`User-Agent`(applicationName.value + "/" + applicationVersion))) + + private val connectionPoolSettings: ConnectionPoolSettings = ConnectionPoolSettings(actorSystem) + .withConnectionSettings(clientConnectionSettings) + def sendRequestGetResponse(context: ServiceRequestContext)(requestStub: HttpRequest): Future[HttpResponse] = { val requestTime = time.currentTime() @@ -272,7 +303,7 @@ package rest { log.info(s"Sending request to ${request.method} ${request.uri}") - val response = Http()(actorSystem).singleRequest(request)(materializer) + val response = client.singleRequest(request, settings = connectionPoolSettings)(materializer) response.onComplete { case Success(r) => -- cgit v1.2.3 From 9a7e3688e407febec5c5ab05d3c7ff432c4f9025 Mon Sep 17 00:00:00 2001 From: vlad Date: Thu, 25 May 2017 17:05:23 -0700 Subject: Merge branch 'master' of https://github.com/drivergroup/driver-core into service-dependencies # Conflicts: # src/main/scala/xyz/driver/core/app.scala # src/main/scala/xyz/driver/core/rest.scala --- src/main/scala/xyz/driver/core/app.scala | 11 ++++++++--- src/main/scala/xyz/driver/core/json.scala | 3 ++- src/main/scala/xyz/driver/core/rest.scala | 1 - 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/scala/xyz/driver/core/app.scala b/src/main/scala/xyz/driver/core/app.scala index a14da76..c4f72ad 100644 --- a/src/main/scala/xyz/driver/core/app.scala +++ b/src/main/scala/xyz/driver/core/app.scala @@ -126,9 +126,14 @@ object app { val swagger: Swagger = reader.read(toJavaTypeSet(apiTypes).asJava) // Removing trailing spaces - swagger.setPaths(swagger.getPaths.asScala.map { case (key, path) => - key.trim -> path - }.toMap.asJava) + swagger.setPaths( + swagger.getPaths.asScala + .map { + case (key, path) => + key.trim -> path + } + .toMap + .asJava) Json.pretty().writeValueAsString(swagger) } catch { diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index b9d0745..b203c91 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -18,7 +18,8 @@ import xyz.driver.core.time.Time object json { import DefaultJsonProtocol._ - private def UuidInPath[T]: PathMatcher1[Id[T]] = PathMatchers.JavaUUID.map((id: UUID) => Id[T](id.toString.toLowerCase)) + private def UuidInPath[T]: PathMatcher1[Id[T]] = + PathMatchers.JavaUUID.map((id: UUID) => Id[T](id.toString.toLowerCase)) def IdInPath[T]: PathMatcher1[Id[T]] = UuidInPath[T] | new PathMatcher1[Id[T]] { def apply(path: Path) = path match { diff --git a/src/main/scala/xyz/driver/core/rest.scala b/src/main/scala/xyz/driver/core/rest.scala index d4425fe..cbd671e 100644 --- a/src/main/scala/xyz/driver/core/rest.scala +++ b/src/main/scala/xyz/driver/core/rest.scala @@ -21,7 +21,6 @@ import akka.util.ByteString import com.github.swagger.akka.model._ import com.github.swagger.akka.{HasActorSystem, SwaggerHttpService} import com.typesafe.config.Config -import com.typesafe.scalalogging.Logger import io.swagger.models.Scheme import pdi.jwt.{Jwt, JwtAlgorithm} import xyz.driver.core.auth._ -- cgit v1.2.3