This documentation is not maintained. Please refer to doc.castsoftware.com/technologies to find the latest updates.

Extension ID

com.castsoftware.azure.java

What's new?

See Azure Java 1.0 - Release Notes.

In what situation should you install this extension?

This extension should be used for analyzing java source code using any of the supported Azure services. 

Azure Blob support

Click here to expand...

Whenever a call to a method carrying a CRUD operation on an Azure Blob is found in the source code, this extension evaluates the name of the container in which the operation is made and a link is created from the caller of the method to that blob container. The list of supported methods and the type of links created are listed in the following tables. If the evaluation of the container name fails (either due to missing information in the source code or to limitations in the evaluation) a link is created to an Unknown container.

For methods copying a blob from one container to another, a useSelectLink is created to the source container and both a useInsertLink and a useUpdateLink are created to the destination container.

Methods from Azure Storage Client library v. 12.x (com.azure.storage)

ClassesMethodslink_types
com.azure.storage.blob.BlobServiceClientdeleteBlobContainer, deleteBlobContainerWithResponseuseDeleteLink
As aboveundeleteBlobContainer, undeleteBlobContainerWithResponseuseUpdateLink
com.azure.storage.blob.BlobContainerClientdelete, deleteWithResponseuseDeleteLink

com.azure.storage.blob.specialized.BlobClientBase

com.azure.storage.blob.specialized.BlobAsyncClientBase

delete, deleteWithResponseuseDeleteLink

As above

download, downloadContent, downloadStream, downloadContentWithResponse, downloadStreamWithResponse, downloadToFile, downloadToFileWithResponse, downloadWithResponse, query, queryWithResponse

useSelectLink

As above

beginCopy, copyFromUrl, copyFromUrlWithResponseuseSelectLink, useInsertLink, useUpdateLink

com.azure.storage.blob.BlobClient

com.azure.storage.blob.BlobAsyncClient

upload, uploadFromFile, uploadFromFileWithResponse, uploadWithResponseuseInsertLink, useUpdateLink

com.azure.storage.blob.specialized.AppendBlobClient

com.azure.storage.blob.specialized.AppendBlobAsyncClient

appendBlock, appendBlockWithResponseuseUpdateLink

As above

appendBlockFromUrl, appendBlockFromUrlWithResponseuseSelectLink, useInsertLink, useUpdateLink

com.azure.storage.blob.specialized.BlockBlobClient

com.azure.storage.blob.specialized.BlockBlobAsyncClient

commitBlockList, commitBlockListWithResponseuseUpdateLink

As above

stageBlockuseInsertLink

As above

upload, uploadWithResponseuseInsertLink, useUpdateLink

As above

stageBlockFromUrl, stageBlockFromUrlWithResponse, uploadFromUrl, uploadFromUrlWithResponseuseSelectLink, useInsertLink, useUpdateLink

com.azure.storage.blob.specialized.PageBlobClient

com.azure.storage.blob.specialized.PageBlobAsyncClient

clearPages, clearPagesWithResponseuseDeleteLink

As above

uploadPages, uploadPagesWithResponseuseInsertLink, useUpdateLink

As above

copyIncremental, copyIncrementalWithResponse, uploadPagesFromUrl, uploadPagesFromUrlWithResponseuseSelectLink, useInsertLink, useUpdateLink
com.azure.storage.common.StorageOutputStreamwrite, dispatchWrite, writeInternaluseUpdateLink
com.azure.storage.common.BlobInputStreamreaduseSelectLink

Methods form Azure Storage Client library v. 11.x (com.microsoft.azure.storage)

Note that the Azure Storage Client library v. 11.x is deprecated.
ClassesMethodslink_types
com.microsoft.azure.storage.blob.CloudBlobContainerdelete, deleteIfExistsuseDelete
com.microsoft.azure.storage.blob.CloudBlobdelete, deleteIfExistsuseDelete
As abovedownload, downloadRange, downloadRangeInternal, downloadRangeToByteArray, downloadToByteArray, downloadToFileuseSelect
As aboveupload, uploadFromByteArray, uploadFromFileuseInsert, useUpdate
As abovestartCopy, startCopyImpluseSelect, useInsert, useUpdate
com.microsoft.azure.storage.blob.CloudAppendBlobappend, appendBlock, appendFromByteArray, appendFromFile, appendTextuseUpdate
As aboveuploaduseInsert, useUpdate
As aboveappendBlockFromURI, startCopyuseSelect, useInsert, useUpdate
com.microsoft.azure.storage.blob.CloudBlockBlobcommitBlockListuseUpdate
As abovedownloadBlockList, downloadTextuseSelect
As aboveupload, uploadBlock, uploadFromByteArray, uploadFullBlob, uploadTextuseInsert, useUpdate
As abovecreateBlockFromURI, startCopyuseSelect, useInsert, useUpdate
com.microsoft.azure.storage.blob.CloudPageBlobclearPagesuseDelete
As abovedownloadPageRangesuseSelect
As aboveupload, uploadFromByteArray, uploadFromFile, uploadPagesuseInsert, useUpdate
As aboveputPagesFromURI, startCopy, startIncrementalCopyuseSelect, useInsert, useUpdate
com.microsoft.azure.storage.blob.BlobInputStreamreaduseSelect
com.microsoft.azure.storage.blob.BlobOutputStreamwriteuseUpdate

Example

When analyzing the following source code:

import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.specialized.BlockBlobClient;

public class BasicExample {

    public static void main(String[] args) throws IOException {

        StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey);

        String endpoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net", accountName);

        BlobServiceClient storageClient = new BlobServiceClientBuilder().endpoint(endpoint).credential(credential).buildClient();

        BlobContainerClient blobContainerClient = storageClient.getBlobContainerClient("mycontainer");

        blobContainerClient.create();

        BlockBlobClient blobClient = blobContainerClient.getBlobClient("HelloWorld.txt").getBlockBlobClient();

        blobClient.upload(dataStream, data.length());
    }
}

we get the following result:

Azure Service Bus support

Click here to expand...

Whenever a call to a method carrying a sender/receiver operation on an Azure Service Bus queue/topic is found in the source code, this extension evaluates the name of the queue/topic in which the operation is made and a link is created from the caller of the method to that Service Bus Publisher/Receiver. If the evaluation of the Service Bus queue/topic name fails (either due to missing information in the source code or to limitations in the evaluation) a link is created to an Unknown Service Bus Publisher/Receiver.

This extension supports:

Supported APIs

com.azure.messaging.servicebus

For the publisher side:

Supported API methods (com.azure.messaging.servicebus)Object created (Callee)Link createdCaller type

ServiceBusSenderClient.sendMessage

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

ServiceBusSenderClient.sendMessages

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

ServiceBusSenderAsyncClient.sendMessage

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

ServiceBusSenderAsyncClient.sendMessages

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

For the receiver side:

Supported API methods (com.azure.messaging.servicebus)Object created (Caller)Link createdCallee type

ServiceBusReceiverClient.receiveMessages

Java Azure (Unknown) Service Bus ReceivercallLinkJava Method
ServiceBusProcessorClient.start

Java Azure (Unknown) Service Bus Receiver

callLinkJava Method

ServiceBusReceiverAsyncClient (reactor.core.publisher.Flux.subscribe)

ServiceBusSessionReceiverAsyncClient

Java Azure (Unknown) Service Bus Receiver

callLink

Java Lambda Expression /Java Method
(see also Limitation section below)

com.microsoft.azure.servicebus

For the publisher side:

Supported API methods (com.microsoft.azure.servicebus)Object created (Callee)Link createdCaller type

QueueClient.scheduleMessage

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

QueueClient.scheduleMessageAsync

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

QueueClient.send

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

QueueClient.sendAsync

Java Azure (Unknown) Service Bus PublishercallLinkJava Method
QueueClient.sendBatchJava Azure (Unknown) Service Bus PublishercallLinkJava Method
QueueClient.sendBatchAsyncJava Azure (Unknown) Service Bus PublishercallLinkJava Method
TopicClient.scheduleMessageJava Azure (Unknown) Service Bus PublishercallLinkJava Method
TopicClient.scheduleMessageAsyncJava Azure (Unknown) Service Bus PublishercallLinkJava Method
TopicClient.sendJava Azure (Unknown) Service Bus PublishercallLinkJava Method
TopicClient.sendAsyncJava Azure (Unknown) Service Bus PublishercallLinkJava Method
TopicClient.sendBatchJava Azure (Unknown) Service Bus PublishercallLinkJava Method
TopicClient.sendBatchAsyncJava Azure (Unknown) Service Bus PublishercallLinkJava Method

For the receiver side:

Supported API methods (com.microsoft.azure.servicebus)Object created (Caller)Link createdCallee type

QueueClient.registerMessageHandler

Java Azure (Unknown) Service Bus ReceivercallLinkJava Method
QueueClient.registerSessionHandlerJava Azure (Unknown) Service Bus ReceivercallLinkJava Method

SubscriptionClient.registerMessageHandler

Java Azure (Unknown) Service Bus ReceivercallLinkJava Method
SubscriptionClient.registerSessionHandlerJava Azure (Unknown) Service Bus ReceivercallLinkJava Method

Code samples

package com.foo.test;

import com.azure.messaging.servicebus.ServiceBusSenderClient;
import com.azure.messaging.servicebus.ServiceBusReceiverClient;
import com.azure.messaging.servicebus.ServiceBusClientBuilder;
import com.azure.messaging.servicebus.ServiceBusMessage;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.Arrays;
import java.util.List;

//
// https://docs.microsoft.com/fr-fr/azure/service-bus-messaging/service-bus-java-how-to-use-queues
//
public class SendReceive {
    
	static String connectionString = "<NAMESPACE CONNECTION STRING>";
	static String queueName = "<QUEUE NAME>";	
		
	static void sendMessage() {
		
		// create a Service Bus Sender client for the queue 
		ServiceBusSenderClient senderClient = new ServiceBusClientBuilder()
				.connectionString(connectionString)
				.sender()
				.queueName(queueName)				
				.buildClient();

		// send one message to the queue
		senderClient.sendMessage(new ServiceBusMessage("Hello, World!"));
		System.out.println("Sent a single message to the queue: " + queueName);
		
	}
	
	static void receiveMessages() {
		
		 ServiceBusReceiverClient receiverClient = new ServiceBusClientBuilder()
			     .connectionString(connectionString)
			     .receiver()
			     .queueName(queueName)
			     .buildClient();

			 // Use the receiver and finally close it.
		 receiverClient.receiveMessages(1);
		 receiverClient.close();
	}   
	
	public static void main(String[] args) throws InterruptedException {    	
    	sendMessage();		
		receiveMessages();
	} 
}

Azure Functions support

Click here to expand...

Azure Functions allow executing some source code on the cloud. The execution can be set to be triggered by some Azure events. In Java, the Azure Functions API are defined using annotations: com.microsoft.azure.functions.annotation:

Supported API methods (com.microsoft.azure.functions.annotation)Object created (Caller)Link createdCallee type

@FunctionName

Java Azure (Unknown) FunctioncallLinkJava Method

The analyzer will create a Java Azure Function object with a call link to the handler of the Azure Function.

@FunctionName("RetrieveDailySubscriptions")
public void retrieveDailySubscriptions(...

The Azure Function can be configured to be triggered or to interact with some other Azure services. Triggers cause a function to run. Binding to a function is a way of declaratively connecting another resource to the function; bindings may be connected as input bindings, output bindings, or both. Data from bindings is provided to the function as parameters. The following table list the supported interactions:

Service

trigger

input

output

Http(tick)--
Service Bus(tick)-(tick)
Blob(tick)(tick)(tick)
CosmosDB(tick)(tick)(tick)
Event Hubs(tick)-(tick)

Detailed support for each of these interactions is given in the following sections.

Support for binding with Azure Service Bus

Service Bus can be used as a trigger or as an output binding for Azure function. For the trigger, we create a Java Azure Service Bus Receiver object with a call link to Java Azure Function object. For output binding, the Java function sends a message to a Topic or a Queue. We create a Java Azure Service Bus Publisher object with a callLink to that object from the handler of function.

Supported API methods (com.microsoft.azure.functions.annotation)Object created (Caller)Link createdCallee type

@ServiceBusQueueTrigger

@ServiceBusTopicTrigger

Java Azure (Unknown) Service Bus ReceivercallLinkJava Azure Function
Supported API methods (com.microsoft.azure.functions.annotation)Object created (Callee)Link createdCaller type

@ServiceBusQueueOutput

@ServiceBusTopicOutput

Java Azure (Unknown) Service Bus PublishercallLinkJava Method

For example, when analyzing the following source code:

 	@FunctionName("RetrieveDailySubscriptions")
    public void retrieveDailySubscriptions(
        @TimerTrigger(
            name = "timer",
            schedule = "0 0 0 * * *") String timerInfo,       
        @ServiceBusQueueOutput(name = "sb",
            queueName = "%PaymentQueue%",
            connection = "ServiceBusConnectionStr") OutputBinding<Subscription[]> subscriptionOutput,
        final ExecutionContext context) {
        subscriptionOutput.setValue(subscriptions);
    }

 	@FunctionName("ProcessSubscriptionPayment")
    public void processSubscriptionPayment(
        @ServiceBusQueueTrigger(
            name = "sb",
            queueName = "%PaymentQueue%",
            connection = "ServiceBusConnectionStr") Subscription subscription,     
        final ExecutionContext context) {
      
    }

HttpTrigger

We create operations linked to the handler of function. If the type of operation is not specified, the function responds to all HTTP methods, we create Java Azure Any Operation. If the url is not specified, it is the function name:

Supported API methods (com.microsoft.azure.functions.annotation)Object created (Caller)Link createdCallee type

@HttpTrigger

Java Azure Get Operation

Java Azure Post Operation

Java Azure Put Operation

Java Azure Delete Operation

Java Azure Any Operation

callLinkJava Azure Function

For example, when analyzing the following source code:

    @FunctionName("ServiceBusTopicOutput")
    public void serviceBusTopicOutput(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
        @ServiceBusTopicOutput(name = "message", topicName = "%SBTopicName%", subscriptionName = "%SBTopicSubName%", connection = "AzureWebJobsServiceBus") OutputBinding<String> output,
        final ExecutionContext context
    ) {
        String message = request.getBody().orElse("default message");
        output.setValue(message);
        context.getLogger().info("Java Service Bus Topic output function got a message: " + message);
    }

you will get the following result:

Durable functions

Durable Functions allow calling an azure function from another Azure Function:

Supported API methods (com.microsoft.durabletask)

Object created (Callee)Link createdCaller

DurableTaskClient.scheduleNewOrchestrationInstance

TaskOrchestrationContext.callSubOrchestrator

TaskOrchestrationContext.callActivity

Java Call to Azure (Unknown) FunctioncallLinkJV Method

The extension com.castsoftware.wbslinker will match Java Call to Azure Function objects to Azure Function objects such as Java Azure Function. For example, when analyzing the following source code:

	@FunctionName("StartHelloCities")
    public HttpResponseMessage startHelloCities(
            @HttpTrigger(name = "req", methods = {HttpMethod.POST}) HttpRequestMessage<Optional<String>> req,
            @DurableClientInput(name = "durableContext", taskHub = "%MyTaskHub%") DurableClientContext durableContext,
            final ExecutionContext context) {

        DurableTaskClient client = durableContext.getClient();
        String instanceId = client.scheduleNewOrchestrationInstance("HelloCities");
        context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
        return durableContext.createCheckStatusResponse(req, instanceId);
    }

    /**
     * This is the orchestrator function, which can schedule activity functions, create durable timers,
     * or wait for external events in a way that's completely fault-tolerant. The OrchestrationRunner.loadAndRun()
     * static method is used to take the function input and execute the orchestrator logic.
     */
    @FunctionName("HelloCities")
    public String helloCitiesOrchestrator(@DurableOrchestrationTrigger(name = "runtimeState") String runtimeState) {
        return OrchestrationRunner.loadAndRun(runtimeState, ctx -> {
            String result = "";
            result += ctx.callActivity("SayHello", "Tokyo", String.class).await() + ", ";
            result += ctx.callActivity("SayHello", "London", String.class).await() + ", ";
            result += ctx.callActivity("SayHello", "Seattle", String.class).await();
            return result;
        });
    }

    /**
     * This is the activity function that gets invoked by the orchestrator function.
     */
    @FunctionName("SayHello")
    public String sayHello(@DurableActivityTrigger(name = "name") String name) {
        return String.format("Hello %s!", name);
    }

you will get the following result:

Durable function client with HTTP trigger

It is common that a durable function client is triggered by an HTTP call and that with a proper URL any orchestrator function can be triggered. In this case, for each existing orchestrator azure function, an Operation with the corresponding url is created with a callLink to a Call to Azure Function object to the orchestrator function. For example when analyzing the following code:

	@FunctionName("HttpStart")
	public HttpResponseMessage httpStart(
	        @HttpTrigger(name = "req", route = "orchestrators/{functionName}") HttpRequestMessage<?> req,
	        @DurableClientInput(name = "durableContext") DurableClientContext durableContext,
	        @BindingName("functionName") String functionName,
	        final ExecutionContext context) {

	    DurableTaskClient client = durableContext.getClient();
	    String instanceId = client.scheduleNewOrchestrationInstance(functionName);
	    context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
	    return durableContext.createCheckStatusResponse(req, instanceId);
	}

if your source code contains two orchestrator azure functions named HelloCities and HelloCities2, you will get the following result:

Binding with Azure Blob

Supported API methods (com.microsoft.azure.functions.annotation)Link createdCaller typeCallee type

@BlobTrigger 

callLinkJava MethodJava Azure function
@BlobInputuseSelectLinkJava MethodJava Azure Blob Container
@BlobOutputuseUpdateLink Java MethodJava Azure Blob Container

Blob trigger - @BlobTrigger 

Whenever a file is added or updated to a blob container the azure function will be executed. We add the property 'CAST_Azure_Function.blob_triggers' to the Java Azure function. The extension com.castsoftware.wbslinker will create a callLink from the method (which added or updated to the blob) to the Java Azure function. For example, when analyzing the following source code,

	@FunctionName("blobprocessor")
	public void run(
	  @BlobTrigger(name = "file",
	               dataType = "binary",
	               path = "myblob/{name}",
	               connection = "MyStorageAccountAppSetting") byte[] content,
	  @BindingName("name") String filename,
	  final ExecutionContext context
	) {
	  context.getLogger().info("Name: " + filename + " Size: " + content.length + " bytes");
	}

you will get the following result:

Input Binding - @BlobInput

This is used to get access to a blob. From a Java Method, we create a useSelectLink to the blob object.  For example, when analyzing the following source code:

      @FunctionName("getBlobSizeHttp")
	  @StorageAccount("Storage_Account_Connection_String")
	  public HttpResponseMessage blobSize(	    
	    @BlobInput(
	      name = "file", 
	      dataType = "binary", 
	      path = "samples-workitems/{Query.file}") 
	    byte[] content,
	    final ExecutionContext context) {
	      
	  }

you will get the following result:

Output Binding - @BlobOutput

This is used to update a blob. From a Java Method, we create a useUpdateLink to the blob object. For example, when analyzing the following source code:

	  @FunctionName("copyBlobHttp")
	  @StorageAccount("Storage_Account_Connection_String")
	  public HttpResponseMessage copyBlobHttp(	 
	    @BlobOutput(
	      name = "target", 
	      path = "myblob/{Query.file}-CopyViaHttp")
	    OutputBinding<String> outputItem,
	    final ExecutionContext context) {
	    
	  }

you will get the following result:

Binding with CosmosDB

Supported for Java from function 2.x and higher:

Supported API methods (com.microsoft.azure.functions.annotation)Link createdCaller typeCallee type

@CosmosDBTrigger 

callLinkJava MethodJava Azure function
@CosmosDBInputuseSelectLinkJava MethodJava CosmosDB Collection
@CosmosDBOutputuseUpdateLink Java MethodJava CosmosDB Collection

CosmosDB trigger - @CosmosDBTrigger

An Azure Function is invoked when there are inserts or updates in the specified database and collection. We add the property 'CAST_Azure_Function.cosmosDB_triggers' to the azure function. The extension com.castsoftware.wbslinker will create a callLink from the JV method (which added or updated to the cosmosDB) to the azure function. For example, when analyzing the following source code:

	@FunctionName("CosmosTriggerAndOutput")
    public void CosmosTriggerAndOutput(
        @CosmosDBTrigger(name = "itemIn", databaseName = "familydb", collectionName = "familycoll", leaseCollectionName = "leases", connectionStringSetting = "AzureWebJobsCosmosDBConnectionString", createLeaseCollectionIfNotExists = true) Object inputItem,       
        final ExecutionContext context) {

        context.getLogger().info("Java Cosmos DB trigger function executed. Received document: " + inputItem);
      
    }

you will get the following result:

Input Binding - @CosmosDBInput

This is used to get access to CosmosDB database and collection. From a Java Method (which is the handler of the azure function), we create a useSelectLink to the CosmosDB collection object. For example, when analyzing the following source code:

	@FunctionName("CosmosDBInputId")
    public HttpResponseMessage CosmosDBInputId(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
        HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
                                               @CosmosDBInput(name = "item", databaseName = "familydb", collectionName = "familycoll", connectionStringSetting = "AzureWebJobsCosmosDBConnectionString", id = "{docId}") String item,
                                               final ExecutionContext context) {

        context.getLogger().info("Java HTTP trigger processed a request.");

        if (item != null) {
            return request.createResponseBuilder(HttpStatus.OK).body("Received Document" + item).build();
        } else {
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("Did not find expected item in ItemsCollectionIn").build();
    	}
   } 

you will get the following result:

Output Binding - @CosmosDBOutput

This is used to update a CosmosDB database and collection. From a Java Method (which is the handle of the azure function), we create a useUpdateLink to the CosmosDB collection object. For example, when analyzing the following source code:

	@FunctionName("CosmosDBInputQueryPOJOArray")
    public HttpResponseMessage CosmosDBInputQueryPOJOArray(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
        HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,                                                        
                                                           @CosmosDBOutput(name = "itemsOut", databaseName = "%CosmosDBDatabaseName%", collectionName = "familycoll", connectionStringSetting = "AzureWebJobsCosmosDBConnectionString") OutputBinding<Document[]> itemsOut,
                                                           final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

       
    }

you will get the following result:

Support Azure Event Hubs Trigger and Binding Output

Event Hubs can be used as a trigger or as an output binding for Azure function. For the trigger, we create a Java Azure Event Hub Receiver object with a call link to Java Azure function object. For output binding, the Java function sends events to a Event Hub. We create a Java Azure Event Hub Publisher object with a callLink to that object from the handler of function.

Supported API methods (com.microsoft.azure.functions.annotation)

Object created (Caller)

Link created

Callee type

@EventHubTrigger

Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Azure function

Supported API methods (com.microsoft.azure.functions.annotation)

Object created (Callee)

Link created

Caller type

@EventHubOutput

Java Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method

For example, when analyzing the following source code:

	@FunctionName("EventHubReceiver")
    @StorageAccount("bloboutput")
    public void run(
            @EventHubTrigger(name = "message",
                eventHubName = "%eventhub%",
                consumerGroup = "%consumergroup%",
                connection = "eventhubconnection",
                cardinality = Cardinality.ONE)
            String message,

            final ExecutionContext context,

            @BindingName("Properties") Map<String, Object> properties,
            @BindingName("SystemProperties") Map<String, Object> systemProperties,
            @BindingName("PartitionContext") Map<String, Object> partitionContext,
            @BindingName("EnqueuedTimeUtc") Object enqueuedTimeUtc,

            @BlobOutput(
                name = "outputItem",
                path = "iotevents/{datetime:yy}/{datetime:MM}/{datetime:dd}/{datetime:HH}/" +
                       "{datetime:mm}/{PartitionContext.PartitionId}/{SystemProperties.SequenceNumber}.json")
            OutputBinding<String> outputItem) {

        var et = ZonedDateTime.parse(enqueuedTimeUtc + "Z"); // needed as the UTC time presented does not have a TZ
                                                             // indicator
        context.getLogger().info("Event hub message received: " + message + ", properties: " + properties);
        context.getLogger().info("Properties: " + properties);
        context.getLogger().info("System Properties: " + systemProperties);
        context.getLogger().info("partitionContext: " + partitionContext);
        context.getLogger().info("EnqueuedTimeUtc: " + et);

        outputItem.setValue(message);
    }
    
    @FunctionName("sendTime")
    @EventHubOutput(name = "event", eventHubName = "samples-workitems", connection = "AzureEventHubConnection")
    public String sendTime(
       @TimerTrigger(name = "sendTimeTrigger", schedule = "0 */5 * * * *") String timerInfo)  {
         return LocalDateTime.now().toString();
    }

you will get the following result:

Azure Event Hubs support

Click here to expand...

Whenever a call to a method carrying a sender/receiver operation on an Azure Event Hubs is found in the source code, this extension evaluates the name of the Event Hub in which the operation is made and a link is created from the caller of the method to that Event Hub Publisher/Receiver. If the evaluation of the Event Hub name fails (either due to missing information in the source code or to limitations in the evaluation) a link is created to an Unknown Event Hub Publisher/Receiver.

This extension supports:

Supported send/receive Events APIs

com.azure.messaging.eventhubs (latest)

For the publisher side (Send Events):

Supported API methods (com.azure.messaging.eventhubs)Object created (Callee)Link createdCaller type

EventHubProducerClient.send

Java Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method

EventHubProducerAsyncClient.send

Java Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method

For the receiver side (Receive Events):

Supported API methods (com.azure.messaging.eventhubs)Object created (Caller)Link createdCallee type

EventHubConsumerClient.receiveFromPartition

Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method

EventHubConsumerAsyncClient.receiveFromPartition

Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method

EventHubConsumerAsyncClient.receive

Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method
EventProcessorClient.start Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method

com.microsoft.azure.eventprocessorhost (legacy)

For the publisher side (Send Events):

Supported API methods (com.microsoft.azure.eventhubs)Object created (Callee)Link createdCaller type

EventHubClient.send

Java Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method
EventHubClient.sendsyncJava Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method
PartitionSender.sendJava Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method

PartitionSender.sendsync

Java Azure Event Hub Publisher / Java Azure Unknown Event Hub PublishercallLinkJava Method

For the receiver side (Receive Events):

Supported API methods (com.microsoft.azure.eventhubs)Object created (Caller)Link createdCallee type

PartitionReceiver.receive

Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method
PartitionReceiver.receiveSyncJava Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method
Supported API methods (com.microsoft.azure.eventprocessorhost)Object created (Caller)Link createdCallee type

EventProcessorHost.registerEventProcessor 

Java Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method
EventProcessorHost.registerEventProcessorFactoryJava Azure Event Hub Receiver / Java Azure Unknown Event Hub ReceivercallLinkJava Method

The extension com.castsoftware.wbslinker will match Azure Event Hub Publisher objects to Azure Event Hub Receiver.

Checkpoint Store

We support Azure Event Hubs Checkpoint Store using Storage Blobs

Supported API methods (com.azure.messaging.eventhubs)Link createdCaller typeCallee type

EventProcessorClientBuilder.checkpointStore

useUpdateLinkJava MethodJava Azure Blob Container
Supported API methods (com.microsoft.azure.eventprocessorhost)Link createdCaller typeCallee type

EventProcessorHost.EventProcessorHostBuilder.useAzureStorageCheckpointLeaseManager

useUpdateLinkJava MethodJava Azure Blob Container

From a Java Method, we create a useUpdateLink to the blob container object. For example, when analyzing the following source code:

public class Sender {
    private static final String connectionString = "<Event Hubs namespace connection string>";
    private static final String eventHubName = "<Event hub name>";

    public static void main(String[] args) {
        publishEvents();
    }
    
    /**
     * Code sample for publishing events.
     * @throws IllegalArgumentException if the EventData is bigger than the max batch size.
     */
    public static void publishEvents() {
        // create a producer client
        EventHubProducerClient producer = new EventHubClientBuilder()
            .connectionString(connectionString, eventHubName)
            .buildProducerClient();

        // sample events in an array
        List<EventData> allEvents = Arrays.asList(new EventData("Foo"), new EventData("Bar"));

        // create a batch
        EventDataBatch eventDataBatch = producer.createBatch();

        for (EventData eventData : allEvents) {
            // try to add the event from the array to the batch
            if (!eventDataBatch.tryAdd(eventData)) {
                // if the batch is full, send it and then create a new batch
                producer.send(eventDataBatch);
                eventDataBatch = producer.createBatch();

                // Try to add that event that couldn't fit before.
                if (!eventDataBatch.tryAdd(eventData)) {
                    throw new IllegalArgumentException("Event is too large for an empty batch. Max size: "
                        + eventDataBatch.getMaxSizeInBytes());
                }
            }
        }
        // send the last batch of remaining events
        if (eventDataBatch.getCount() > 0) {
            producer.send(eventDataBatch);
        }
        producer.close();
    }
}

and:

public class Receiver {
	private static final String connectionString = "<Event Hubs namespace connection string>";
	private static final String eventHubName = "<Event hub name>";
	private static final String storageConnectionString = "<Storage connection string>";
	private static final String storageContainerName = "<Storage container name>";
	
	public static void main(String[] args) throws Exception {
	    // Create a blob container client that you use later to build an event processor client to receive and process events
	    BlobContainerAsyncClient blobContainerAsyncClient = new BlobContainerClientBuilder()
	        .connectionString(storageConnectionString)
	        .containerName(storageContainerName)
	        .buildAsyncClient();

	    // Create a builder object that you will use later to build an event processor client to receive and process events and errors.
	    EventProcessorClientBuilder eventProcessorClientBuilder = new EventProcessorClientBuilder()
	        .connectionString(connectionString, eventHubName)
	        .consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME)
	        .processEvent(PARTITION_PROCESSOR)
	        .processError(ERROR_HANDLER)
	        .checkpointStore(new BlobCheckpointStore(blobContainerAsyncClient));

	    // Use the builder object to create an event processor client
	    EventProcessorClient eventProcessorClient = eventProcessorClientBuilder.buildEventProcessorClient();

	    System.out.println("Starting event processor");
	    eventProcessorClient.start();

	    System.out.println("Press enter to stop.");
	    System.in.read();

	    System.out.println("Stopping event processor");
	    eventProcessorClient.stop();
	    System.out.println("Event processor stopped.");

	    System.out.println("Exiting process");
	}
	
	public static final Consumer<EventContext> PARTITION_PROCESSOR = eventContext -> {
	    PartitionContext partitionContext = eventContext.getPartitionContext();
	    EventData eventData = eventContext.getEventData();

	    System.out.printf("Processing event from partition %s with sequence number %d with body: %s%n",
	        partitionContext.getPartitionId(), eventData.getSequenceNumber(), eventData.getBodyAsString());

	    // Every 10 events received, it will update the checkpoint stored in Azure Blob Storage.
	    if (eventData.getSequenceNumber() % 10 == 0) {
	        eventContext.updateCheckpoint();
	    }
	};

	public static final Consumer<ErrorContext> ERROR_HANDLER = errorContext -> {
	    System.out.printf("Error occurred in partition processor for partition %s, %s.%n",
	        errorContext.getPartitionContext().getPartitionId(),
	        errorContext.getThrowable());
	};
}

you will get the following result:

Azure SignalR service support

Click here to expand...

Client side

Call methods that run on the server. When there is an API method which invokes a hub method, we create a Java Azure SignalR Call to Hub Method object where the object name is the name of invoked hub method. Add a property hub_Name to save the hub name which is connected by this client.

Supported API methods (com.microsoft.signalr)Object createdLink createdCaller type

HubConnection.send

HubConnection.start

HubConnection.stop

Java Azure SignalR Call to Hub Method / Java Azure SignalR Call to Unknown Hub Method

callLink

Java Method

The extension com.castsoftware.wbslinker will match Java Azure SignalR Call to Hub Method objects to DotNet Azure SignalR Hub Method in server side (which created by Azure Dotnet extension). For example, when analyzing the following source code in client side:

	public static void main(String[] args) throws Exception {	
		HubConnection hubConnection = HubConnectionBuilder.create("/chatHub")
                .build();       
		...
        //This is a blocking call
        hubConnection.start().blockingAwait();

        while (!input.equals("leave")){
            input = reader.nextLine();
            hubConnection.send("SendMessage", input);
        }
		
		hubConnection.stop();
	}

and if your source code contains a corresponding signalR Hub class, you will get the following result:

Objects

The following objects are resolved:

IconDescription

Java Azure Blob Container

Java Azure Unknown Blob Container

Java Azure Service Bus Publisher

Java Azure Service Bus Receiver

Java Azure Unknown Service Bus Publisher

Java Azure Unknown Service Bus Receiver

Java Azure Function

Java Azure Unknown Function

Java Call to Azure Function

Java Call to Azure Unknown Function

Java Azure Get Operation

Java Azure Post Operation

Java Azure Put Operation

Java Azure Delete Operation

Java Azure Any Operation

Java Azure Event Hub Publisher

Java Azure Event Hub Receiver

Java Azure Unknown Event Hub Publisher

Java Azure Unknown Event Hub Receiver

Java Azure SignalR Call to Hub Method

Java Azure SignalR Call to Unknown Hub Method

Known limitations

  • In Service Bus support, for the support of com.azure.messaging.servicebus.ServiceBusReceiverAsyncClient (reactor.core.publisher.Flux.subscribe), if the first parameter of method reactor.core.publisher.Flux.subscribe is a method reference (utilize the  ::operator), the callLink do not point to this method reference but its parent.