Skip to content
This repository was archived by the owner on Aug 17, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions backend/ingress/ingress_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (

func TestHttpIngress(t *testing.T) {
in.Run(t,
in.WithLanguages("go", "java"),
in.WithLanguages("go", "java", "kotlin"),
in.CopyModule("httpingress"),
in.Deploy("httpingress"),
in.SubTests(
Expand Down Expand Up @@ -132,7 +132,7 @@ func TestHttpIngress(t *testing.T) {
assert.Equal(t, nil, resp.Headers["Access-Control-Allow-Headers"])
})},
),
in.IfLanguage("go", in.SubTests(
in.IfLanguages(in.SubTests(
// Double, Int etc work in java with JSON encoding, but test/plain is not implemented yet
in.SubTest{Name: "PostInt", Action: in.HttpCall(http.MethodPost, "/int", nil, []byte("1234"), func(t testing.TB, resp *in.HTTPResponse) {
assert.Equal(t, 200, resp.Status)
Expand Down Expand Up @@ -172,10 +172,10 @@ func TestHttpIngress(t *testing.T) {
in.SubTest{Name: "TestExtraFieldLenient", Action: in.HttpCall(http.MethodPost, "/lenient", nil, in.JsonData(t, in.Obj{"user_id": 123, "postId": 345, "extra": "blah"}), func(t testing.TB, resp *in.HTTPResponse) {
assert.Equal(t, 201, resp.Status)
})},
)),
), "go", "kotlin"),

in.IfLanguage("java", in.SubTests(
// Double, Int etc work in java with JSON encoding, but test/plain is not implemented yet
// Double, Int etc work in java with JSON encoding, but text/plain is not implemented yet
in.SubTest{Name: "JavaVerbClient", Action: in.HttpCall(http.MethodGet, "/client", nil, nil, func(t testing.TB, resp *in.HTTPResponse) {
assert.Equal(t, 200, resp.Status)
assert.Equal(t, []byte("Hello"), resp.BodyBytes)
Expand Down
2 changes: 2 additions & 0 deletions backend/ingress/testdata/kotlin/httpingress/ftl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "httpingress"
language = "kotlin"
14 changes: 14 additions & 0 deletions backend/ingress/testdata/kotlin/httpingress/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ftl.httpingress</groupId>
<artifactId>httpingress</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>xyz.block.ftl</groupId>
<artifactId>ftl-build-parent-kotlin</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ftl.httpingress;

data class ArrayType(
val item: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ftl.httpingress;

data class DeleteRequest(
val userId: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ftl.httpingress;

class DeleteResponse {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ftl.httpingress;

data class GetRequest(
val userId: String,
val postId: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ftl.httpingress;

data class GetResponse(
val nested: Nested,
val msg: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ftl.httpingress;

import xyz.block.ftl.SourceVerb
import xyz.block.ftl.Verb

@Verb
fun hello(): String {
return "Hello"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ftl.httpingress;

import com.fasterxml.jackson.annotation.JsonAlias;

data class Nested(
@field:JsonAlias("good_stuff")
val goodStuff: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ftl.httpingress;

import com.fasterxml.jackson.annotation.JsonAlias;

data class PostRequest(
@field:JsonAlias("user_id")
val userId: Long,
val postId: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ftl.httpingress;

data class PostResponse(
val success: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ftl.httpingress;

data class PutRequest(
val postId: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ftl.httpingress;

class PutResponse {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ftl.httpingress;

import org.jetbrains.annotations.Nullable;

data class QueryParamRequest(
val foo:String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package ftl.httpingress;

import java.util.List;

import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import org.jboss.resteasy.reactive.ResponseHeader;
import org.jboss.resteasy.reactive.ResponseStatus;
import org.jboss.resteasy.reactive.RestPath;
import org.jboss.resteasy.reactive.RestQuery;

@Path("/")
class TestHTTP {

@GET
@Path("/users/{userId}/posts/{postId}")
@ResponseHeader(name = "Get", value = ["Header from FTL"])
fun get(
@RestPath userId:Long,
@RestPath postId:Long
): GetResponse {
return GetResponse(
nested = Nested(
goodStuff = "This is good stuff"
),
msg = String.format("UserID: %s, PostID: %s", userId, postId),
)
}

@GET
@Path("/getquery")
@ResponseHeader(name = "Get", value = ["Header from FTL"])
fun getquery(@RestQuery userId:Long, @RestQuery postId:Long): GetResponse {
return GetResponse(
msg = String.format("UserID: %s, PostID: %s", userId, postId),
nested = Nested(
goodStuff = "This is good stuff"
),
)
}

@POST
@Path("/users")
@ResponseStatus(201)
@ResponseHeader(name = "Post", value = ["Header from FTL"])
fun post(req: PostRequest): PostResponse {
return PostResponse(success = true)
}

@PUT
@Path("/users/{userId}")
@ResponseHeader(name = "Put", value = ["Header from FTL"])
fun put(req:PutRequest): PutResponse {
return PutResponse();
}

@DELETE
@Path("/users/{userId}")
@ResponseHeader(name = "Delete", value = ["Header from FTL"])
@ResponseStatus(200)
fun delete(@RestPath userId:String): DeleteResponse {
System.out.println("delete");
return DeleteResponse();
}

@GET
@Path("/queryparams")
fun query(@RestQuery foo:String): String {
if (foo == null) {
return "No value";
}
return foo;
}

@GET
@Path("/html")
@Produces("text/html; charset=utf-8")
fun html() : String {
return "<html><body><h1>HTML Page From FTL 🚀!</h1></body></html>";
}

@POST
@Path("/bytes")
fun bytes(b: ByteArray): ByteArray {
return b;
}

@GET
@Path("/empty")
@ResponseStatus(200)
fun empty() {
}

@POST
@Path("/string")
fun string(value:String): String {
return value;
}

@POST
@Path("/int")
@Produces(MediaType.APPLICATION_JSON)
fun intMethod(value:Int): Int {
return value;
}

@POST
@Path("/float")
@Produces(MediaType.APPLICATION_JSON)
fun floatVerb(value:Float): Float {
return value;
}

@POST
@Path("/bool")
@Produces(MediaType.APPLICATION_JSON)
fun bool(value:Boolean): Boolean {
return value;
}

@GET
@Path("/error")
fun error():String {
throw RuntimeException("Error from FTL");
}

@POST
@Path("/array/string")
fun arrayString(array:List<String>): List<String> {
return array;
}

@POST
@Path("/array/data")
fun arrayData(array:List<ByteArray>): List<ByteArray> {
return array;
}
}
Loading