Skip to content

Commit

Permalink
Add logging of request from proxy stub
Browse files Browse the repository at this point in the history
  • Loading branch information
ashashev committed Sep 30, 2023
1 parent c9653a8 commit 65d3bde
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 106 deletions.
3 changes: 2 additions & 1 deletion backend/mockingbird/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ ru.tinkoff.tcb {
excludedRequestHeaders = []
excludedResponseHeaders = []
insecureHosts = []
loggingOutgoingRequests = false
}

event {
fetchInterval = "5 s"
reloadInterval = "1 m"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.circe.Json
import io.circe.parser.parse
import io.circe.syntax.*
import io.estatico.newtype.ops.*
import mouse.boolean.*
import mouse.option.*
import sttp.client3.*
import sttp.client3.circe.*
Expand Down Expand Up @@ -151,40 +152,42 @@ final class PublicApiHandler(
body: RequestBody
)(uri: String, delay: Option[FiniteDuration], timeout: Option[FiniteDuration]): RIO[WLD, HttpStubResponse] = {
val requestUri = uri"$uri".pipe(query.foldLeft(_) { case (u, (key, value)) => u.addParam(key, value) })
log.debug(s"Received headers: ${headers.keys.mkString(", ")}") *> basicRequest
.headers(headers -- proxyConfig.excludedRequestHeaders)
.method(Method(method.entryName), requestUri)
.pipe(rt =>
body match {
case AbsentRequestBody => rt
case SimpleRequestBody(value) => rt.body(value)
case MultipartRequestBody(value) =>
rt.multipartBody[Any](
value.map(part =>
multipart(part.name, part.body)
.pipe(newPart =>
part.headers.foldLeft(newPart) { case (acc, header) =>
acc.header(header.name, header.value, true)
}
)
for {
_ <- log.debug(s"Received headers: ${headers.keys.mkString(", ")}")
req = basicRequest
.headers(headers -- proxyConfig.excludedRequestHeaders)
.method(Method(method.entryName), requestUri)
.pipe(rt =>
body match {
case AbsentRequestBody => rt
case SimpleRequestBody(value) => rt.body(value)
case MultipartRequestBody(value) =>
rt.multipartBody[Any](
value.map(part =>
multipart(part.name, part.body)
.pipe(newPart =>
part.headers.foldLeft(newPart) { case (acc, header) =>
acc.header(header.name, header.value, true)
}
)
)
)
)
}
)
.response(asByteArrayAlways)
.readTimeout(timeout.getOrElse(1.minute.asScala))
.send(httpBackend)
.map { response =>
BinaryResponse(
response.code.code,
response.headers
.filterNot(h => proxyConfig.excludedResponseHeaders(h.name))
.map(h => h.name -> h.value)
.toMap,
response.body.coerce[ByteArray],
delay
}
)
}
.response(asByteArrayAlways)
_ <- proxyConfig.loggingOutgoingRequests.fold(log.debug("Executing request: {}", req.toCurl), ZIO.unit)
response <- req
.readTimeout(timeout.getOrElse(1.minute.asScala))
.send(httpBackend)
} yield BinaryResponse(
response.code.code,
response.headers
.filterNot(h => proxyConfig.excludedResponseHeaders(h.name))
.map(h => h.name -> h.value)
.toMap,
response.body.coerce[ByteArray],
delay
)
}

private def jsonProxyRequest(
Expand All @@ -202,43 +205,47 @@ final class PublicApiHandler(
val requestUri = uri"$uri".pipe(query.foldLeft(_) { case (u, (key, value)) =>
u.addParam(key, value)
})
log.debug(s"Received headers: ${headers.keys.mkString(", ")}") *> basicRequest
.headers(headers -- proxyConfig.excludedRequestHeaders)
.method(Method(method.entryName), requestUri)
.pipe(rt =>
body match {
case AbsentRequestBody => rt
case SimpleRequestBody(value) => rt.body(value)
case MultipartRequestBody(value) =>
rt.multipartBody[Any](
value.map(part =>
multipart(part.name, part.body)
.pipe(newPart =>
part.headers.foldLeft(newPart) { case (acc, header) => acc.header(header.name, header.value, true) }
)
for {
_ <- log.debug(s"Received headers: ${headers.keys.mkString(", ")}")
req = basicRequest
.headers(headers -- proxyConfig.excludedRequestHeaders)
.method(Method(method.entryName), requestUri)
.pipe(rt =>
body match {
case AbsentRequestBody => rt
case SimpleRequestBody(value) => rt.body(value)
case MultipartRequestBody(value) =>
rt.multipartBody[Any](
value.map(part =>
multipart(part.name, part.body)
.pipe(newPart =>
part.headers.foldLeft(newPart) { case (acc, header) =>
acc.header(header.name, header.value, true)
}
)
)
)
)
}
)
.response(asJsonAlways[Json])
.readTimeout(timeout.getOrElse(1.minute.asScala))
.send(httpBackend)
.map { response =>
response.body match {
case Right(jsonResponse) =>
RawResponse(
response.code.code,
response.headers
.filterNot(h => proxyConfig.excludedResponseHeaders(h.name))
.map(h => h.name -> h.value)
.toMap,
jsonResponse.patch(data, patch).noSpaces,
delay
)
case Left(error) =>
RawResponse(500, Map(), error.body, delay)
}
}
}
)
.response(asJsonAlways[Json])
_ <- proxyConfig.loggingOutgoingRequests.fold(log.debug("Executing request: {}", req.toCurl), ZIO.unit)
response <- req
.readTimeout(timeout.getOrElse(1.minute.asScala))
.send(httpBackend)
} yield response.body match {
case Right(jsonResponse) =>
RawResponse(
response.code.code,
response.headers
.filterNot(h => proxyConfig.excludedResponseHeaders(h.name))
.map(h => h.name -> h.value)
.toMap,
jsonResponse.patch(data, patch).noSpaces,
delay
)
case Left(error) =>
RawResponse(500, Map(), error.body, delay)
}
}

private def xmlProxyRequest(
Expand All @@ -257,43 +264,47 @@ final class PublicApiHandler(
val requestUri = uri"$uri".pipe(query.foldLeft(_) { case (u, (key, value)) =>
u.addParam(key, value)
})
log.debug(s"Received headers: ${headers.keys.mkString(", ")}") *> basicRequest
.headers(headers -- proxyConfig.excludedRequestHeaders)
.method(Method(method.entryName), requestUri)
.pipe(rt =>
body match {
case AbsentRequestBody => rt
case SimpleRequestBody(value) => rt.body(value)
case MultipartRequestBody(value) =>
rt.multipartBody[Any](
value.map(part =>
multipart(part.name, part.body)
.pipe(newPart =>
part.headers.foldLeft(newPart) { case (acc, header) => acc.header(header.name, header.value, true) }
)
for {
_ <- log.debug(s"Received headers: ${headers.keys.mkString(", ")}")
req = basicRequest
.headers(headers -- proxyConfig.excludedRequestHeaders)
.method(Method(method.entryName), requestUri)
.pipe(rt =>
body match {
case AbsentRequestBody => rt
case SimpleRequestBody(value) => rt.body(value)
case MultipartRequestBody(value) =>
rt.multipartBody[Any](
value.map(part =>
multipart(part.name, part.body)
.pipe(newPart =>
part.headers.foldLeft(newPart) { case (acc, header) =>
acc.header(header.name, header.value, true)
}
)
)
)
)
}
)
.response(asXML)
.readTimeout(timeout.getOrElse(1.minute.asScala))
.send(httpBackend)
.map { response =>
response.body match {
case Right(xmlResponse) =>
RawResponse(
response.code.code,
response.headers
.filterNot(h => proxyConfig.excludedResponseHeaders(h.name))
.map(h => h.name -> h.value)
.toMap,
xmlResponse.patchFromValues(jData, xData, patch.map { case (k, v) => k.toZoom -> v }).toString(),
delay
)
case Left(error) =>
RawResponse(500, Map(), error, delay)
}
}
}
)
.response(asXML)
_ <- proxyConfig.loggingOutgoingRequests.fold(log.debug("Executing request: {}", req.toCurl), ZIO.unit)
response <- req
.readTimeout(timeout.getOrElse(1.minute.asScala))
.send(httpBackend)
} yield response.body match {
case Right(xmlResponse) =>
RawResponse(
response.code.code,
response.headers
.filterNot(h => proxyConfig.excludedResponseHeaders(h.name))
.map(h => h.name -> h.value)
.toMap,
xmlResponse.patchFromValues(jData, xData, patch.map { case (k, v) => k.toZoom -> v }).toString(),
delay
)
case Left(error) =>
RawResponse(500, Map(), error, delay)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ case class ProxyConfig(
excludedRequestHeaders: Seq[String],
excludedResponseHeaders: Set[String],
proxyServer: Option[ProxyServerConfig],
insecureHosts: Seq[String]
insecureHosts: Seq[String],
loggingOutgoingRequests: Boolean
)

case class EventConfig(fetchInterval: FiniteDuration, reloadInterval: FiniteDuration)
Expand Down

0 comments on commit 65d3bde

Please sign in to comment.