Skip to content

Commit dece4c6

Browse files
committed
fix(awslambda): attributes should persist between exchanges for the same request/response pair.
1 parent 96df7a0 commit dece4c6

File tree

3 files changed

+18
-19
lines changed

3 files changed

+18
-19
lines changed

adapter/awslambda/src/main/java/io/gatehill/imposter/awslambda/impl/LambdaServer.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ abstract class LambdaServer<Request, Response>(
7676

7777
fun dispatch(event: Request): Response {
7878
val response = LambdaHttpResponse()
79+
val attributes = mutableMapOf<String, Any>()
80+
7981
var failureCause: Throwable? = null
8082
try {
8183
val matched = matchRoutes(event)
@@ -87,7 +89,7 @@ abstract class LambdaServer<Request, Response>(
8789
} else {
8890
matched.forEach { route ->
8991
val request = buildRequest(event, route)
90-
val exchange = LambdaHttpExchange(router, route, request, response)
92+
val exchange = LambdaHttpExchange(router, route, request, response, attributes)
9193
val handler = route.handler ?: throw IllegalStateException("No route handler set for: $route")
9294
try {
9395
handler(exchange).get()
@@ -111,12 +113,12 @@ abstract class LambdaServer<Request, Response>(
111113
when (val statusCode = response.statusCode) {
112114
in 400..499 -> {
113115
errorHandlers[statusCode]?.let { errorHandler ->
114-
failExchange(event, response, statusCode, null, errorHandler)
116+
failExchange(event, response, attributes, statusCode, null, errorHandler)
115117
} ?: logger.warn("Unhandled client error for: ${describeRequestShort(event)} [status code: $statusCode]")
116118
}
117119
in 500..599 -> {
118120
errorHandlers[statusCode]?.let { errorHandler ->
119-
failExchange(event, response, statusCode, failureCause, errorHandler)
121+
failExchange(event, response, attributes, statusCode, failureCause, errorHandler)
120122
} ?: logger.error("Unhandled server error for: ${describeRequestShort(event)} [status code: $statusCode]", failureCause)
121123
}
122124
}
@@ -127,12 +129,13 @@ abstract class LambdaServer<Request, Response>(
127129
private fun failExchange(
128130
event: Request,
129131
response: LambdaHttpResponse,
132+
attributes: MutableMap<String, Any>,
130133
statusCode: Int,
131134
failureCause: Throwable?,
132135
errorHandler: (HttpExchange) -> Unit,
133136
) {
134137
val request = buildRequest(event, null)
135-
val exchange = LambdaHttpExchange(router, null, request, response)
138+
val exchange = LambdaHttpExchange(router, null, request, response, attributes)
136139
exchange.fail(statusCode, failureCause)
137140
errorHandler(exchange)
138141
}

adapter/awslambda/src/main/java/io/gatehill/imposter/awslambda/impl/model/LambdaHttpExchange.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,7 @@
4444
package io.gatehill.imposter.awslambda.impl.model
4545

4646
import com.google.common.base.Strings
47-
import io.gatehill.imposter.http.ExchangePhase
48-
import io.gatehill.imposter.http.HttpExchange
49-
import io.gatehill.imposter.http.HttpRequest
50-
import io.gatehill.imposter.http.HttpResponse
51-
import io.gatehill.imposter.http.HttpRoute
52-
import io.gatehill.imposter.http.HttpRouter
47+
import io.gatehill.imposter.http.*
5348
import io.gatehill.imposter.util.HttpUtil
5449
import io.vertx.core.buffer.Buffer
5550

@@ -61,9 +56,14 @@ class LambdaHttpExchange(
6156
override val currentRoute: HttpRoute?,
6257
override val request: HttpRequest,
6358
response: HttpResponse,
59+
60+
/**
61+
* Externally manage the lifecycle of attributes so they persist between exchange
62+
* instances for the same request/response pair.
63+
*/
64+
private val attributes : MutableMap<String, Any>,
6465
) : HttpExchange {
6566
override var phase = ExchangePhase.REQUEST_RECEIVED
66-
private val attributes = mutableMapOf<String, Any>()
6767

6868
override var failureCause: Throwable? = null
6969
private set

core/engine/src/main/java/io/gatehill/imposter/service/HandlerServiceImpl.kt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,7 @@ import com.google.common.collect.Lists
4646
import io.gatehill.imposter.ImposterConfig
4747
import io.gatehill.imposter.config.ResolvedResourceConfig
4848
import io.gatehill.imposter.config.util.EnvVars
49-
import io.gatehill.imposter.http.ExchangePhase
50-
import io.gatehill.imposter.http.HttpExchange
51-
import io.gatehill.imposter.http.HttpExchangeFutureHandler
52-
import io.gatehill.imposter.http.HttpExchangeHandler
53-
import io.gatehill.imposter.http.HttpMethod
54-
import io.gatehill.imposter.http.HttpRouter
55-
import io.gatehill.imposter.http.ResourceMatcher
49+
import io.gatehill.imposter.http.*
5650
import io.gatehill.imposter.lifecycle.SecurityLifecycleHooks
5751
import io.gatehill.imposter.lifecycle.SecurityLifecycleListener
5852
import io.gatehill.imposter.plugin.config.InterceptorsHolder
@@ -73,7 +67,7 @@ import kotlinx.coroutines.future.future
7367
import org.apache.logging.log4j.Level
7468
import org.apache.logging.log4j.LogManager
7569
import java.io.File
76-
import java.util.UUID
70+
import java.util.*
7771
import java.util.concurrent.CompletableFuture
7872
import java.util.regex.Pattern
7973
import javax.inject.Inject
@@ -155,6 +149,8 @@ class HandlerServiceImpl @Inject constructor(
155149
httpExchange.get<Boolean>(ResourceUtil.RC_SEND_NOT_FOUND_RESPONSE) == true
156150
) {
157151
// only override response processing if the 404 did not originate from the mock engine
152+
// otherwise this will attempt to send a duplicate response to an already completed
153+
// exchange, resulting in an IllegalStateException
158154
logAppropriatelyForPath(httpExchange, "File not found")
159155
responseService.sendNotFoundResponse(httpExchange)
160156
}

0 commit comments

Comments
 (0)