Azure / azure-functions-java-library

Contains annotations for writing Azure Functions in Java
MIT License
43 stars 43 forks source link

Azure Functions not able to access partition context in eventhub trigger in Java #95

Closed siva007tv closed 4 years ago

siva007tv commented 4 years ago

Hi,

I am trying to access the partition context from EventHubTrigger Azure Functions using Java language but not able to get it.It's throwing error in the run time. Please help me.

CODE

import com.microsoft.azure.eventhubs.EventData; import com.microsoft.azure.eventprocessorhost.PartitionContext; import com.microsoft.azure.functions.ExecutionContext; import com.microsoft.azure.functions.annotation.BindingName; import com.microsoft.azure.functions.annotation.Cardinality; import com.microsoft.azure.functions.annotation.EventHubTrigger; import com.microsoft.azure.functions.annotation.FunctionName; public class Eventhubtriggerfn {

@FunctionName("Eventhubtriggerfn")
public void run(

@BindingName("SystemProperties") Map<String, Object> systemProperties,

    @EventHubTrigger(name = "message", eventHubName = "notificationdeveventhub", connection = "AzureEventHubConnection", 
    consumerGroup = "$Default", cardinality = Cardinality.ONE) EventData events,PartitionContext partitionContext,
    final ExecutionContext context
) {

}

ERROR

[9/14/2019 11:48:34 AM] Executed 'Functions.Eventhubtriggerfn' (Failed, Id=ed76248e-8d1b-46ec-98fa-ddf9ba300c18) [9/14/2019 11:48:34 AM] System.Private.CoreLib: Exception while executing function: Functions.Eventhubtriggerfn. System.Private.CoreLib: Result: Failure Exception: UnsupportedOperationException: Interface can't be instantiated! Interface name: com.microsoft.azure.eventhubs.EventData Stack: java.lang.RuntimeException: Unable to invoke no-args constructor for interface com.microsoft.azure.eventhubs.EventData. Registering an InstanceCreator with Gson for this type may fix this problem. [9/14/2019 11:48:34 AM] at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:228) [9/14/2019 11:48:34 AM] at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212) [9/14/2019 11:48:34 AM] at com.google.gson.Gson.fromJson(Gson.java:927) [9/14/2019 11:48:34 AM] at com.google.gson.Gson.fromJson(Gson.java:892) [9/14/2019 11:48:34 AM] at com.google.gson.Gson.fromJson(Gson.java:841) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.DataOperations.convertFromJson(DataOperations.java:158) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.DataOperations.apply(DataOperations.java:114) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.DataSource.computeByType(DataSource.java:56) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.RpcStringDataSource.computeByType(RpcStringDataSource.java:5) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.DataSource.computeByName(DataSource.java:42) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.RpcStringDataSource.computeByName(RpcStringDataSource.java:5) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.binding.BindingDataStore.getDataByName(BindingDataStore.java:50) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.broker.ParameterResolver.resolve(ParameterResolver.java:59) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.broker.ParameterResolver.resolve(ParameterResolver.java:42) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.broker.JavaMethodExecutor.execute(JavaMethodExecutor.java:52) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:51) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:33) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:45) [9/14/2019 11:48:34 AM] at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:92) [9/14/2019 11:48:34 AM] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [9/14/2019 11:48:34 AM] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [9/14/2019 11:48:34 AM] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [9/14/2019 11:48:34 AM] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [9/14/2019 11:48:34 AM] at java.lang.Thread.run(Thread.java:748) [9/14/2019 11:48:34 AM] Caused by: java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name: com.microsoft.azure.eventhubs.EventData [9/14/2019 11:48:34 AM] at com.google.gson.internal.UnsafeAllocator.assertInstantiable(UnsafeAllocator.java:117) [9/14/2019 11:48:34 AM] at com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:49) [9/14/2019 11:48:34 AM] at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:225) [9/14/2019 11:48:34 AM] ... 24 more

Thanks in advance

Siva TV

amamounelsayed commented 4 years ago

@siva007tv you can't access partionContext, if you would like to access the SystemProperties which contains public static class SystemProperty { public String SequenceNumber; public String Offset; public String PartitionKey;
public String EnqueuedTimeUtc; } Please follow this example: https://github.com/Azure/azure-functions-java-worker/blob/dev/endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/EventHubTriggerTests.java#L27

Please let us know if this solve your issue. Thank you!

scgbear commented 3 years ago

This solution isn't an equivalent workaround to replace the partition context that's provided for C#. Namely the partitionId isn't available.

amamounelsayed commented 3 years ago

Can you please elaborate what info you may need from partionContext? Thank you!

scgbear commented 3 years ago

PartitionId is what I'm specifically hunting for. Not the PartitionKey, but the PartitionId. When I attempted the above SystemProperty workaround my PartitionKey values are null. Which I would expect as I am not setting a PartitionKey on the messages. But I do want to know which of the 32 partitions I have in the event hub the message was processed from. We are using this understand how well the load is being distributed across the partitions and compared to the Azure Function App instances. Something we can do with C#, but don't have a way to do from Java.

scgbear commented 3 years ago

For example, with C# and the PartitionID on the partition context we can create charts like this from the log analytics data comparing the load distro:

image

Sarah-Aly commented 3 years ago

@amamounelsayed, any updates on accessing the partitionId ?