Azure / Azure/azure-functions-java-worker

Add support for LocalDate (or OffsetDateTime, etc.) in HttpRequestMessage<Optional<T>> in Functions with Spring Cloud

Đang mở
#709 2 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:java-functions Enhancement needs-discussion Needs: Triage (Functions) reviewed
Ngôn ngữ chính
Java
Star
103
Fork
74
Merge trung bình
4 ngày 8 giờ
Pull request đã merge (30 ngày)
2

Mô tả

#### Investigative information

Please provide the following:

- Timestamp: 2023-03-16T10:26:35.390Z
- Function App name: local development
- Function name(s) (as appropriate): local development
- Invocation ID: local development
- Region: local development

#### Repro steps

Provide the steps required to reproduce the problem:

1. Define any POJO with a `LocalDate` or `OffsetDateTime` property, e.g. `User`
2. Use the POJO as request body for your HTTP call, e.g. `HttpRequestMessage>`
3. Build & run your Application (`mvn azure-functions:run`)
4. Call your function and define the request body as defined in the POJO

#### Expected behavior

Provide a description of the expected behavior.

After Step 4 I expect to have called the function successfully

#### Actual behavior

Provide a description of the actual behavior observed.

Step 4 won't work because I always get the same error message as follows:

```
[2023-03-16T10:26:35.390Z] [WARNING] {CheckedBiFunction.tryApply}: InaccessibleObjectException: Unable to make field private final int java.time.LocalDate.year accessible: module java.base does not "opens java.time" to unnamed module @2b05039f
[2023-03-16T10:26:35.447Z] Executed 'Functions.person' (Failed, Id=c4d45e9c-b0df-49ab-9051-004d3e8a384b, Duration=288ms)
[2023-03-16T10:26:35.450Z] System.Private.CoreLib: Exception while executing function: Functions.person. System.Private.CoreLib: Result: Failure
Exception: ClassCastException: Cannot convert com.microsoft.azure.functions.worker.binding.RpcHttpRequestDataSource@3a19100ato type com.microsoft.azure.functions.HttpRequestMessage>
Stack: java.lang.ClassCastException: Cannot convert com.microsoft.azure.functions.worker.binding.RpcHttpRequestDataSource@3a19100ato type com.microsoft.azure.functions.HttpRequestMessage>
[2023-03-16T10:26:35.455Z] at com.microsoft.azure.functions.worker.binding.DataOperations.generalAssignment(DataOperations.java:191)
[2023-03-16T10:26:35.460Z] at com.microsoft.azure.functions.worker.binding.DataOperations.apply(DataOperations.java:120)
[2023-03-16T10:26:35.462Z] at com.microsoft.azure.functions.worker.binding.DataSource.computeByType(DataSource.java:56)
[2023-03-16T10:26:35.470Z] at com.microsoft.azure.functions.worker.binding.RpcHttpRequestDataSource.computeByType(RpcHttpRequestDataSource.java:20)
[2023-03-16T10:26:35.477Z] at com.microsoft.azure.functions.worker.binding.DataSource.computeByName(DataSource.java:42)
[2023-03-16T10:26:35.479Z] at com.microsoft.azure.functions.worker.binding.RpcHttpRequestDataSource.computeByName(RpcHttpRequestDataSource.java:20)
[2023-03-16T10:26:35.496Z] at com.microsoft.azure.functions.worker.binding.BindingDataStore.getDataByName(BindingDataStore.java:59)
[2023-03-16T10:26:35.505Z] at com.microsoft.azure.functions.worker.binding.ExecutionContextDataSource.getBindingData(ExecutionContextDataSource.java:176)
[2023-03-16T10:26:35.511Z] at com.microsoft.azure.functions.worker.broker.ParameterResolver.resolve(ParameterResolver.java:44)
[2023-03-16T10:26:35.518Z] at com.microsoft.azure.functions.worker.broker.ParameterResolver.resolveArguments(ParameterResolver.java:22)
[2023-03-16T10:26:35.525Z] at com.microsoft.azure.functions.worker.broker.EnhancedJavaMethodExecutorImpl.execute(EnhancedJavaMethodExecutorImpl.java:20)
[2023-03-16T10:26:35.528Z] at com.microsoft.azure.functions.worker.chain.FunctionExecutionMiddleware.invoke(FunctionExecutionMiddleware.java:19)
[2023-03-16T10:26:35.552Z] at com.microsoft.azure.functions.worker.chain.InvocationChain.doNext(InvocationChain.java:21)
[2023-03-16T10:26:35.561Z] at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:125)
[2023-03-16T10:26:35.566Z] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:37)
[2023-03-16T10:26:35.572Z] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:12)
[2023-03-16T10:26:35.580Z] at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:44)
[2023-03-16T10:26:35.587Z] at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:93)
[2023-03-16T10:26:35.589Z] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
[2023-03-16T10:26:35.603Z] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[2023-03-16T10:26:35.615Z] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[2023-03-16T10:26:35.627Z] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[2023-03-16T10:26:35.629Z] at java.base/java.lang.Thread.run(Thread.java:833)
```

#### Known workarounds

Provide a description of any known workarounds.

The current workaround would be to use a `String` instead of the immutable date objects. But that would not be suffice, because in our project we want to work with generated models that uses the ISO datetime.

Another workaround would be that we use `Java.util.Date` when generating our models, but I don't really like the idea of using that.

#### Related information

Provide any related information

* Programming language used: Java 17
* Bindings used: EventHubBinding, HttpTrigger

Source

```java

@Component
@RequiredArgsConstructor
public class PersonHandler {

private final Person person;

@FunctionName("person")
public HttpResponseMessage execute(
@HttpTrigger(
name = "request",
methods = {HttpMethod.POST, HttpMethod.DELETE},
authLevel = AuthorizationLevel.ANONYMOUS
) HttpRequestMessage> request,
@EventHubOutput(

) OutputBinding output,
ExecutionContext context) {

context.getLogger().info("Hello there, General Kenobi");

final User user= request.getBody().orElse(null);

if (user == null) {
return request
.createResponseBuilder(HttpStatus.BAD_REQUEST)
.body("Please do it right")
.build();
} else {
final CloudEvent event = person.apply(user);

final byte[] serializedEvent = Objects.requireNonNull(EventFormatProvider
.getInstance()
.resolveFormat(JsonFormat.CONTENT_TYPE))
.serialize(event);

output.setValue(serializedEvent);

return request
.createResponseBuilder(HttpStatus.OK)
.body("Sucess!")
.build();
}
}
}

@Component
@RequiredArgsConstructor
public class Person implements Function {

@Override
public CloudEvent apply(User user) {
try {
final ObjectMapper objectMapper = new ObjectMapper();
final byte[] serializedPojo = objectMapper.writeValueAsBytes(user);

final LocalDateTime now = LocalDateTime.now();
final ZoneId zone = ZoneId.of("Europe/Berlin");
final ZoneOffset zoneOffset = zone.getRules().getOffset(now);

return CloudEventBuilder.v1()
.withId(UUID.randomUUID().toString())
.withSource(URI.create("/some/uri"))
.withType("TYPE")
.withDataContentType("application/json")
.withSubject("SUBJECT")
.withTime(OffsetDateTime.of(now, zoneOffset))
.withData(serializedPojo)
.build();
} catch (JsonProcessingException e) {
return null;
}
}
}

4.0.0
com.example
beep
0.0.1-${revision}
com.example.beep


org.springframework.boot
spring-boot-starter-parent
3.0.1

BeepFunction


local
17

UTF-8

17
17

1.24.0
3.0.0
4.0.0
2.4.2
1.18.26


not relevant
not relevant
not relevant

westeurope
EP1
${project.build.directory}/azure-functions/${functionAppName}

com.example.BeepApplication




org.springframework.cloud
spring-cloud-function-adapter-azure


org.springframework.cloud
spring-cloud-starter-function-webflux
provided



org.projectlombok
lombok
${lombok.version}
provided


io.cloudevents
cloudevents-core
${cloudevents.version}


io.cloudevents
cloudevents-json-jackson
${cloudevents.version}


org.openapitools
jackson-databind-nullable
0.2.4


io.swagger.core.v3
swagger-annotations
2.2.8



jakarta.validation
jakarta.validation-api
3.0.2



jakarta.annotation
jakarta.annotation-api
2.1.1



org.springframework.boot
spring-boot-starter-test
test


org.junit.jupiter
junit-jupiter-api
test


org.mockito
mockito-core
2.23.4
test


org.assertj
assertj-core
3.24.2
test




org.springframework.cloud
spring-cloud-function-dependencies
${spring.cloud.function.dependencies}
pom
import


com.microsoft.azure.functions
azure-functions-java-library
${azure.functions.java.library.version}






com.microsoft.azure
azure-functions-maven-plugin
${azure.functions.maven.plugin.version}


org.apache.maven.plugins
maven-resources-plugin
3.3.0


org.apache.maven.plugins
maven-dependency-plugin
3.4.0


org.apache.maven.plugins
maven-clean-plugin




org.openapitools
openapi-generator-maven-plugin
6.3.0


generate-contract

generate


${project.basedir}/src/main/resources/some-spec.yaml
spring

true
true
true


@lombok.Builder @lombok.NoArgsConstructor @lombok.AllArgsConstructor


false
false





com.microsoft.azure
azure-functions-maven-plugin

${functionResourceGroup}
${functionAppName}
${functionAppRegion}
${functionAppServicePlanName}
${functionAppPricingTier}

${project.basedir}/src/main/azure/host.json
${project.basedir}/src/main/azure/local.settings.json


linux
17




FUNCTIONS_EXTENSION_VERSION
~4





package-functions

package






maven-clean-plugin
3.2.0



obj





org.springframework.boot
spring-boot-maven-plugin


```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu với đường dẫn binding trong DataOperations.java và RpcHttpRequestDataSource.java, sau đó tái hiện vấn đề bằng ví dụ PersonHandler được cung cấp và `mvn azure-functions:run`. Xác minh cách một POJO chứa LocalDate hoặc OffsetDateTime được chuyển đổi cho HttpRequestMessage>; hoàn tất khi request được binding thành công mà không có exception đã báo cáo.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
azure, java, spring
Lĩnh vực
api, backend, cloud
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.