Skip to content

Commit

Permalink
spike: moves computed config out of model.
Browse files Browse the repository at this point in the history
  • Loading branch information
outofcoffee committed Jul 15, 2024
1 parent 6a6f93f commit 7e6c31a
Show file tree
Hide file tree
Showing 25 changed files with 165 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
package io.gatehill.imposter.config

import io.gatehill.imposter.plugin.config.resource.BasicResourceConfig
import io.gatehill.imposter.plugin.config.resource.RestResourceConfig
import io.gatehill.imposter.plugin.config.resource.conditional.ConditionalNameValuePair
import io.gatehill.imposter.plugin.config.resource.request.FormParamsResourceConfig
import io.gatehill.imposter.plugin.config.resource.request.PathParamsResourceConfig
Expand All @@ -62,10 +63,10 @@ data class ResolvedResourceConfig(
companion object {
fun parse(config: BasicResourceConfig) = ResolvedResourceConfig(
config = config,
pathParams = (config as? PathParamsResourceConfig)?.pathParams ?: emptyMap(),
queryParams = (config as? QueryParamsResourceConfig)?.queryParams ?: emptyMap(),
formParams = (config as? FormParamsResourceConfig)?.formParams ?: emptyMap(),
requestHeaders = (config as? RequestHeadersResourceConfig)?.requestHeaders ?: emptyMap(),
pathParams = (config as? PathParamsResourceConfig)?.let { RestResourceConfig.pathParams(it) } ?: emptyMap(),
queryParams = (config as? QueryParamsResourceConfig)?.let { RestResourceConfig.queryParams(it) } ?: emptyMap(),
formParams = (config as? FormParamsResourceConfig)?.let { RestResourceConfig.formParams(it) } ?: emptyMap(),
requestHeaders = (config as? RequestHeadersResourceConfig)?.let { RestResourceConfig.requestHeaders(it) } ?: emptyMap(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ open class PluginConfigImpl : AbstractResourceConfig(), BasicPluginConfig {
override val systemConfig: SystemConfig? = null

/**
* Not set by configuration file.
* Not set by configuration file, and should not be serialised once set.
*/
@field:JsonIgnore
@field:Transient
override lateinit var dir: File

override fun toString(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
package io.gatehill.imposter.plugin.config.capture

import com.fasterxml.jackson.annotation.JsonProperty
import io.gatehill.imposter.plugin.config.capture.CaptureConfig.Companion.requestBody
import io.gatehill.imposter.plugin.config.flex.TypeParser

/**
Expand Down Expand Up @@ -78,14 +79,15 @@ open class CaptureConfig(
) {
companion object : TypeParser<String?, CaptureConfig> {
override fun parse(raw: String?) = CaptureConfig(expression = raw)

fun requestBody(config: CaptureConfig): BodyCaptureConfig = with(config) {
BodyCaptureConfig.parse(_requestBody, jsonPath)
}
}

@field:JsonProperty("jsonPath")
private val jsonPath: String? = null

@delegate:Transient
open val requestBody: BodyCaptureConfig by lazy { BodyCaptureConfig.parse(_requestBody, jsonPath) }

override fun toString(): String {
return "CaptureConfig(pathParam=$pathParam, queryParam=$queryParam, formParam=$formParam, requestHeader=$requestHeader, jsonPath=$jsonPath, expression=$expression, constValue=$constValue)"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ package io.gatehill.imposter.plugin.config.capture

import com.fasterxml.jackson.annotation.JsonProperty
import io.gatehill.imposter.http.ExchangePhase
import io.gatehill.imposter.plugin.config.flex.FlexibleTypeUtil.lazyParse
import io.gatehill.imposter.plugin.config.capture.ItemCaptureConfig.Companion.key
import io.gatehill.imposter.plugin.config.capture.ItemCaptureConfig.Companion.store
import io.gatehill.imposter.plugin.config.flex.FlexibleTypeUtil

/**
* A capture configuration for values, that allows the key and store to be overridden.
Expand Down Expand Up @@ -86,12 +88,13 @@ class ItemCaptureConfig(
expression,
constValue,
) {
@delegate:Transient
val key: CaptureConfig? by lazyParse(_key, CaptureConfig)
companion object {
fun key(itemCaptureConfig: ItemCaptureConfig): CaptureConfig? = with(itemCaptureConfig) {
FlexibleTypeUtil.parse(_key, CaptureConfig)
}

@delegate:Transient
val store: CaptureConfig? by lazyParse(_store, CaptureConfig)

override val requestBody
get() = super.requestBody
fun store(itemCaptureConfig: ItemCaptureConfig): CaptureConfig? = with(itemCaptureConfig) {
FlexibleTypeUtil.parse(_store, CaptureConfig)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,18 @@ object FlexibleTypeUtil {
* @param T the computed value
* @return a delegate that will parse [raw] to an instance of [T] when [Lazy.getValue] is called.
*/
inline fun <reified R, reified T> parse(raw: Any?, parser: TypeParser<R, T>) = when (raw) {
null -> null
is T -> raw
is R -> parser.parse(raw)
is Map<*, *> -> converter.convertValue(raw, T::class.java)
else -> throw ClassCastException("Config must be Map, ${R::class.qualifiedName} or ${T::class.qualifiedName} - value: $raw")
}

/**
* Wraps [parse] in a [lazy] delegate.
*/
inline fun <reified R, reified T> lazyParse(raw: Any?, parser: TypeParser<R, T>): Lazy<T?> = lazy {
return@lazy when (raw) {
null -> null
is T -> raw
is R -> parser.parse(raw)
is Map<*, *> -> converter.convertValue(raw, T::class.java)
else -> throw ClassCastException("Config must be Map, ${R::class.qualifiedName} or ${T::class.qualifiedName} - value: $raw")
}
return@lazy parse<R, T>(raw, parser)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import io.gatehill.imposter.plugin.config.capture.CaptureConfigHolder
import io.gatehill.imposter.plugin.config.capture.ItemCaptureConfig
import io.gatehill.imposter.plugin.config.security.SecurityConfig
import io.gatehill.imposter.plugin.config.security.SecurityConfigHolder
import java.util.*

/**
* Base configuration for plugins and sub-resources.
Expand All @@ -75,7 +74,7 @@ abstract class AbstractResourceConfig : BasicResourceConfig, SecurityConfigHolde
override val continueToNext: Boolean? = null

@get:JsonIgnore
override val resourceId = UUID.randomUUID().toString()
override lateinit var resourceId: String

override fun toString(): String {
return "AbstractResourceConfig(path=$path, securityConfig=$securityConfig, captureConfig=$captureConfig, responseConfig=$responseConfig, continueToNext=$continueToNext)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ package io.gatehill.imposter.plugin.config.resource
*
* @author Pete Cornish
*/
interface BasicResourceConfig : ResourceConfig, ResponseConfigHolder, StableResourceIdHolder, InterceptorConfigHolder
interface BasicResourceConfig : ResourceConfig, ResponseConfigHolder, StableResourceIdHolder, InterceptorConfigHolder {
override var resourceId: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@
package io.gatehill.imposter.plugin.config.resource

import com.fasterxml.jackson.annotation.JsonAlias
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonProperty
import io.gatehill.imposter.http.HttpMethod
import io.gatehill.imposter.plugin.config.resource.RestResourceConfig.Companion.formParams
import io.gatehill.imposter.plugin.config.resource.RestResourceConfig.Companion.pathParams
import io.gatehill.imposter.plugin.config.resource.RestResourceConfig.Companion.queryParams
import io.gatehill.imposter.plugin.config.resource.RestResourceConfig.Companion.requestHeaders
import io.gatehill.imposter.plugin.config.resource.conditional.ConditionalNameValuePair
import io.gatehill.imposter.plugin.config.resource.conditional.MatchOperator
import io.gatehill.imposter.plugin.config.resource.request.FormParamsResourceConfig
import io.gatehill.imposter.plugin.config.resource.request.LegacyQueryParamsResourceConfig
import io.gatehill.imposter.plugin.config.resource.request.MethodResourceConfig
import io.gatehill.imposter.plugin.config.resource.request.PathParamsResourceConfig
import io.gatehill.imposter.plugin.config.resource.request.QueryParamsResourceConfig
Expand All @@ -67,54 +68,34 @@ open class RestResourceConfig(
* Raw configuration. Use [pathParams] instead.
*/
@field:JsonProperty("pathParams")
protected var rawPathParams: Map<String, Any>? = null,
override var rawPathParams: Map<String, Any>? = null,

/**
* Raw configuration. Use [queryParams] instead.
*/
@field:JsonProperty("queryParams")
@field:JsonAlias("params")
protected var rawQueryParams: Map<String, Any>? = null,
override var rawQueryParams: Map<String, Any>? = null,

/**
* Raw configuration. Use [requestHeaders] instead.
*/
@field:JsonProperty("requestHeaders")
protected var rawRequestHeaders: Map<String, Any>? = null,
override var rawRequestHeaders: Map<String, Any>? = null,

/**
* Raw configuration. Use [formParams] instead.
*/
@field:JsonProperty("formParams")
private val rawFormParams: Map<String, Any>? = null,
override val rawFormParams: Map<String, Any>? = null,

) : AbstractResourceConfig(), MethodResourceConfig, PathParamsResourceConfig,
QueryParamsResourceConfig, LegacyQueryParamsResourceConfig, RequestHeadersResourceConfig, FormParamsResourceConfig,
QueryParamsResourceConfig, RequestHeadersResourceConfig, FormParamsResourceConfig,
RequestBodyResourceConfig, EvalResourceConfig, PassthroughResourceConfig, StepsConfigHolder {

@field:JsonProperty("method")
override var method: HttpMethod? = null

@delegate:Transient
override val pathParams: Map<String, ConditionalNameValuePair> by lazy {
rawPathParams?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

@delegate:Transient
override val queryParams: Map<String, ConditionalNameValuePair> by lazy {
rawQueryParams?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

@delegate:Transient
override val requestHeaders: Map<String, ConditionalNameValuePair> by lazy {
rawRequestHeaders?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

@delegate:Transient
override val formParams: Map<String, ConditionalNameValuePair> by lazy {
rawFormParams?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

@field:JsonProperty("requestBody")
override var requestBody: RequestBodyConfig? = null

Expand All @@ -124,20 +105,28 @@ open class RestResourceConfig(
@field:JsonProperty("passthrough")
override var passthrough: String? = null

/**
* Backward compatibility for deprecated `params` property.
* Only [MatchOperator.EqualTo] matches are supported.
*/
@get:JsonIgnore
override val params: Map<String, String>?
get() = queryParams
.filter { it.value.operator == MatchOperator.EqualTo && it.value.value != null }
.mapValues { it.value.value!! }

@field:JsonProperty("steps")
override val steps: List<StepConfig>? = null

override fun toString(): String {
return "RestResourceConfig(parent=${super.toString()}, method=$method, pathParams=$pathParams, queryParams=$queryParams, formParams=$formParams, requestHeaders=$requestHeaders, requestBody=$requestBody, eval=$eval, passthrough=$passthrough)"
return "RestResourceConfig(parent=${super.toString()}, method=$method, pathParams=$rawPathParams, queryParams=$rawQueryParams, formParams=$rawFormParams, requestHeaders=$rawRequestHeaders, requestBody=$requestBody, eval=$eval, passthrough=$passthrough)"
}

companion object {
fun pathParams(config: PathParamsResourceConfig): Map<String, ConditionalNameValuePair> = with(config) {
rawPathParams?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

fun queryParams(config: QueryParamsResourceConfig): Map<String, ConditionalNameValuePair> = with(config) {
rawQueryParams?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

fun requestHeaders(config: RequestHeadersResourceConfig): Map<String, ConditionalNameValuePair> = with(config) {
rawRequestHeaders?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}

fun formParams(config: FormParamsResourceConfig): Map<String, ConditionalNameValuePair> = with(config) {
rawFormParams?.let { ConditionalNameValuePair.parse(it) } ?: emptyMap()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@
*/
package io.gatehill.imposter.plugin.config.resource.request

import io.gatehill.imposter.plugin.config.resource.conditional.ConditionalNameValuePair

/**
* @author Pete Cornish
*/
interface FormParamsResourceConfig {
val formParams: Map<String, ConditionalNameValuePair>?
val rawFormParams: Map<String, Any>?
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@
*/
package io.gatehill.imposter.plugin.config.resource.request

import io.gatehill.imposter.plugin.config.resource.conditional.ConditionalNameValuePair

/**
* @author Pete Cornish
*/
interface PathParamsResourceConfig {
val pathParams: Map<String, ConditionalNameValuePair>?
val rawPathParams: Map<String, Any>?
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@
*/
package io.gatehill.imposter.plugin.config.resource.request

import io.gatehill.imposter.plugin.config.resource.conditional.ConditionalNameValuePair

/**
* @author Pete Cornish
*/
interface QueryParamsResourceConfig {
val queryParams: Map<String, ConditionalNameValuePair>?
val rawQueryParams: Map<String, Any>?
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@
*/
package io.gatehill.imposter.plugin.config.resource.request

import io.gatehill.imposter.plugin.config.resource.conditional.ConditionalNameValuePair

/**
* @author Pete Cornish
*/
interface RequestHeadersResourceConfig {
val requestHeaders: Map<String, ConditionalNameValuePair>?
val rawRequestHeaders: Map<String, Any>?
}
Loading

0 comments on commit 7e6c31a

Please sign in to comment.