diff --git a/inngest-spring-boot-adapter/README.md b/inngest-spring-boot-adapter/README.md new file mode 100644 index 00000000..f0a2a04a --- /dev/null +++ b/inngest-spring-boot-adapter/README.md @@ -0,0 +1,5 @@ +# inngest-spring-boot-adapter + +Adapter to serve Inngest functions from a SpringBoot application. + + diff --git a/inngest-spring-boot-adapter/VERSION b/inngest-spring-boot-adapter/VERSION index bcab45af..bbdeab62 100644 --- a/inngest-spring-boot-adapter/VERSION +++ b/inngest-spring-boot-adapter/VERSION @@ -1 +1 @@ -0.0.3 +0.0.5 diff --git a/inngest-spring-boot-adapter/build.gradle.kts b/inngest-spring-boot-adapter/build.gradle.kts index 11e82d7e..8d5486cf 100644 --- a/inngest-spring-boot-adapter/build.gradle.kts +++ b/inngest-spring-boot-adapter/build.gradle.kts @@ -23,7 +23,7 @@ repositories { } dependencies { - val pkg = if (System.getenv("RELEASE") != null) "com.inngest:inngest:[0.0, 0.1)" else project(":inngest") + val pkg = if (System.getenv("RELEASE") != null) "com.inngest:inngest:[0.0.5, 0.1)" else project(":inngest") api(pkg) implementation("org.springframework.boot:spring-boot-starter-web") diff --git a/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestConfiguration.java b/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestConfiguration.java index 2c10cc33..746a0884 100644 --- a/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestConfiguration.java +++ b/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestConfiguration.java @@ -15,9 +15,10 @@ public abstract class InngestConfiguration { protected abstract Inngest inngestClient(); @Bean - protected CommHandler commHandler(@Autowired Inngest inngestClient) { - // TODO: Add missing configuration - ServeConfig serveConfig = new ServeConfig(inngestClient); - return new CommHandler(functions(), inngestClient, serveConfig, frameworkName); + protected abstract ServeConfig serve(@Autowired Inngest inngestClient); + + @Bean + protected CommHandler commHandler(@Autowired Inngest inngestClient, @Autowired ServeConfig serve) { + return new CommHandler(functions(), inngestClient, serve, frameworkName); } } diff --git a/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestController.java b/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestController.java index bd25eb4a..66ff8804 100644 --- a/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestController.java +++ b/inngest-spring-boot-adapter/src/main/java/com/inngest/springboot/InngestController.java @@ -4,12 +4,14 @@ import com.inngest.CommResponse; import com.inngest.signingkey.SignatureVerificationKt; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; + public abstract class InngestController { @Autowired CommHandler commHandler; @@ -20,15 +22,33 @@ private HttpHeaders getHeaders() { return headers; } + // ex. https://api.mysite.com + @Value("${inngest.serveOrigin:}") + private String serveOrigin; + @GetMapping() - public ResponseEntity index() { - String response = commHandler.introspect(); + public ResponseEntity index( + @RequestHeader(HttpHeaders.HOST) String hostHeader, + HttpServletRequest request + ) { + String origin = String.format("%s://%s", request.getScheme(), hostHeader); + if (this.serveOrigin != null && !this.serveOrigin.isEmpty()) { + origin = this.serveOrigin; + } + String response = commHandler.introspect(origin); return ResponseEntity.ok().headers(getHeaders()).body(response); } @PutMapping() - public ResponseEntity put() { - String response = commHandler.register(); + public ResponseEntity put( + @RequestHeader(HttpHeaders.HOST) String hostHeader, + HttpServletRequest request + ) { + String origin = String.format("%s://%s", request.getScheme(), hostHeader); + if (this.serveOrigin != null && !this.serveOrigin.isEmpty()) { + origin = this.serveOrigin; + } + String response = commHandler.register(origin); return ResponseEntity.ok().headers(getHeaders()).body(response); } diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java index 4e81c4e3..9e8992ee 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoConfiguration.java @@ -21,7 +21,12 @@ public HashMap functions() { } @Override - public Inngest inngestClient() { + protected Inngest inngestClient() { return new Inngest("spring_demo"); } + + @Override + protected ServeConfig serve(Inngest inngestClient) { + return new ServeConfig(inngestClient); + } } diff --git a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoController.java b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoController.java index 06b639a6..bf59ce65 100644 --- a/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoController.java +++ b/inngest-spring-boot-demo/src/main/java/com/inngest/springbootdemo/DemoController.java @@ -7,4 +7,5 @@ @RestController @RequestMapping(value = "/api/inngest") public class DemoController extends InngestController { + } diff --git a/inngest-spring-boot-demo/src/main/resources/application.yml b/inngest-spring-boot-demo/src/main/resources/application.yml index a1f56d6e..a7afc92b 100644 --- a/inngest-spring-boot-demo/src/main/resources/application.yml +++ b/inngest-spring-boot-demo/src/main/resources/application.yml @@ -1,4 +1,2 @@ server: - port: 8080 # We probably want to change this to 8081 to avoid port conflicts - # but I kept it for now because of the hardcoded URL that are sent - # to the inngest dev-server. + port: 8080 diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/CustomStepResultIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/CustomStepResultIntegrationTest.java index e83aec30..bae32e3c 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/CustomStepResultIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/CustomStepResultIntegrationTest.java @@ -16,7 +16,7 @@ class CustomStepResultIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoControllerTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoControllerTest.java index 7a2e8f03..f187d487 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoControllerTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoControllerTest.java @@ -19,11 +19,12 @@ public class DemoControllerTest { @Test public void shouldReturnSyncPayload() throws Exception { - mockMvc.perform(get("/api/inngest")) + mockMvc.perform(get("/api/inngest").header("Host", "localhost:8080")) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(header().string(InngestHeaderKey.Framework.getValue(), "springboot")) .andExpect(jsonPath("$.appName").value("spring_test_demo")) + .andExpect(jsonPath("$.url").value("http://localhost:8080/api/inngest")) .andExpect(jsonPath("$.sdk").value("inngest-kt")); } } diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java index 6892142f..0e576eb9 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/DemoTestConfiguration.java @@ -35,6 +35,11 @@ protected Inngest inngestClient() { return new Inngest("spring_test_demo"); } + @Override + protected ServeConfig serve(Inngest client) { + return new ServeConfig(client); + } + @Bean protected CommHandler commHandler(@Autowired Inngest inngestClient) { ServeConfig serveConfig = new ServeConfig(inngestClient); diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/ErrorsInStepsIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/ErrorsInStepsIntegrationTest.java index be89493e..ec8ec084 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/ErrorsInStepsIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/ErrorsInStepsIntegrationTest.java @@ -19,7 +19,7 @@ class ErrorsInStepsIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java index 626e3981..470e31e8 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/MultiStepsFunctionIntegrationTest.java @@ -15,7 +15,7 @@ class MultiStepsFunctionIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java index ab98f8b1..f7151926 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/NoStepFunctionIntegrationTest.java @@ -15,7 +15,7 @@ class NoStepFunctionIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java index 6ec8864c..19e57acd 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SendEventFunctionIntegrationTest.java @@ -18,7 +18,7 @@ class SendEventFunctionIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java index 6f4a3e83..78848e42 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/SleepFunctionIntegrationTest.java @@ -16,7 +16,7 @@ class SleepFunctionIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java index a935a0ca..35dd4090 100644 --- a/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java +++ b/inngest-spring-boot-demo/src/test/java/com/inngest/springbootdemo/WaitForEventFunctionIntegrationTest.java @@ -16,7 +16,7 @@ class WaitForEventFunctionIntegrationTest { @BeforeAll static void setup(@Autowired CommHandler handler) { - handler.register(); + handler.register("http://localhost:8080"); } @Autowired diff --git a/inngest/VERSION b/inngest/VERSION index 81340c7e..bbdeab62 100644 --- a/inngest/VERSION +++ b/inngest/VERSION @@ -1 +1 @@ -0.0.4 +0.0.5 diff --git a/inngest/src/main/kotlin/com/inngest/Comm.kt b/inngest/src/main/kotlin/com/inngest/Comm.kt index ad48316d..c3f4a0d8 100644 --- a/inngest/src/main/kotlin/com/inngest/Comm.kt +++ b/inngest/src/main/kotlin/com/inngest/Comm.kt @@ -112,15 +112,16 @@ class CommHandler( return mapper.writeValueAsString(requestBody) } - private fun getFunctionConfigs(): List> { + + private fun getFunctionConfigs(origin: String): List> { val configs: MutableList> = mutableListOf() - functions.forEach { entry -> configs.add(entry.value.getFunctionConfig(getServeUrl(), client)) } + functions.forEach { entry -> configs.add(entry.value.getFunctionConfig(getServeUrl(origin), client)) } return configs } - fun register(): String { + fun register(origin: String): String { val registrationUrl = "${config.baseUrl()}/fn/register" - val requestPayload = getRegistrationRequestPayload() + val requestPayload = getRegistrationRequestPayload(origin) val httpClient = client.httpClient @@ -147,24 +148,25 @@ class CommHandler( return Result.success(InngestSyncResult.None) } - fun introspect(): String { - val requestPayload = getRegistrationRequestPayload() + fun introspect(origin: String): String { + val requestPayload = getRegistrationRequestPayload(origin) return parseRequestBody(requestPayload) } - private fun getRegistrationRequestPayload(): RegistrationRequestPayload { + private fun getRegistrationRequestPayload(origin: String): RegistrationRequestPayload { return RegistrationRequestPayload( appName = config.appId(), framework = framework.toString(), sdk = "inngest-kt", - url = getServeUrl(), + url = getServeUrl(origin), v = Version.getVersion(), - functions = getFunctionConfigs(), + functions = getFunctionConfigs(origin), ) } - private fun getServeUrl(): String { - val serveOrigin = config.serveOrigin() ?: "http://localhost:8080" + private fun getServeUrl(origin: String): String { + // TODO - property from SpringBoot should take preference to env variable? + val serveOrigin = config.serveOrigin() ?: origin val servePath = config.servePath() ?: "/api/inngest" return "$serveOrigin$servePath" } diff --git a/inngest/src/main/kotlin/com/inngest/ktor/Route.kt b/inngest/src/main/kotlin/com/inngest/ktor/Route.kt index e4d010b0..23406c34 100644 --- a/inngest/src/main/kotlin/com/inngest/ktor/Route.kt +++ b/inngest/src/main/kotlin/com/inngest/ktor/Route.kt @@ -3,6 +3,7 @@ package com.inngest.ktor import com.inngest.* import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.plugins.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* @@ -42,7 +43,11 @@ fun Route.serve( route(path) { get("") { - val resp = comm.introspect() + var origin = String.format("%s://%s", call.request.origin.scheme, call.request.origin.serverHost) + if (call.request.origin.serverPort != 80 || call.request.origin.serverPort != 443) { + origin = String.format("%s:%s", origin, call.request.origin.serverPort) + } + val resp = comm.introspect(origin) call.respond(HttpStatusCode.OK, resp) } @@ -72,7 +77,11 @@ fun Route.serve( } put("") { - val resp = comm.register() + var origin = String.format("%s://%s", call.request.origin.scheme, call.request.origin.serverHost) + if (call.request.origin.serverPort != 80 || call.request.origin.serverPort != 443) { + origin = String.format("%s:%s", origin, call.request.origin.serverPort) + } + val resp = comm.register(origin) call.respond(HttpStatusCode.OK, resp) } }