@@ -2,22 +2,27 @@ package com.github.mduesterhoeft.router
22
33import com.amazonaws.services.lambda.runtime.Context
44import com.amazonaws.services.lambda.runtime.RequestHandler
5+ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent
6+ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent
57import com.fasterxml.jackson.databind.ObjectMapper
68import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
79import com.github.mduesterhoeft.router.ProtoBufUtils.toJsonWithoutWrappers
810import com.google.common.net.MediaType
911import com.google.protobuf.GeneratedMessageV3
10- import org.apache.logging.log4j.LogManager
11- import org.apache.logging.log4j.Logger
12+ import org.slf4j.Logger
13+ import org.slf4j.LoggerFactory
14+ import java.util.Base64
15+ import java.util.logging.LogManager
1216import kotlin.reflect.KClass
1317import kotlin.reflect.jvm.reflect
1418
15- abstract class RequestHandler : RequestHandler <ApiRequest , ApiResponse > {
19+ abstract class RequestHandler : RequestHandler <APIGatewayProxyRequestEvent , APIGatewayProxyResponseEvent > {
1620
1721 open val objectMapper = jacksonObjectMapper()
1822
19- override fun handleRequest (input : ApiRequest , context : Context ): ApiResponse ? {
20- log.info(" handling request with method '${input.httpMethod} ' and path '${input.path} ' - Accept:${input.acceptHeader} Content-Type:${input.contentType} $input " )
23+ @Suppress(" UNCHECKED_CAST" )
24+ override fun handleRequest (input : APIGatewayProxyRequestEvent , context : Context ): APIGatewayProxyResponseEvent ? {
25+ log.info(" handling request with method '${input.httpMethod} ' and path '${input.path} ' - Accept:${input.acceptHeader()} Content-Type:${input.contentType()} $input " )
2126 val routes = router.routes as List <RouterFunction <Any , Any >>
2227 val matchResults: List <MatchResult > = routes.map { routerFunction: RouterFunction <Any , Any > ->
2328 val matchResult = routerFunction.requestPredicate.match(input)
@@ -36,7 +41,7 @@ abstract class RequestHandler : RequestHandler<ApiRequest, ApiResponse> {
3641
3742 private fun deserializeRequest (
3843 handler : HandlerFunction <Any , Any >,
39- input : ApiRequest
44+ input : APIGatewayProxyRequestEvent
4045 ): Any {
4146 val requestType = handler.reflect()!! .parameters.first().type.arguments.first().type?.classifier as KClass <* >
4247 return when (requestType) {
@@ -46,7 +51,7 @@ abstract class RequestHandler : RequestHandler<ApiRequest, ApiResponse> {
4651 }
4752 }
4853
49- private fun handleNonDirectMatch (matchResults : List <MatchResult >, input : ApiRequest ): ApiResponse {
54+ private fun handleNonDirectMatch (matchResults : List <MatchResult >, input : APIGatewayProxyRequestEvent ): APIGatewayProxyResponseEvent {
5055 // no direct match
5156 if (matchResults.any { it.matchPath && it.matchMethod && ! it.matchContentType }) {
5257 return createErrorResponse(
@@ -86,44 +91,43 @@ abstract class RequestHandler : RequestHandler<ApiRequest, ApiResponse> {
8691
8792 abstract val router: Router
8893
89- open fun createErrorResponse (input : ApiRequest , ex : ApiException ): ApiResponse =
90- ApiJsonResponse (
91- statusCode = ex.statusCode,
92- headers = mapOf (" Content-Type" to " application/json" ),
93- body = objectMapper.writeValueAsString(mapOf (
94+ open fun createErrorResponse (input : APIGatewayProxyRequestEvent , ex : ApiException ): APIGatewayProxyResponseEvent =
95+ APIGatewayProxyResponseEvent ()
96+ .withBody(objectMapper.writeValueAsString(mapOf (
9497 " message" to ex.message,
9598 " code" to ex.errorCode,
9699 " details" to ex.details
97- ))
98- )
100+ )))
101+ .withStatusCode(ex.statusCode)
102+ .withHeaders(mapOf (" Content-Type" to " application/json" ))
99103
100- open fun <T > createResponse (input : ApiRequest , response : ResponseEntity <T >): ApiResponse {
101- val accept = MediaType .parse(input.acceptHeader)
104+ open fun <T > createResponse (input : APIGatewayProxyRequestEvent , response : ResponseEntity <T >): APIGatewayProxyResponseEvent {
105+ val accept = MediaType .parse(input.acceptHeader() )
102106 return when {
103- response.body is Unit -> ApiJsonResponse (statusCode = 204 , body = null )
104- accept.`is `(MediaType .parse(" application/x-protobuf" )) -> ApiProtoResponse (
105- statusCode = 200 ,
106- headers = mapOf (" Accept" to " application/x-protobuf" ),
107- body = (response.body as GeneratedMessageV3 ).toByteArray()
108- )
107+ response.body is Unit -> APIGatewayProxyResponseEvent ()
108+ .withStatusCode(204 )
109+
110+ accept.`is `(MediaType .parse(" application/x-protobuf" )) -> APIGatewayProxyResponseEvent ()
111+ .withStatusCode(200 )
112+ .withBody(Base64 .getEncoder().encodeToString((response.body as GeneratedMessageV3 ).toByteArray()))
113+ .withHeaders(mapOf (" Content-Type" to " application/x-protobuf" ))
114+
109115 accept.`is `(MediaType .parse(" application/json" )) ->
110116 if (response.body is GeneratedMessageV3 )
111- ApiJsonResponse (
112- statusCode = 200 ,
113- headers = mapOf (" Content-Type" to " application/json" ),
114- body = toJsonWithoutWrappers(response.body)
115- )
117+ APIGatewayProxyResponseEvent ()
118+ .withStatusCode(200 )
119+ .withBody(toJsonWithoutWrappers(response.body))
120+ .withHeaders(mapOf (" Content-Type" to " application/json" ))
116121 else
117- ApiJsonResponse (
118- statusCode = 200 ,
119- headers = mapOf (" Content-Type" to " application/json" ),
120- body = response.body?.let { objectMapper.writeValueAsString(it) }
121- )
122+ APIGatewayProxyResponseEvent ()
123+ .withStatusCode(200 )
124+ .withBody(response.body?.let { objectMapper.writeValueAsString(it) })
125+ .withHeaders(mapOf (" Content-Type" to " application/json" ))
122126 else -> throw IllegalArgumentException (" unsupported response $response " )
123127 }
124128 }
125129
126130 companion object {
127- val log: Logger = LogManager .getLogger(RequestHandler ::class .java)
131+ val log: Logger = LoggerFactory .getLogger(RequestHandler ::class .java)
128132 }
129133}
0 commit comments