MrNiamh
01/04/2024, 6:47 PMval inputFilesMultipart = MultipartFormFile.multi.optional("inputFiles")
val proxyTrackingMultipart = MultipartFormField.auto<PostPutProxyTrackingRequestDTO>(CustomJackson).required("proxyTracking")
data class PostPutProxyTrackingRequestDTO(
val title: String,
val description: String,
val isin: String,
val date: LocalDate,
val existingDocumentIds: List<TenantDocumentId>,
val options: List<PostPutProxyTrackingOptionRequestDTO>
)
data class PostPutProxyTrackingOptionRequestDTO(
val option: String,
val voted: Boolean,
)
val proxyTrackingFormBody = Body.multipartForm(Validator.Strict, inputFilesMultipart, proxyTrackingMultipart).toLens()
I'm then sending this request (no files in this one):
curl '<http://localhost:9000/tenants/48a295c5-da55-45b7-8b95-78818dc38cc2/proxy-tracking>' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8' \
-H 'Connection: keep-alive' \
-H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryEsUJBnHCya0lYGPx' \
-H 'Origin: <http://localhost:3000>' \
-H 'Referer: <http://localhost:3000/>' \
--data-raw $'------WebKitFormBoundaryEsUJBnHCya0lYGPx\r\nContent-Disposition: form-data; name="body"; filename="blob"\r\nContent-Type: application/json\r\n\r\n{"title":"dsad","description":"adsadsa","isin":"ecf66d3a-f67c-451b-86ad-47d72c271c73","date":"2024-01-04","existingDocumentIds":[],"options":[]}\r\n------WebKitFormBoundaryEsUJBnHCya0lYGPx--\r\n' \
--compressed
but just get the below error when i run
proxyTrackingFormBody(request)
{
"message": "Missing/invalid parameters",
"params": [
{
"name": "proxyTracking",
"type": "form",
"datatype": "object",
"required": true,
"reason": "Missing"
}
]
}
The multipart all looks fine, content disposition etc all looks fine so I'm at a bit of a loss.Andrew O'Hara
01/05/2024, 3:03 PMnull
in the fake scenario).
val devices = mutableMapOf<Int, HttpHandler>()
val proxyApp = routes(
{ r: Request -> r.uri.port == null }.asRouter() bind controlApi,
{ r: Request -> r.uri.port in devices }.asRouter() bind { request ->
devices[request.uri.port]!!.invoke(request)
}
)
Is there a nicer way to do this? I understand it's not typical for an HttpHandler
to be listening to multiple ports at once (the real server is actually raw Netty), but perhaps there's some more advanced routing-fu.
I'm also interested if there's a built-in way to build a dynamic reverse proxy in general; i.e. a reverse proxy where I can add routes at runtime.dave
01/05/2024, 3:46 PMdave
01/05/2024, 3:48 PMRoutingHttpHandler
which checked the dynamic list for a match when each request came in.Andrew O'Hara
01/05/2024, 4:00 PMI think that's probably about as clean as you can get it barring some tweakingYeah, that's what I suspected. Thanks for clarifying.
you'd want to just implement a new version ofThat's what I was hoping to avoid 😇 . I don't really understand this class yet, but perhaps I'll have to muscle through it.RoutingHttpHandler
Andrew O'Hara
01/05/2024, 9:18 PMdmcg
01/09/2024, 2:51 PM{
"RoleArn": "AQICAH... lots of chars ...N62A==",
"AccessKeyId": "ASIA...",
"SecretAccessKey": "***",
"Token": "IQo....",
"Expiration": "2024-01-09T14:51:19Z"
}
The token appears to be valid as far as I can see, but RoleArn is failing to parse as an ARN and throwing a wobbly before the token can be used. I note that the type is declared as a String? in the response object - maybe that’s significant (@Andrew O'Hara ?)Ahmed Riyadh
01/16/2024, 1:28 PMDanielZ
01/30/2024, 7:00 PMEnvironment
and lenses
.
When running following test:
@Test
fun `extract a list of domain ids from environment`() {
data class MyDomainId(val value: String)
val DOMAIN_ID by EnvironmentKey.csv(",")
.map(
{ strings: List<String> -> strings.map(::MyDomainId) },
{ next -> next.map(MyDomainId::value) })
.of()
.required()
val domainIds = listOf(MyDomainId("1"), MyDomainId("2"))
val environment = Environment.defaults(DOMAIN_ID of domainIds)
environment[DOMAIN_ID] shouldBe domainIds
}
it ends up in
Missing elements from index 1
expected:<[MyDomainId(value=1), MyDomainId(value=2)]> but was:<[MyDomainId(value=1)]>
Expected :[MyDomainId(value=1), MyDomainId(value=2)]
Actual :[MyDomainId(value=1)]
<Click to see difference>
io.kotest.assertions.AssertionFailedError: Missing elements from index 1
Replacing the delimiter in csv()
to for example ":"
makes the test pass.
My findings so far: it’s not the csv()
part - this happens when I split
the string by hand.
How can I use both type-safety of the lens
and ,
as separator? Where is my misunderstanding?Gopal S Akshintala
02/03/2024, 12:59 PMisSuccessful
. A over simplified example:
Success response:
{
"isSuccessful": true,
"value": "Okay!"
}
Failure response:
{
"isSuccessful": false,
"error_logs": {
"order": 66
}
}
All the examples I referred use String
as TypeLabel. How can I use boolean
field instead of String
?Tamara
02/13/2024, 3:38 PMAndrew O'Hara
02/13/2024, 11:21 PMautoDynamoLens
can't map SS
and NS
properties properly. When writing it will convert them to a List Dynamo type. When reading it will omit the sets from the result. Is this known? Or was it overlooked?Andrew O'Hara
02/15/2024, 3:38 PMTamara
02/22/2024, 11:32 AMOliver
02/24/2024, 6:34 PMQuery
action has a Select
parameter of the corresponding enum type, whereas in the Scan
action the Select
parameter is just a string. I suppose that's an oversight, since the same set of values can be used for both actions. Are there any concerns in changing the type in Scan
also to the Select
enum (even if this would be an incompatible change)?Oliver
02/24/2024, 7:03 PMCount
and ScannedCount
elements are always returned. So why are they optional in the corresponding classes QueryResponse
and ScanResponse
? (Background: I would like to add a count
convenience function to the DynamoDbIndexMapper
.)Tamara
02/27/2024, 3:37 PMCosmin Marginean
02/29/2024, 12:28 PMEnvironment
from a .yaml
in the classpath, but I see there's only Environment.fromYaml(file: File)
and classpath support can only be used for .properties
files.
Is there a way to do this that I might be missing?Andrew O'Hara
02/29/2024, 6:57 PMjetty11
fallback saved me again. I have hundreds of thousands of IOT devices hitting a config server, and for some reason, they didn't like something in the jetty12 response (even with an ELB in the way) and began DDOSing us with their retries. No idea why the devices didn't like the jetty 12 response, but based on what I know of the manufacturer, I'm inclined to believe it's more of a device problem then a jetty problem 🙃.Dmitry Kandalov
03/01/2024, 11:24 AMroutes()
which chooses the first matching handler? Or is it the wrong thing to do anyway?
For the context I’m profiling a simple http4k app (with get/set endpoints) and can see that OrRouter
takes about 5% of time. Wondering if there is an easy way to make it ~0% 😅Dmitry Kandalov
03/01/2024, 1:18 PMOAuthPersistence
? I can see there is FakeOAuthPersistence
and InsecureCookieBasedOAuthPersistence
but it’s not too clear to me what a real implementation should do blob smile Or FakeOAuthPersistence
and CustomOAuthPersistence
are good enough?Cosmin Marginean
03/01/2024, 3:45 PMMarco Garofalo
03/04/2024, 9:01 AMMarco Garofalo
03/07/2024, 2:07 PMMrNiamh
03/09/2024, 4:03 PMAdrian Witaszak
03/14/2024, 8:19 PMAPIGatewayV2HTTPEvent
in the FnHandler
but getting Reflection errorzed
03/15/2024, 9:45 AM“-XX:+UseParallelGC -XX:ActiveProcessorCount=2 -XX:MaxRAMPercentage=65.0 -XX:MinRAMPercentage=60.0”
• Http4k: 5.14.0.0
• Server: Undertow (but also netty)
• ~30 requests / second
• AWS, Kubernetes:
◦ requests: { memory: 1720Mi, cpu: 500m }
◦ limits: { memory: 1720Mi, cpu: 2000m }
Observations:
• When overall CPU usage starts to increase, minor GC usage completely stopped.
• Self-healing effect (over ~12 hours).
• Response time increases massively in the “explosion” phase (currently we have a timeout of 10s on client side).elect
03/16/2024, 7:26 AMelect
03/18/2024, 10:42 AM-d '{"ref":"refs/heads/featureA","sha":"aa218f56b14c9653891f9e74264a383fa43fefbd"}'