最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Quarkus Funqy lambda handler returns 404 HTML intermittently, does not execute handler code - Stack Overflow

programmeradmin4浏览0评论

In summary: Sometimes my AWS Lambda handler built with Quarkus Funqy is not invoked and Quarkus seem to return some default 404 HTML, both when running locally with Quarkus Dev Mode and deploying native executable to AWS Lambda. I ask for assistance in fixing this behavior. Below I define how the application works and how it is configured.

The purpose of this lambda is registering and fetching a specific entity (POST and GET operations). I intend to build native executable.

@ApplicationScoped
public class DeviceController {

    private static final Logger log = LoggerFactory.getLogger(DeviceController.class);
    private final DeviceService deviceService;
    private final ObjectMapper objectMapper;
    @Inject
    public DeviceController(DeviceService deviceService) {
        this.deviceService = deviceService;
        this.objectMapper = new ObjectMapper().registerModule(new JavaTimeModule())
                .disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
    }

    @Funq
    public Map<String, Object> handler(Map<String, Object> apiRequestEvent) {
        try {
            String path = (String) apiRequestEvent.get("path");
            String httpMethod = (String) apiRequestEvent.get("httpMethod");
            String body = (String) apiRequestEvent.get("body");
            Map<String, String> queryStringParameters = readQueryParameters(apiRequestEvent);
            if (!path.equals("/device")) {
                throw new ServiceException(String.format("Path %s does not exist", path)
                        , GlobalExceptionCode.INVALID_PATH);
            }
            return switch (httpMethod) {
                case "POST"-> this.createDevice(body);
                case "GET"-> this.getDevice(queryStringParameters);
                default ->  throw new ServiceException("Invalid method", GlobalExceptionCode.INVALID_METHOD);
            };
        } catch (ServiceException ex ){
            return handleServiceException(ex);
        } catch ( ModelException ex){
            return handleModelException(ex);
        } catch (RuntimeException ex){
            return handleRuntimeException(ex);
        } catch (Exception e) {
            return handleGenericException(e);
        }
    }

The handler layer is nothing fancy: I can highlight the handler receives a Map<String,Object> for he API Gateway request event (with body, queryStringParameters, httpMethod etc), and returns another Map for the API Gateway response event. It uses dependency injection of a service layer to handle business logic. There's auxiliary methods to parse the input map and to build the output map. I'll attach pom.xml and application.properties at the end.

The handler code mostly fine when debugging locally on Quarkus Dev mode, and also works when building a native executable and deploying to AWS Lambda. However, there's this weird behavior where sometimes the handler is not invoked (does not even trigger debugger breakpoint on the first line), and calling the handler returns a 404.

Here's the lambda running succesfully in quarkus dev mode, calling from Postman:

Here's the intermittent error when running locally:

Here's the intermittent error on AWS Lambda:

Here's application.properties, I don't think there's relevant stuff in here. Today I tried defining the method 'handler' as the Funqy handler, but it changed nothing as I only have one handler annotated with @Funq. There's also configuration for the native build which don't affect the application running locally on Quarkus dev mode.

quarkus.funqy.export=handler

lambda.bastion.write.arn=${BASTION_WRITE_ARN}
lambda.bastion.read.arn=${BASTION_READ_ARN}
quarkus.amazon-services-lambda.sync-client.type=url-connection

quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:23.1-jdk-21
quarkus.native.container-build=true
quarkus.native.container-runtime=docker
quarkus.native.additional-build-args=-march=compatibility

Here's pom.xml. I can highlight the usage of the AWS SDK since I need to call another lambda for database access, MapStruct for DTO mapping and Apache commons commons-lang3 for some legacy utility code I've reused from another company application.

(Omitted project definitions and properties...)
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>${quarkus.platform.artifact-id}</artifactId>
                <version>${quarkus.platform.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.30.37</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.quarkiverse.amazonservices</groupId>
                <artifactId>quarkus-amazon-services-bom</artifactId>
                <version>3.3.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.quarkiverse.amazonservices</groupId>
            <artifactId>quarkus-amazon-lambda</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>url-connection-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-funqy-amazon-lambda</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-rest-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-amazon-lambda-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-amazon-lambda</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jacoco</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5-mockito</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>.apachemons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>io.quarkus</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <java.util.logging.manager>.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <groupId>.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>21</source>
                    <target>21</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <version>${surefire-plugin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                                <configuration>
                                    <systemPropertyVariables>
                                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                                        <java.util.logging.manager>.jboss.logmanager.LogManager</java.util.logging.manager>
                                        <maven.home>${maven.home}</maven.home>
                                    </systemPropertyVariables>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <properties>
                <quarkus.native.enabled>true</quarkus.native.enabled>
            </properties>
        </profile>
    </profiles>
</project>

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论