diff --git a/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml b/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml index 1bfad853d7e96..6d3c98cbed17a 100755 --- a/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml +++ b/eng/code-quality-reports/src/main/resources/checkstyle/checkstyle-suppressions.xml @@ -33,11 +33,21 @@ + + + + - + + + + + + + diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/AzureStorageCheckpointLeaseManager.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/AzureStorageCheckpointLeaseManager.java index 8adcf3a2b898e..a4938c1a88d62 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/AzureStorageCheckpointLeaseManager.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/AzureStorageCheckpointLeaseManager.java @@ -4,8 +4,22 @@ package com.microsoft.azure.eventprocessorhost; import com.google.gson.Gson; -import com.microsoft.azure.storage.*; -import com.microsoft.azure.storage.blob.*; +import com.microsoft.azure.storage.AccessCondition; +import com.microsoft.azure.storage.CloudStorageAccount; +import com.microsoft.azure.storage.StorageErrorCodeStrings; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.StorageExtendedErrorInformation; +import com.microsoft.azure.storage.blob.BlobListingDetails; +import com.microsoft.azure.storage.blob.BlobProperties; +import com.microsoft.azure.storage.blob.BlobRequestOptions; +import com.microsoft.azure.storage.blob.CloudBlob; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.blob.CloudBlobContainer; +import com.microsoft.azure.storage.blob.CloudBlobDirectory; +import com.microsoft.azure.storage.blob.CloudBlockBlob; +import com.microsoft.azure.storage.blob.DeleteSnapshotsOption; +import com.microsoft.azure.storage.blob.LeaseState; +import com.microsoft.azure.storage.blob.ListBlobItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,7 +34,8 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -79,11 +94,11 @@ void initialize(HostContext hostContext) throws InvalidKeyException, URISyntaxEx Pattern p = Pattern.compile("^(?-i)(?:[a-z0-9]|(?<=[0-9a-z])-(?=[0-9a-z])){3,63}$"); Matcher m = p.matcher(this.storageContainerName); if (!m.find()) { - throw new IllegalArgumentException("EventHub names must conform to the following rules to be able to use it with EventProcessorHost: " + - "Must start with a letter or number, and can contain only letters, numbers, and the dash (-) character. " + - "Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in container names. " + - "All letters in a container name must be lowercase. " + - "Must be from 3 to 63 characters long."); + throw new IllegalArgumentException("EventHub names must conform to the following rules to be able to use it with EventProcessorHost: " + + "Must start with a letter or number, and can contain only letters, numbers, and the dash (-) character. " + + "Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in container names. " + + "All letters in a container name must be lowercase. " + + "Must be from 3 to 63 characters long."); } this.storageClient = CloudStorageAccount.parse(this.storageConnectionString).createCloudBlobClient(); @@ -107,8 +122,8 @@ void initialize(HostContext hostContext) throws InvalidKeyException, URISyntaxEx @Override public CompletableFuture checkpointStoreExists() { - return storeExistsInternal(this.checkpointOperationOptions, EventProcessorHostActionStrings.CHECKING_CHECKPOINT_STORE, - "Failure while checking checkpoint store existence"); + return storeExistsInternal(this.checkpointOperationOptions, EventProcessorHostActionStrings.CHECKING_CHECKPOINT_STORE, + "Failure while checking checkpoint store existence"); } @@ -119,9 +134,9 @@ public CompletableFuture checkpointStoreExists() { @Override public CompletableFuture createCheckpointStoreIfNotExists() { - // Because we control the caller, we know that this method will only be called after createLeaseStoreIfNotExists. - // In this implementation, it's the same store, so the store will always exist if execution reaches here. - return CompletableFuture.completedFuture(null); + // Because we control the caller, we know that this method will only be called after createLeaseStoreIfNotExists. + // In this implementation, it's the same store, so the store will always exist if execution reaches here. + return CompletableFuture.completedFuture(null); } @Override @@ -131,8 +146,8 @@ public CompletableFuture deleteCheckpointStore() { @Override public CompletableFuture getCheckpoint(String partitionId) { - CompletableFuture future = null; - + CompletableFuture future = null; + try { AzureBlobLease lease = getLeaseInternal(partitionId, this.checkpointOperationOptions); Checkpoint checkpoint = null; @@ -146,18 +161,18 @@ public CompletableFuture getCheckpoint(String partitionId) { } future = CompletableFuture.completedFuture(checkpoint); } catch (URISyntaxException | IOException | StorageException e) { - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.GETTING_CHECKPOINT)); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.GETTING_CHECKPOINT)); } - + return future; } @Override public CompletableFuture createAllCheckpointsIfNotExists(List partitionIds) { - // Because we control the caller, we know that this method will only be called after createAllLeasesIfNotExists. - // In this implementation checkpoints are in the same blobs as leases, so the blobs will already exist if execution reaches here. - return CompletableFuture.completedFuture(null); + // Because we control the caller, we know that this method will only be called after createAllLeasesIfNotExists. + // In this implementation checkpoints are in the same blobs as leases, so the blobs will already exist if execution reaches here. + return CompletableFuture.completedFuture(null); } @Override @@ -168,23 +183,23 @@ public CompletableFuture updateCheckpoint(CompleteLease lease, Checkpoint updatedLease.setOffset(checkpoint.getOffset()); updatedLease.setSequenceNumber(checkpoint.getSequenceNumber()); - CompletableFuture future = null; - - try { - if (updateLeaseInternal(updatedLease, this.checkpointOperationOptions)) { - future = CompletableFuture.completedFuture(null); - } else { + CompletableFuture future = null; + + try { + if (updateLeaseInternal(updatedLease, this.checkpointOperationOptions)) { + future = CompletableFuture.completedFuture(null); + } else { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(lease, "Lease lost")); future = new CompletableFuture(); future.completeExceptionally(LoggingUtils.wrapException(new RuntimeException("Lease lost while updating checkpoint"), - EventProcessorHostActionStrings.UPDATING_CHECKPOINT)); - } - } catch (StorageException | IOException e) { + EventProcessorHostActionStrings.UPDATING_CHECKPOINT)); + } + } catch (StorageException | IOException e) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(lease, "Failure updating checkpoint"), e); future = new CompletableFuture(); future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.UPDATING_CHECKPOINT)); - } - + } + return future; } @@ -206,37 +221,37 @@ public int getLeaseDurationInMilliseconds() { @Override public CompletableFuture leaseStoreExists() { - return storeExistsInternal(this.leaseOperationOptions, EventProcessorHostActionStrings.CHECKING_LEASE_STORE, - "Failure while checking lease store existence"); + return storeExistsInternal(this.leaseOperationOptions, EventProcessorHostActionStrings.CHECKING_LEASE_STORE, + "Failure while checking lease store existence"); } private CompletableFuture storeExistsInternal(BlobRequestOptions options, String action, String trace) { - CompletableFuture future = null; + CompletableFuture future = null; try { - future = CompletableFuture.completedFuture(this.eventHubContainer.exists(null, options, null)); + future = CompletableFuture.completedFuture(this.eventHubContainer.exists(null, options, null)); } catch (StorageException e) { TRACE_LOGGER.error(this.hostContext.withHost(trace), e); - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(e, action)); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(e, action)); } return future; } @Override public CompletableFuture createLeaseStoreIfNotExists() { - CompletableFuture future = null; - + CompletableFuture future = null; + try { // returns true if the container was created, false if it already existed -- we don't care this.eventHubContainer.createIfNotExists(this.leaseOperationOptions, null); TRACE_LOGGER.info(this.hostContext.withHost("Created lease store OK or it already existed")); future = CompletableFuture.completedFuture(null); } catch (StorageException e) { - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.CREATING_LEASE_STORE)); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.CREATING_LEASE_STORE)); TRACE_LOGGER.error(this.hostContext.withHost("Failure while creating lease store"), e); } - + return future; } @@ -246,30 +261,29 @@ public CompletableFuture deleteLeaseStore() { } private CompletableFuture deleteStoreInternal(BlobRequestOptions options) { - CompletableFuture future = null; - - try { - for (ListBlobItem blob : this.eventHubContainer.listBlobs(null, false, EnumSet.noneOf(BlobListingDetails.class), options, null)) { - if (blob instanceof CloudBlobDirectory) { + CompletableFuture future = null; + + try { + for (ListBlobItem blob : this.eventHubContainer.listBlobs(null, false, EnumSet.noneOf(BlobListingDetails.class), options, null)) { + if (blob instanceof CloudBlobDirectory) { for (ListBlobItem subBlob : ((CloudBlobDirectory) blob).listBlobs(null, false, EnumSet.noneOf(BlobListingDetails.class), options, null)) { ((CloudBlockBlob) subBlob).deleteIfExists(DeleteSnapshotsOption.NONE, null, options, null); } - } else if (blob instanceof CloudBlockBlob) { + } else if (blob instanceof CloudBlockBlob) { ((CloudBlockBlob) blob).deleteIfExists(DeleteSnapshotsOption.NONE, null, options, null); - } - } - + } + } + this.eventHubContainer.deleteIfExists(null, options, null); - + future = CompletableFuture.completedFuture(null); - } - catch (StorageException | URISyntaxException e) { + } catch (StorageException | URISyntaxException e) { TRACE_LOGGER.error(this.hostContext.withHost("Failure while deleting lease store"), e); - future = new CompletableFuture(); - future.completeExceptionally(new CompletionException(e)); - } - - return future; + future = new CompletableFuture(); + future.completeExceptionally(new CompletionException(e)); + } + + return future; } @Override @@ -277,7 +291,7 @@ public CompletableFuture getLease(String partitionId) { CompletableFuture future = null; try { - future = CompletableFuture.completedFuture(getLeaseInternal(partitionId, this.leaseOperationOptions)); + future = CompletableFuture.completedFuture(getLeaseInternal(partitionId, this.leaseOperationOptions)); } catch (URISyntaxException | IOException | StorageException e) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(partitionId, "Failure while getting lease details"), e); future = new CompletableFuture(); @@ -297,31 +311,31 @@ private AzureBlobLease getLeaseInternal(String partitionId, BlobRequestOptions o return retval; } - + @Override public CompletableFuture> getAllLeases() { - CompletableFuture> future = null; - - try { - ArrayList infos = new ArrayList(); - EnumSet details = EnumSet.of(BlobListingDetails.METADATA); - Iterable leaseBlobs = this.consumerGroupDirectory.listBlobs("", true, details, this.leaseOperationOptions, null); - leaseBlobs.forEach((lbi) -> { - CloudBlob blob = (CloudBlob)lbi; - BlobProperties bp = blob.getProperties(); - HashMap metadata = blob.getMetadata(); - Path p = Paths.get(lbi.getUri().getPath()); - infos.add(new BaseLease(p.getFileName().toString(), metadata.get(AzureStorageCheckpointLeaseManager.METADATA_OWNER_NAME), - (bp.getLeaseState() == LeaseState.LEASED))); - }); - future = CompletableFuture.completedFuture(infos); - } catch (URISyntaxException | StorageException e) { + CompletableFuture> future = null; + + try { + ArrayList infos = new ArrayList(); + EnumSet details = EnumSet.of(BlobListingDetails.METADATA); + Iterable leaseBlobs = this.consumerGroupDirectory.listBlobs("", true, details, this.leaseOperationOptions, null); + leaseBlobs.forEach((lbi) -> { + CloudBlob blob = (CloudBlob) lbi; + BlobProperties bp = blob.getProperties(); + HashMap metadata = blob.getMetadata(); + Path p = Paths.get(lbi.getUri().getPath()); + infos.add(new BaseLease(p.getFileName().toString(), metadata.get(AzureStorageCheckpointLeaseManager.METADATA_OWNER_NAME), + (bp.getLeaseState() == LeaseState.LEASED))); + }); + future = CompletableFuture.completedFuture(infos); + } catch (URISyntaxException | StorageException e) { TRACE_LOGGER.warn(this.hostContext.withHost("Failure while getting lease state details"), e); future = new CompletableFuture>(); future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.GETTING_LEASE)); - } - - return future; + } + + return future; } // NOTE NOTE NOTE: this is the one place where this lease manager implementation returns an uncompleted future. @@ -329,56 +343,56 @@ public CompletableFuture> getAllLeases() { // Because it happens during startup, when no user code is running, it cannot deadlock with checkpointing. @Override public CompletableFuture createAllLeasesIfNotExists(List partitionIds) { - CompletableFuture future = null; - - // Optimization: list the blobs currently existing in the directory. If there are the - // expected number of blobs, then we can skip doing the creates. - int blobCount = 0; - try { - Iterable leaseBlobs = this.consumerGroupDirectory.listBlobs("", true, null, this.leaseOperationOptions, null); - Iterator blobIterator = leaseBlobs.iterator(); - while (blobIterator.hasNext()) { - blobCount++; - blobIterator.next(); - } - } catch (URISyntaxException | StorageException e) { - TRACE_LOGGER.error(this.hostContext.withHost("Exception checking lease existence - leaseContainerName: " + this.storageContainerName + " consumerGroupName: " + - this.hostContext.getConsumerGroupName() + " storageBlobPrefix: " + this.storageBlobPrefix), e); - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.CREATING_LEASES)); - } - - if (future == null) { - // No error checking the list, so keep going - if (blobCount == partitionIds.size()) { - // All expected blobs found, so short-circuit - future = CompletableFuture.completedFuture(null); - } else { - // Create the blobs in parallel - ArrayList> createFutures = new ArrayList>(); - - for (String id : partitionIds) { - CompletableFuture oneCreate = CompletableFuture.supplyAsync(() -> { - CompleteLease returnLease = null; - try { - returnLease = createLeaseIfNotExistsInternal(id, this.leaseOperationOptions); - } catch (URISyntaxException | IOException | StorageException e) { - TRACE_LOGGER.error(this.hostContext.withHostAndPartition(id, - "Exception creating lease - leaseContainerName: " + this.storageContainerName + " consumerGroupName: " + this.hostContext.getConsumerGroupName() + - " storageBlobPrefix: " + this.storageBlobPrefix), e); - throw LoggingUtils.wrapException(e, EventProcessorHostActionStrings.CREATING_LEASES); - } - return returnLease; - }, this.hostContext.getExecutor()); - createFutures.add(oneCreate); - } - - CompletableFuture dummy[] = new CompletableFuture[createFutures.size()]; - future = CompletableFuture.allOf(createFutures.toArray(dummy)); - } - } - - return future; + CompletableFuture future = null; + + // Optimization: list the blobs currently existing in the directory. If there are the + // expected number of blobs, then we can skip doing the creates. + int blobCount = 0; + try { + Iterable leaseBlobs = this.consumerGroupDirectory.listBlobs("", true, null, this.leaseOperationOptions, null); + Iterator blobIterator = leaseBlobs.iterator(); + while (blobIterator.hasNext()) { + blobCount++; + blobIterator.next(); + } + } catch (URISyntaxException | StorageException e) { + TRACE_LOGGER.error(this.hostContext.withHost("Exception checking lease existence - leaseContainerName: " + this.storageContainerName + " consumerGroupName: " + + this.hostContext.getConsumerGroupName() + " storageBlobPrefix: " + this.storageBlobPrefix), e); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.CREATING_LEASES)); + } + + if (future == null) { + // No error checking the list, so keep going + if (blobCount == partitionIds.size()) { + // All expected blobs found, so short-circuit + future = CompletableFuture.completedFuture(null); + } else { + // Create the blobs in parallel + ArrayList> createFutures = new ArrayList>(); + + for (String id : partitionIds) { + CompletableFuture oneCreate = CompletableFuture.supplyAsync(() -> { + CompleteLease returnLease = null; + try { + returnLease = createLeaseIfNotExistsInternal(id, this.leaseOperationOptions); + } catch (URISyntaxException | IOException | StorageException e) { + TRACE_LOGGER.error(this.hostContext.withHostAndPartition(id, + "Exception creating lease - leaseContainerName: " + this.storageContainerName + " consumerGroupName: " + this.hostContext.getConsumerGroupName() + + " storageBlobPrefix: " + this.storageBlobPrefix), e); + throw LoggingUtils.wrapException(e, EventProcessorHostActionStrings.CREATING_LEASES); + } + return returnLease; + }, this.hostContext.getExecutor()); + createFutures.add(oneCreate); + } + + CompletableFuture[] dummy = new CompletableFuture[createFutures.size()]; + future = CompletableFuture.allOf(createFutures.toArray(dummy)); + } + } + + return future; } private AzureBlobLease createLeaseIfNotExistsInternal(String partitionId, BlobRequestOptions options) throws URISyntaxException, IOException, StorageException { @@ -389,14 +403,13 @@ private AzureBlobLease createLeaseIfNotExistsInternal(String partitionId, BlobRe uploadLease(returnLease, leaseBlob, AccessCondition.generateIfNoneMatchCondition("*"), UploadActivity.Create, options); // Do not set metadata on creation. No metadata/no owner value indicates that the lease is unowned. TRACE_LOGGER.info(this.hostContext.withHostAndPartition(partitionId, - "CreateLeaseIfNotExist OK - leaseContainerName: " + this.storageContainerName + " consumerGroupName: " + this.hostContext.getConsumerGroupName() + - " storageBlobPrefix: " + this.storageBlobPrefix)); + "CreateLeaseIfNotExist OK - leaseContainerName: " + this.storageContainerName + " consumerGroupName: " + this.hostContext.getConsumerGroupName() + + " storageBlobPrefix: " + this.storageBlobPrefix)); } catch (StorageException se) { StorageExtendedErrorInformation extendedErrorInfo = se.getExtendedErrorInformation(); - if ((extendedErrorInfo != null) && - ((extendedErrorInfo.getErrorCode().compareTo(StorageErrorCodeStrings.BLOB_ALREADY_EXISTS) == 0) || - (extendedErrorInfo.getErrorCode().compareTo(StorageErrorCodeStrings.LEASE_ID_MISSING) == 0))) // occurs when somebody else already has leased the blob - { + if ((extendedErrorInfo != null) + && ((extendedErrorInfo.getErrorCode().compareTo(StorageErrorCodeStrings.BLOB_ALREADY_EXISTS) == 0) + || (extendedErrorInfo.getErrorCode().compareTo(StorageErrorCodeStrings.LEASE_ID_MISSING) == 0))) { // occurs when somebody else already has leased the blob // The blob already exists. TRACE_LOGGER.info(this.hostContext.withHostAndPartition(partitionId, "Lease already exists")); returnLease = getLeaseInternal(partitionId, options); @@ -410,8 +423,8 @@ private AzureBlobLease createLeaseIfNotExistsInternal(String partitionId, BlobRe @Override public CompletableFuture deleteLease(CompleteLease lease) { - CompletableFuture future = null; - + CompletableFuture future = null; + TRACE_LOGGER.info(this.hostContext.withHostAndPartition(lease, "Deleting lease")); try { ((AzureBlobLease) lease).getBlob().deleteIfExists(); @@ -421,14 +434,14 @@ public CompletableFuture deleteLease(CompleteLease lease) { future = new CompletableFuture(); future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.DELETING_LEASE)); } - + return future; } @Override public CompletableFuture acquireLease(CompleteLease lease) { - CompletableFuture future = null; - + CompletableFuture future = null; + try { future = CompletableFuture.completedFuture(acquireLeaseInternal((AzureBlobLease) lease)); } catch (IOException | StorageException e) { @@ -436,7 +449,7 @@ public CompletableFuture acquireLease(CompleteLease lease) { future = new CompletableFuture(); future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.ACQUIRING_LEASE)); } - + return future; } @@ -490,22 +503,22 @@ private boolean acquireLeaseInternal(AzureBlobLease lease) throws IOException, S @Override public CompletableFuture renewLease(CompleteLease lease) { CompletableFuture future = null; - + try { future = CompletableFuture.completedFuture(renewLeaseInternal(lease)); } catch (StorageException se) { - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(se, EventProcessorHostActionStrings.RENEWING_LEASE)); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(se, EventProcessorHostActionStrings.RENEWING_LEASE)); } return future; } - + private boolean renewLeaseInternal(CompleteLease lease) throws StorageException { TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(lease, "Renewing lease")); boolean result = false; - AzureBlobLease azLease = (AzureBlobLease)lease; + AzureBlobLease azLease = (AzureBlobLease) lease; CloudBlockBlob leaseBlob = azLease.getBlob(); try { @@ -515,7 +528,7 @@ private boolean renewLeaseInternal(CompleteLease lease) throws StorageException if (wasLeaseLost(se, azLease.getPartitionId())) { // leave result as false } else { - throw se; + throw se; } } @@ -527,10 +540,10 @@ public CompletableFuture releaseLease(CompleteLease lease) { TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(lease, "Releasing lease")); CompletableFuture future = null; - + AzureBlobLease inLease = (AzureBlobLease) lease; CloudBlockBlob leaseBlob = inLease.getBlob(); - + try { String leaseId = inLease.getToken(); AzureBlobLease releasedCopy = new AzureBlobLease(inLease); @@ -544,30 +557,30 @@ public CompletableFuture releaseLease(CompleteLease lease) { // If the lease was already lost, then the intent of releasing it has been achieved. future = CompletableFuture.completedFuture(null); } else { - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(se, EventProcessorHostActionStrings.RELEASING_LEASE)); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(se, EventProcessorHostActionStrings.RELEASING_LEASE)); } } catch (IOException ie) { - future = new CompletableFuture(); - future.completeExceptionally(LoggingUtils.wrapException(ie, EventProcessorHostActionStrings.RELEASING_LEASE)); + future = new CompletableFuture(); + future.completeExceptionally(LoggingUtils.wrapException(ie, EventProcessorHostActionStrings.RELEASING_LEASE)); } - + return future; } @Override public CompletableFuture updateLease(CompleteLease lease) { - CompletableFuture future = null; - - try { - boolean result = updateLeaseInternal((AzureBlobLease) lease, this.leaseOperationOptions); - future = CompletableFuture.completedFuture(result); - } catch (StorageException | IOException e) { + CompletableFuture future = null; + + try { + boolean result = updateLeaseInternal((AzureBlobLease) lease, this.leaseOperationOptions); + future = CompletableFuture.completedFuture(result); + } catch (StorageException | IOException e) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(lease, "Failure updating lease"), e); future = new CompletableFuture(); future.completeExceptionally(LoggingUtils.wrapException(e, EventProcessorHostActionStrings.UPDATING_LEASE)); - } - + } + return future; } @@ -587,26 +600,26 @@ public boolean updateLeaseInternal(AzureBlobLease lease, BlobRequestOptions opti // Renewing the lease is always logically a lease operation, even if it is part of writing a checkpoint, so // don't pass options. boolean result = renewLeaseInternal(lease); - if (result) { + if (result) { CloudBlockBlob leaseBlob = lease.getBlob(); try { uploadLease(lease, leaseBlob, AccessCondition.generateLeaseCondition(token), UploadActivity.Update, options); // Success! Result is already true, so pass it up unchanged } catch (StorageException se) { if (wasLeaseLost(se, lease.getPartitionId())) { - result = false; + result = false; } else { - throw se; + throw se; } } catch (IOException ie) { - throw ie; + throw ie; } - } - // else could not renew lease due to lease loss. Result is already false, so pass it up unchanged - + } + // else could not renew lease due to lease loss. Result is already false, so pass it up unchanged + return result; } - + private AzureBlobLease downloadLease(CloudBlockBlob blob, BlobRequestOptions options) throws StorageException, IOException { String jsonLease = blob.downloadText(null, null, options, null); TRACE_LOGGER.debug(this.hostContext.withHost("Raw JSON downloaded: " + jsonLease)); @@ -646,27 +659,27 @@ private void uploadLease(AzureBlobLease lease, CloudBlockBlob blob, AccessCondit // avoids a spurious trace in that case. TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(lease, "Raw JSON uploading for " + activity + ": " + jsonLease)); - + if ((activity == UploadActivity.Acquire) || (activity == UploadActivity.Release)) { - blob.downloadAttributes(); - HashMap metadata = blob.getMetadata(); - switch (activity) { - case Acquire: - // Add owner in metadata - metadata.put(AzureStorageCheckpointLeaseManager.METADATA_OWNER_NAME, lease.getOwner()); - break; - - case Release: - // Remove owner in metadata - metadata.remove(AzureStorageCheckpointLeaseManager.METADATA_OWNER_NAME); - break; - - default: - // Should never get here, but passing the metadata through unchanged is harmless. - break; - } - blob.setMetadata(metadata); - blob.uploadMetadata(condition, options, null); + blob.downloadAttributes(); + HashMap metadata = blob.getMetadata(); + switch (activity) { + case Acquire: + // Add owner in metadata + metadata.put(AzureStorageCheckpointLeaseManager.METADATA_OWNER_NAME, lease.getOwner()); + break; + + case Release: + // Remove owner in metadata + metadata.remove(AzureStorageCheckpointLeaseManager.METADATA_OWNER_NAME); + break; + + default: + // Should never get here, but passing the metadata through unchanged is harmless. + break; + } + blob.setMetadata(metadata); + blob.uploadMetadata(condition, options, null); } // else don't touch metadata } @@ -679,17 +692,16 @@ private boolean wasLeaseLost(StorageException se, String partitionId) { "Http " + se.getExtendedErrorInformation().getErrorCode() + " :: " + se.getExtendedErrorInformation().getErrorMessage())); } if ((se.getHttpStatusCode() == 409) || // conflict - (se.getHttpStatusCode() == 412)) // precondition failed - { + (se.getHttpStatusCode() == 412)) { // precondition failed StorageExtendedErrorInformation extendedErrorInfo = se.getExtendedErrorInformation(); if (extendedErrorInfo != null) { String errorCode = extendedErrorInfo.getErrorCode(); TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(partitionId, "Error code: " + errorCode)); TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(partitionId, "Error message: " + extendedErrorInfo.getErrorMessage())); - if ((errorCode.compareTo(StorageErrorCodeStrings.LEASE_LOST) == 0) || - (errorCode.compareTo(StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_LEASE_OPERATION) == 0) || - (errorCode.compareTo(StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_BLOB_OPERATION) == 0) || - (errorCode.compareTo(StorageErrorCodeStrings.LEASE_ALREADY_PRESENT) == 0)) { + if ((errorCode.compareTo(StorageErrorCodeStrings.LEASE_LOST) == 0) + || (errorCode.compareTo(StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_LEASE_OPERATION) == 0) + || (errorCode.compareTo(StorageErrorCodeStrings.LEASE_ID_MISMATCH_WITH_BLOB_OPERATION) == 0) + || (errorCode.compareTo(StorageErrorCodeStrings.LEASE_ALREADY_PRESENT) == 0)) { retval = true; } } @@ -697,5 +709,5 @@ private boolean wasLeaseLost(StorageException se, String partitionId) { return retval; } - private enum UploadActivity {Create, Acquire, Release, Update} + private enum UploadActivity { Create, Acquire, Release, Update } } diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/BaseLease.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/BaseLease.java index 0cbc0fa53368d..7a9d05b895c1c 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/BaseLease.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/BaseLease.java @@ -19,7 +19,7 @@ public class BaseLease implements Comparable { private final String partitionId; private String owner = ""; - private transient boolean isOwned = false; // do not serialize + private transient boolean isOwned = false; // do not serialize /** * Do not use; added only for GSon deserializer @@ -45,9 +45,9 @@ public BaseLease(String partitionId) { * @param isOwned True if the lease is owned, false if not. */ public BaseLease(String partitionId, String owner, boolean isOwned) { - this.partitionId = partitionId; - this.owner = owner; - this.isOwned = isOwned; + this.partitionId = partitionId; + this.owner = owner; + this.isOwned = isOwned; } /** @@ -85,17 +85,17 @@ public void setOwner(String owner) { * @param newState true if the lease is owned, or false if it is not */ public void setIsOwned(boolean newState) { - this.isOwned = newState; + this.isOwned = newState; } - /** - * Get the owned state of the lease. - * - * @return true if the lease is owned, or false if it is not - */ - public boolean getIsOwned() { - return this.isOwned; - } + /** + * Get the owned state of the lease. + * + * @return true if the lease is owned, or false if it is not + */ + public boolean getIsOwned() { + return this.isOwned; + } /** * Convenience function for comparing possibleOwner against this.owner @@ -120,11 +120,11 @@ public String getPartitionId() { return this.partitionId; } - // Compares by partition id - @Override - public int compareTo(BaseLease other) { - return this.partitionId.compareTo(other.getPartitionId()); - } + // Compares by partition id + @Override + public int compareTo(BaseLease other) { + return this.partitionId.compareTo(other.getPartitionId()); + } String getStateDebug() { return "N/A"; diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/Closable.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/Closable.java index fd02de68c94e6..1ed9326baaf3c 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/Closable.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/Closable.java @@ -11,10 +11,10 @@ class Closable { // null parent means top-level Closable(Closable parent) { - this.syncClose = new Object(); - this.parent = parent; - this.isClosing = false; - this.isClosed = false; + this.syncClose = new Object(); + this.parent = parent; + this.isClosing = false; + this.isClosed = false; } protected final boolean getIsClosed() { @@ -33,29 +33,29 @@ protected final boolean getIsClosingOrClosed() { } protected final void setClosing() { - synchronized (this.syncClose) { - this.isClosing = true; - } + synchronized (this.syncClose) { + this.isClosing = true; + } } protected final void setClosed() { - synchronized (this.syncClose) { - this.isClosing = false; - this.isClosed = true; - } + synchronized (this.syncClose) { + this.isClosing = false; + this.isClosed = true; + } } protected final void throwIfClosingOrClosed(String message) { - if (getIsClosingOrClosed()) { - throw new ClosingException(message); - } + if (getIsClosingOrClosed()) { + throw new ClosingException(message); + } } class ClosingException extends RuntimeException { - private static final long serialVersionUID = 1138985585921317036L; + private static final long serialVersionUID = 1138985585921317036L; - ClosingException(String message) { - super(message); - } + ClosingException(String message) { + super(message); + } } } diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/CompleteLease.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/CompleteLease.java index 30c75c279b8da..2fd8fc8564f74 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/CompleteLease.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/CompleteLease.java @@ -22,7 +22,7 @@ public class CompleteLease extends BaseLease { * Do not use; added only for GSon deserializer */ protected CompleteLease() { - super(); + super(); } /** @@ -31,7 +31,7 @@ protected CompleteLease() { * @param partitionId Partition id for this lease. */ public CompleteLease(String partitionId) { - super(partitionId); + super(partitionId); } /** diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHost.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHost.java index d6bdae2f249ca..5cd28a98b14a9 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHost.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHost.java @@ -12,7 +12,14 @@ import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.util.UUID; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /*** @@ -500,8 +507,7 @@ public CompletableFuture unregisterEventProcessor() { // If we own the executor, stop it also. // Owned executor is also created in constructor. if (this.weOwnExecutor) { - this.unregistered = this.unregistered.thenRunAsync(() -> - { + this.unregistered = this.unregistered.thenRunAsync(() -> { // IMPORTANT: run this last stage in the default threadpool! // If a task running in a threadpool waits for that threadpool to terminate, it's going to wait a long time... diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHostActionStrings.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHostActionStrings.java index 42bf57c3dd017..5ca594409c654 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHostActionStrings.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/EventProcessorHostActionStrings.java @@ -8,27 +8,27 @@ * They describe what activity was taking place when the exception occurred. */ public final class EventProcessorHostActionStrings { - public final static String ACQUIRING_LEASE = "Acquiring Lease"; - public final static String CHECKING_CHECKPOINT_STORE = "Checking Checpoint Store Existence"; - public final static String CHECKING_LEASES = "Checking Leases"; - public final static String CHECKING_LEASE_STORE = "Checking Lease Store Existence"; - public final static String CLOSING_EVENT_PROCESSOR = "Closing Event Processor"; - public final static String CREATING_CHECKPOINTS = "Creating Checkpoint Holders"; - public final static String CREATING_CHECKPOINT_STORE = "Creating Checkpoint Store"; - public final static String CREATING_EVENT_HUB_CLIENT = "Creating Event Hub Client"; - public final static String CREATING_EVENT_PROCESSOR = "Creating Event Processor"; - public final static String CREATING_LEASES = "Creating Leases"; - public final static String CREATING_LEASE_STORE = "Creating Lease Store"; - public final static String DELETING_LEASE = "Deleting Lease"; - public final static String GETTING_CHECKPOINT = "Getting Checkpoint Details"; - public final static String GETTING_LEASE = "Getting Lease Details"; - public final static String INITIALIZING_STORES = "Initializing Stores"; - public final static String OPENING_EVENT_PROCESSOR = "Opening Event Processor"; - public final static String PARTITION_MANAGER_CLEANUP = "Partition Manager Cleanup"; - public final static String PARTITION_MANAGER_MAIN_LOOP = "Partition Manager Main Loop"; - public final static String RELEASING_LEASE = "Releasing Lease"; - public final static String RENEWING_LEASE = "Renewing Lease"; - public final static String STEALING_LEASE = "Stealing Lease"; - public final static String UPDATING_CHECKPOINT = "Updating Checkpoint"; - public final static String UPDATING_LEASE = "Updating Lease"; + public static final String ACQUIRING_LEASE = "Acquiring Lease"; + public static final String CHECKING_CHECKPOINT_STORE = "Checking Checpoint Store Existence"; + public static final String CHECKING_LEASES = "Checking Leases"; + public static final String CHECKING_LEASE_STORE = "Checking Lease Store Existence"; + public static final String CLOSING_EVENT_PROCESSOR = "Closing Event Processor"; + public static final String CREATING_CHECKPOINTS = "Creating Checkpoint Holders"; + public static final String CREATING_CHECKPOINT_STORE = "Creating Checkpoint Store"; + public static final String CREATING_EVENT_HUB_CLIENT = "Creating Event Hub Client"; + public static final String CREATING_EVENT_PROCESSOR = "Creating Event Processor"; + public static final String CREATING_LEASES = "Creating Leases"; + public static final String CREATING_LEASE_STORE = "Creating Lease Store"; + public static final String DELETING_LEASE = "Deleting Lease"; + public static final String GETTING_CHECKPOINT = "Getting Checkpoint Details"; + public static final String GETTING_LEASE = "Getting Lease Details"; + public static final String INITIALIZING_STORES = "Initializing Stores"; + public static final String OPENING_EVENT_PROCESSOR = "Opening Event Processor"; + public static final String PARTITION_MANAGER_CLEANUP = "Partition Manager Cleanup"; + public static final String PARTITION_MANAGER_MAIN_LOOP = "Partition Manager Main Loop"; + public static final String RELEASING_LEASE = "Releasing Lease"; + public static final String RENEWING_LEASE = "Renewing Lease"; + public static final String STEALING_LEASE = "Stealing Lease"; + public static final String UPDATING_CHECKPOINT = "Updating Checkpoint"; + public static final String UPDATING_LEASE = "Updating Lease"; } diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/HostContext.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/HostContext.java index 40d13afde2778..1998a782e97ae 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/HostContext.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/HostContext.java @@ -8,21 +8,21 @@ import java.util.concurrent.ScheduledExecutorService; final class HostContext { - final private ScheduledExecutorService executor; + private final ScheduledExecutorService executor; // Ideally we wouldn't need the host, but there are certain things which can be dynamically changed // by the user via APIs on the host and which need to be exposed on the HostContext. Passing the // call through is easier and safer than trying to keep two copies in sync. - final private EventProcessorHost host; - final private String hostName; + private final EventProcessorHost host; + private final String hostName; - final private String eventHubPath; - final private String consumerGroupName; - final private String eventHubConnectionString; - final private RetryPolicy retryPolicy; + private final String eventHubPath; + private final String consumerGroupName; + private final String eventHubConnectionString; + private final RetryPolicy retryPolicy; - final private ILeaseManager leaseManager; - final private ICheckpointManager checkpointManager; + private final ILeaseManager leaseManager; + private final ICheckpointManager checkpointManager; // Cannot be final because it is not available at HostContext construction time. private EventProcessorOptions eventProcessorOptions = null; diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/ICheckpointManager.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/ICheckpointManager.java index 868bb6fa7b2ac..36a41f0641577 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/ICheckpointManager.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/ICheckpointManager.java @@ -54,8 +54,8 @@ public interface ICheckpointManager { public CompletableFuture getCheckpoint(String partitionId); /*** - * Creates the checkpoint HOLDERs for the given partitions. Does nothing for any checkpoint HOLDERs - * that already exist. + * Creates the checkpoint HOLDERs for the given partitions. Does nothing for any checkpoint HOLDERs + * that already exist. * * The semantics of this are complicated because it is possible to use the same store for both * leases and checkpoints (the Azure Storage implementation does so) and it is required to diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryCheckpointManager.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryCheckpointManager.java index 6ea1a1193cdfa..594db9c70bb18 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryCheckpointManager.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryCheckpointManager.java @@ -86,22 +86,22 @@ public CompletableFuture getCheckpoint(String partitionId) { @Override public CompletableFuture createAllCheckpointsIfNotExists(List partitionIds) { - for (String id : partitionIds) { - Checkpoint checkpointInStore = InMemoryCheckpointStore.singleton.getCheckpoint(id); - if (checkpointInStore != null) { - TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(id, - "createCheckpointIfNotExists() found existing checkpoint, OK")); - } else { - TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(id, - "createCheckpointIfNotExists() creating new checkpoint")); - Checkpoint newStoreCheckpoint = new Checkpoint(id); - // This API actually creates the holder, not the checkpoint itself. In this implementation, we do create a Checkpoint object - // and put it in the store, but the values are set to indicate that it is not initialized. - newStoreCheckpoint.setOffset(null); - newStoreCheckpoint.setSequenceNumber(-1); - InMemoryCheckpointStore.singleton.setOrReplaceCheckpoint(newStoreCheckpoint); - } - } + for (String id : partitionIds) { + Checkpoint checkpointInStore = InMemoryCheckpointStore.singleton.getCheckpoint(id); + if (checkpointInStore != null) { + TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(id, + "createCheckpointIfNotExists() found existing checkpoint, OK")); + } else { + TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(id, + "createCheckpointIfNotExists() creating new checkpoint")); + Checkpoint newStoreCheckpoint = new Checkpoint(id); + // This API actually creates the holder, not the checkpoint itself. In this implementation, we do create a Checkpoint object + // and put it in the store, but the values are set to indicate that it is not initialized. + newStoreCheckpoint.setOffset(null); + newStoreCheckpoint.setSequenceNumber(-1); + InMemoryCheckpointStore.singleton.setOrReplaceCheckpoint(newStoreCheckpoint); + } + } return CompletableFuture.completedFuture(null); } @@ -129,7 +129,7 @@ public CompletableFuture deleteCheckpoint(String partitionId) { private static class InMemoryCheckpointStore { - final static InMemoryCheckpointStore singleton = new InMemoryCheckpointStore(); + static final InMemoryCheckpointStore singleton = new InMemoryCheckpointStore(); private ConcurrentHashMap inMemoryCheckpointsPrivate = null; diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryLeaseManager.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryLeaseManager.java index 75f156dd3b597..ecb094bad5ecc 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryLeaseManager.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/InMemoryLeaseManager.java @@ -8,7 +8,10 @@ import java.util.ArrayList; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ConcurrentHashMap; /*** * An ILeaseManager implementation based on an in-memory store. @@ -31,7 +34,7 @@ * or EventProcessorHost.registerEventProcessorFactory(). */ public class InMemoryLeaseManager implements ILeaseManager { - private final static Logger TRACE_LOGGER = LoggerFactory.getLogger(InMemoryLeaseManager.class); + private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(InMemoryLeaseManager.class); private HostContext hostContext; private long millisecondsLatency = 0; @@ -45,18 +48,18 @@ public void initialize(HostContext hostContext) { } public void setLatency(long milliseconds) { - this.millisecondsLatency = milliseconds; + this.millisecondsLatency = milliseconds; } private void latency(String caller) { if (this.millisecondsLatency > 0) { - try { - //TRACE_LOGGER.info("sleep " + caller); - Thread.sleep(this.millisecondsLatency); - } catch (InterruptedException e) { - // Don't care - TRACE_LOGGER.info("sleepFAIL " + caller); - } + try { + //TRACE_LOGGER.info("sleep " + caller); + Thread.sleep(this.millisecondsLatency); + } catch (InterruptedException e) { + // Don't care + TRACE_LOGGER.info("sleepFAIL " + caller); + } } } @@ -91,52 +94,52 @@ public CompletableFuture deleteLeaseStore() { @Override public CompletableFuture getLease(String partitionId) { - TRACE_LOGGER.debug(this.hostContext.withHost("getLease()")); - latency("getLease"); - InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(partitionId); - return CompletableFuture.completedFuture(new InMemoryLease(leaseInStore)); + TRACE_LOGGER.debug(this.hostContext.withHost("getLease()")); + latency("getLease"); + InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(partitionId); + return CompletableFuture.completedFuture(new InMemoryLease(leaseInStore)); } @Override public CompletableFuture> getAllLeases() { - ArrayList infos = new ArrayList(); - for (String id : InMemoryLeaseStore.singleton.getPartitionIds()) { - InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(id); - infos.add(new BaseLease(id, leaseInStore.getOwner(), !leaseInStore.isExpiredSync())); - } - latency("getAllLeasesStateInfo"); - return CompletableFuture.completedFuture(infos); + ArrayList infos = new ArrayList(); + for (String id : InMemoryLeaseStore.singleton.getPartitionIds()) { + InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(id); + infos.add(new BaseLease(id, leaseInStore.getOwner(), !leaseInStore.isExpiredSync())); + } + latency("getAllLeasesStateInfo"); + return CompletableFuture.completedFuture(infos); } @Override public CompletableFuture createAllLeasesIfNotExists(List partitionIds) { - ArrayList> createFutures = new ArrayList>(); - - // Implemented like this to provide an experience more similar to lease creation in the Storage-based manager. - for (String id : partitionIds) { - final String workingId = id; - CompletableFuture oneCreate = CompletableFuture.supplyAsync(() -> { - InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(workingId); - InMemoryLease returnLease = null; - if (leaseInStore != null) { - TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(workingId, - "createLeaseIfNotExists() found existing lease, OK")); - returnLease = new InMemoryLease(leaseInStore); - } else { - TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(workingId, - "createLeaseIfNotExists() creating new lease")); - InMemoryLease newStoreLease = new InMemoryLease(workingId); - InMemoryLeaseStore.singleton.setOrReplaceLease(newStoreLease); - returnLease = new InMemoryLease(newStoreLease); - } - latency("createLeaseIfNotExists " + workingId); - return returnLease; - }, this.hostContext.getExecutor()); - createFutures.add(oneCreate); - } - - CompletableFuture dummy[] = new CompletableFuture[createFutures.size()]; - return CompletableFuture.allOf(createFutures.toArray(dummy)); + ArrayList> createFutures = new ArrayList>(); + + // Implemented like this to provide an experience more similar to lease creation in the Storage-based manager. + for (String id : partitionIds) { + final String workingId = id; + CompletableFuture oneCreate = CompletableFuture.supplyAsync(() -> { + InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(workingId); + InMemoryLease returnLease = null; + if (leaseInStore != null) { + TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(workingId, + "createLeaseIfNotExists() found existing lease, OK")); + returnLease = new InMemoryLease(leaseInStore); + } else { + TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(workingId, + "createLeaseIfNotExists() creating new lease")); + InMemoryLease newStoreLease = new InMemoryLease(workingId); + InMemoryLeaseStore.singleton.setOrReplaceLease(newStoreLease); + returnLease = new InMemoryLease(newStoreLease); + } + latency("createLeaseIfNotExists " + workingId); + return returnLease; + }, this.hostContext.getExecutor()); + createFutures.add(oneCreate); + } + + CompletableFuture[] dummy = new CompletableFuture[createFutures.size()]; + return CompletableFuture.allOf(createFutures.toArray(dummy)); } @Override @@ -269,8 +272,7 @@ public CompletableFuture updateLease(CompleteLease lease) { TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(leaseToUpdate, "updateLease()")); // Renew lease first so it doesn't expire in the middle. - return renewLease(leaseToUpdate).thenApply((retval) -> - { + return renewLease(leaseToUpdate).thenApply((retval) -> { if (retval) { InMemoryLease leaseInStore = InMemoryLeaseStore.singleton.getLease(leaseToUpdate.getPartitionId()); if (leaseInStore != null) { @@ -296,7 +298,7 @@ public CompletableFuture updateLease(CompleteLease lease) { private static class InMemoryLeaseStore { - final static InMemoryLeaseStore singleton = new InMemoryLeaseStore(); + static final InMemoryLeaseStore singleton = new InMemoryLeaseStore(); private static int leaseDurationInMilliseconds; private ConcurrentHashMap inMemoryLeasesPrivate = null; @@ -323,8 +325,7 @@ synchronized InMemoryLease getLease(String partitionId) { synchronized List getPartitionIds() { ArrayList ids = new ArrayList(); - this.inMemoryLeasesPrivate.keySet().forEach((key) -> - { + this.inMemoryLeasesPrivate.keySet().forEach((key) -> { ids.add(key); }); return ids; @@ -377,7 +378,7 @@ synchronized void removeLease(InMemoryLease goneLease) { private static class InMemoryLease extends CompleteLease { - private final static Logger TRACE_LOGGER = LoggerFactory.getLogger(InMemoryLease.class); + private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(InMemoryLease.class); private long expirationTimeMillis = 0; InMemoryLease(String partitionId) { diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/LoggingUtils.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/LoggingUtils.java index 539b6875af9c9..9ed73eb53b54e 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/LoggingUtils.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/LoggingUtils.java @@ -24,8 +24,8 @@ static CompletionException wrapExceptionWithMessage(Throwable e, String message, static Throwable unwrapException(Throwable wrapped, StringBuilder outAction) { Throwable unwrapped = wrapped; - while ((unwrapped instanceof ExecutionException) || (unwrapped instanceof CompletionException) || - (unwrapped instanceof ExceptionWithAction)) { + while ((unwrapped instanceof ExecutionException) || (unwrapped instanceof CompletionException) + || (unwrapped instanceof ExceptionWithAction)) { if ((unwrapped instanceof ExceptionWithAction) && (outAction != null)) { // Save the action string from an ExceptionWithAction, if desired. outAction.append(((ExceptionWithAction) unwrapped).getAction()); diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionContext.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionContext.java index f7d2f53a35169..1adfacd07e494 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionContext.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionContext.java @@ -91,8 +91,8 @@ void setOffsetAndSequenceNumber(EventData event) { this.sequenceNumber = event.getSystemProperties().getSequenceNumber(); } else { TRACE_LOGGER.info(this.hostContext.withHostAndPartition(this.partitionId, - "setOffsetAndSequenceNumber(" + event.getSystemProperties().getOffset() + "//" + - event.getSystemProperties().getSequenceNumber() + ") would move backwards, ignoring")); + "setOffsetAndSequenceNumber(" + event.getSystemProperties().getOffset() + "//" + + event.getSystemProperties().getSequenceNumber() + ") would move backwards, ignoring")); } } @@ -108,8 +108,7 @@ public String getPartitionId() { // Returns a String (offset) or Instant (timestamp). CompletableFuture getInitialOffset() { return this.hostContext.getCheckpointManager().getCheckpoint(this.partitionId) - .thenApply((startingCheckpoint) -> - { + .thenApply((startingCheckpoint) -> { return checkpointToOffset(startingCheckpoint); }); } @@ -167,14 +166,14 @@ public CompletableFuture checkpoint() { * @return CompletableFuture {@literal ->} null when the checkpoint has been persisted successfully, completes exceptionally on error. */ public CompletableFuture checkpoint(EventData event) { - CompletableFuture result = null; - if (event == null) { - result = new CompletableFuture(); - result.completeExceptionally(new IllegalArgumentException("Cannot checkpoint with null EventData")); - } else { - result = checkpoint(new Checkpoint(this.partitionId, event.getSystemProperties().getOffset(), event.getSystemProperties().getSequenceNumber())); - } - return result; + CompletableFuture result = null; + if (event == null) { + result = new CompletableFuture(); + result.completeExceptionally(new IllegalArgumentException("Cannot checkpoint with null EventData")); + } else { + result = checkpoint(new Checkpoint(this.partitionId, event.getSystemProperties().getOffset(), event.getSystemProperties().getSequenceNumber())); + } + return result; } /** @@ -186,15 +185,15 @@ public CompletableFuture checkpoint(EventData event) { * @return CompletableFuture {@literal ->} null when the checkpoint has been persisted successfully, completes exceptionally on error. */ public CompletableFuture checkpoint(Checkpoint checkpoint) { - CompletableFuture result = null; - if (checkpoint == null) { - result = new CompletableFuture(); - result.completeExceptionally(new IllegalArgumentException("Cannot checkpoint with null Checkpoint")); - } else { - TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(checkpoint.getPartitionId(), - "Saving checkpoint: " + checkpoint.getOffset() + "//" + checkpoint.getSequenceNumber())); - result = this.hostContext.getCheckpointManager().updateCheckpoint(this.lease, checkpoint); - } - return result; + CompletableFuture result = null; + if (checkpoint == null) { + result = new CompletableFuture(); + result.completeExceptionally(new IllegalArgumentException("Cannot checkpoint with null Checkpoint")); + } else { + TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(checkpoint.getPartitionId(), + "Saving checkpoint: " + checkpoint.getOffset() + "//" + checkpoint.getSequenceNumber())); + result = this.hostContext.getCheckpointManager().updateCheckpoint(this.lease, checkpoint); + } + return result; } } diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManager.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManager.java index f661317055045..b8a6d85de6355 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManager.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManager.java @@ -12,16 +12,21 @@ import java.io.IOException; import java.util.Arrays; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; class PartitionManager extends Closable { private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(PartitionManager.class); // Protected instead of private for testability protected final HostContext hostContext; - final private Object scanFutureSynchronizer = new Object(); + private final Object scanFutureSynchronizer = new Object(); private final int retryMax = 5; protected PumpManager pumpManager = null; - protected volatile String partitionIds[] = null; + protected volatile String[] partitionIds = null; private ScheduledFuture scanFuture = null; PartitionManager(HostContext hostContext) { @@ -44,8 +49,7 @@ CompletableFuture cachePartitionIds() { // Stage 0A: get EventHubClient for the event hub retval = EventHubClient.create(this.hostContext.getEventHubConnectionString(), this.hostContext.getRetryPolicy(), this.hostContext.getExecutor()) // Stage 0B: set up a way to close the EventHubClient when we're done - .thenApplyAsync((ehClient) -> - { + .thenApplyAsync((ehClient) -> { final EventHubClient saveForCleanupClient = ehClient; cleanupFuture.thenComposeAsync((empty) -> saveForCleanupClient.close(), this.hostContext.getExecutor()); return ehClient; @@ -53,8 +57,7 @@ CompletableFuture cachePartitionIds() { // Stage 1: use the client to get runtime info for the event hub .thenComposeAsync((ehClient) -> ehClient.getRuntimeInformation(), this.hostContext.getExecutor()) // Stage 2: extract the partition ids from the runtime info or throw on null (timeout) - .thenAcceptAsync((EventHubRuntimeInformation ehInfo) -> - { + .thenAcceptAsync((EventHubRuntimeInformation ehInfo) -> { if (ehInfo != null) { this.partitionIds = ehInfo.getPartitionIds(); @@ -67,8 +70,7 @@ CompletableFuture cachePartitionIds() { } }, this.hostContext.getExecutor()) // Stage 3: RUN REGARDLESS OF EXCEPTIONS -- if there was an error, wrap it in IllegalEntityException and throw - .handleAsync((empty, e) -> - { + .handleAsync((empty, e) -> { cleanupFuture.complete(null); // trigger client cleanup if (e != null) { Throwable notifyWith = e; @@ -147,8 +149,7 @@ public CompletableFuture initialize() { // Stage 1: initialize stores, if stage 0 succeeded .thenComposeAsync((unused) -> initializeStores(), this.hostContext.getExecutor()) // Stage 2: RUN REGARDLESS OF EXCEPTIONS -- trace errors - .whenCompleteAsync((empty, e) -> - { + .whenCompleteAsync((empty, e) -> { if (e != null) { StringBuilder outAction = new StringBuilder(); Throwable notifyWith = LoggingUtils.unwrapException(e, outAction); @@ -161,8 +162,7 @@ public CompletableFuture initialize() { } }, this.hostContext.getExecutor()) // Stage 3: schedule scan, which will find partitions and start pumps, if previous stages succeeded - .thenRunAsync(() -> - { + .thenRunAsync(() -> { // Schedule the first scan immediately. synchronized (this.scanFutureSynchronizer) { TRACE_LOGGER.debug(this.hostContext.withHost("Scheduling lease scanner first pass")); @@ -180,8 +180,8 @@ private CompletableFuture initializeStores() { // let R = this.retryMax // Stages 0 to R: create lease store if it doesn't exist CompletableFuture initializeStoresFuture = buildRetries(CompletableFuture.completedFuture(null), - () -> leaseManager.createLeaseStoreIfNotExists(), "Failure creating lease store for this Event Hub, retrying", - "Out of retries creating lease store for this Event Hub", EventProcessorHostActionStrings.CREATING_LEASE_STORE, this.retryMax); + () -> leaseManager.createLeaseStoreIfNotExists(), "Failure creating lease store for this Event Hub, retrying", + "Out of retries creating lease store for this Event Hub", EventProcessorHostActionStrings.CREATING_LEASE_STORE, this.retryMax); // Stages R+1 to 2R: create checkpoint store if it doesn't exist initializeStoresFuture = buildRetries(initializeStoresFuture, () -> checkpointManager.createCheckpointStoreIfNotExists(), @@ -197,8 +197,7 @@ private CompletableFuture initializeStores() { "Failure creating checkpoint holders, retrying", "Out of retries creating checkpoint holders", EventProcessorHostActionStrings.CREATING_CHECKPOINTS, this.retryMax); - initializeStoresFuture.whenCompleteAsync((r, e) -> - { + initializeStoresFuture.whenCompleteAsync((r, e) -> { // If an exception has propagated this far, it should be a FinalException, which is guaranteed to contain a CompletionException. // Unwrap it so we don't leak a private type. if ((e != null) && (e instanceof FinalException)) { @@ -216,8 +215,7 @@ private CompletableFuture initializeStores() { private CompletableFuture buildRetries(CompletableFuture buildOnto, Callable> lambda, String retryMessage, String finalFailureMessage, String action, int maxRetries) { // Stage 0: first attempt - CompletableFuture retryChain = buildOnto.thenComposeAsync((unused) -> - { + CompletableFuture retryChain = buildOnto.thenComposeAsync((unused) -> { CompletableFuture newresult = CompletableFuture.completedFuture(null); try { newresult = lambda.call(); @@ -232,8 +230,7 @@ private CompletableFuture buildRetries(CompletableFuture buildOnto, Callab // Stages 1, 3, 5, etc: trace errors but stop normal exception propagation in order to keep going. // Either return null if we don't have a valid result, or pass the result along to the next stage. // FinalExceptions are passed along also so that fatal error earlier in the chain aren't lost. - .handleAsync((r, e) -> - { + .handleAsync((r, e) -> { Object effectiveResult = r; if (e != null) { if (e instanceof FinalException) { @@ -252,8 +249,7 @@ private CompletableFuture buildRetries(CompletableFuture buildOnto, Callab }, this.hostContext.getExecutor()) // Stages 2, 4, 6, etc: if we already have a valid result, pass it along. Otherwise, make another attempt. // Once we have a valid result there will be no more attempts or exceptions. - .thenComposeAsync((oldresult) -> - { + .thenComposeAsync((oldresult) -> { CompletableFuture newresult = CompletableFuture.completedFuture(oldresult); if (oldresult == null) { try { @@ -266,8 +262,7 @@ private CompletableFuture buildRetries(CompletableFuture buildOnto, Callab }, this.hostContext.getExecutor()); } // Stage final: trace the exception with the final message, or pass along the valid result. - retryChain = retryChain.handleAsync((r, e) -> - { + retryChain = retryChain.handleAsync((r, e) -> { if (e != null) { if (e instanceof FinalException) { throw (FinalException) e; @@ -289,16 +284,15 @@ private Void scan(boolean isFirst) { long start = System.currentTimeMillis(); (new PartitionScanner(this.hostContext, (lease) -> this.pumpManager.addPump(lease), this)).scan(isFirst) - .whenCompleteAsync((didSteal, e) -> - { + .whenCompleteAsync((didSteal, e) -> { TRACE_LOGGER.debug(this.hostContext.withHost("Scanning took " + (System.currentTimeMillis() - start))); onPartitionCheckCompleteTestHook(); // Schedule the next scan unless we are shutting down. if (!this.getIsClosingOrClosed()) { - int seconds = didSteal ? this.hostContext.getPartitionManagerOptions().getFastScanIntervalInSeconds() : - this.hostContext.getPartitionManagerOptions().getSlowScanIntervalInSeconds(); + int seconds = didSteal ? this.hostContext.getPartitionManagerOptions().getFastScanIntervalInSeconds() + : this.hostContext.getPartitionManagerOptions().getSlowScanIntervalInSeconds(); if (isFirst) { seconds = this.hostContext.getPartitionManagerOptions().getStartupScanDelayInSeconds(); } diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManagerOptions.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManagerOptions.java index 2a44e3ef1e821..c1c1365bcc659 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManagerOptions.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionManagerOptions.java @@ -13,21 +13,21 @@ public class PartitionManagerOptions { /** * The default duration after which a partition lease will expire unless renewed. */ - public final static int DefaultLeaseDurationInSeconds = 30; + public static final int DefaultLeaseDurationInSeconds = 30; /** * The default duration between lease renewals. */ - public final static int DefaultLeaseRenewIntervalInSeconds = 10; + public static final int DefaultLeaseRenewIntervalInSeconds = 10; /** * The default timeout for checkpoint operations. */ - public final static int DefaultCheckpointTimeoutInSeconds = 120; + public static final int DefaultCheckpointTimeoutInSeconds = 120; - public final static int DefaultStartupScanDelayInSeconds = 30; - public final static int DefaultFastScanIntervalInSeconds = 3; - public final static int DefaultSlowScanIntervalInSeconds = 5; + public static final int DefaultStartupScanDelayInSeconds = 30; + public static final int DefaultFastScanIntervalInSeconds = 3; + public static final int DefaultSlowScanIntervalInSeconds = 5; protected int leaseDurationInSeconds = PartitionManagerOptions.DefaultLeaseDurationInSeconds; protected int leaseRenewIntervalInSeconds = PartitionManagerOptions.DefaultLeaseRenewIntervalInSeconds; diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionPump.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionPump.java index af89c14e2e853..ef774f314eaea 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionPump.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionPump.java @@ -3,7 +3,13 @@ package com.microsoft.azure.eventprocessorhost; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.EventData; +import com.microsoft.azure.eventhubs.EventHubClient; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.PartitionReceiveHandler; +import com.microsoft.azure.eventhubs.PartitionReceiver; +import com.microsoft.azure.eventhubs.ReceiverDisconnectedException; +import com.microsoft.azure.eventhubs.ReceiverOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,8 +26,8 @@ class PartitionPump extends Closable implements PartitionReceiveHandler { private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(PartitionPump.class); protected final HostContext hostContext; protected final CompleteLease lease; // protected for testability - final private CompletableFuture shutdownTriggerFuture; - final private CompletableFuture shutdownFinishedFuture; + private final CompletableFuture shutdownTriggerFuture; + private final CompletableFuture shutdownFinishedFuture; private final Object processingSynchronizer; private final Consumer pumpManagerCallback; private EventHubClient eventHubClient = null; @@ -66,8 +72,7 @@ CompletableFuture startPump() { CompletableFuture.runAsync(() -> openProcessor(), this.hostContext.getExecutor()) .thenComposeAsync((empty) -> openClientsRetryWrapper(), this.hostContext.getExecutor()) .thenRunAsync(() -> scheduleLeaseRenewer(), this.hostContext.getExecutor()) - .whenCompleteAsync((r, e) -> - { + .whenCompleteAsync((r, e) -> { if (e != null) { // If startup failed, trigger shutdown to clean up. internalShutdown(CloseReason.Shutdown, e); @@ -103,12 +108,11 @@ private CompletableFuture openClientsRetryWrapper() { retryResult = retryResult // Stages 1, 3, 5, etc: trace errors but stop exception propagation in order to keep going // UNLESS it's ReceiverDisconnectedException. - .handleAsync((r, e) -> - { + .handleAsync((r, e) -> { if (e != null) { Exception notifyWith = (Exception) LoggingUtils.unwrapException(e, null); if (notifyWith instanceof ReceiverDisconnectedException) { - // TODO Assuming this is due to a receiver with a higher epoch. + // TODO: Assuming this is due to a receiver with a higher epoch. // Is there a way to be sure without checking the exception text? // DO NOT trace here because then we could get multiple traces for the same exception. // If it's a bad epoch, then retrying isn't going to help. @@ -123,15 +127,13 @@ private CompletableFuture openClientsRetryWrapper() { return (e == null) ? r : false; }, this.hostContext.getExecutor()) // Stages 2, 4, 6, etc: make another attempt if needed. - .thenComposeAsync((done) -> - { + .thenComposeAsync((done) -> { return done ? CompletableFuture.completedFuture(done) : openClients(); }, this.hostContext.getExecutor()); } // Stage final: on success, hook up the user's event handler to start receiving events. On error, // trace exceptions from the final attempt, or ReceiverDisconnectedException. - return retryResult.handleAsync((r, e) -> - { + return retryResult.handleAsync((r, e) -> { if (e == null) { // IEventProcessor.onOpen is called from the base PartitionPump and must have returned in order for execution to reach here, // meaning it is safe to set the handler and start calling IEventProcessor.onEvents. @@ -139,7 +141,7 @@ private CompletableFuture openClientsRetryWrapper() { } else { Exception notifyWith = (Exception) LoggingUtils.unwrapException(e, null); if (notifyWith instanceof ReceiverDisconnectedException) { - // TODO Assuming this is due to a receiver with a higher epoch. + // TODO: Assuming this is due to a receiver with a higher epoch. // Is there a way to be sure without checking the exception text? TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(this.partitionContext, "Receiver disconnected on create, bad epoch?"), notifyWith); @@ -186,8 +188,7 @@ private CompletableFuture openClients() { // Stage 0: get EventHubClient return startOpeningFuture // Stage 1: save EventHubClient on success, trace on error - .whenCompleteAsync((ehclient, e) -> - { + .whenCompleteAsync((ehclient, e) -> { if ((ehclient != null) && (e == null)) { this.eventHubClient = ehclient; } else { @@ -199,8 +200,7 @@ private CompletableFuture openClients() { // Stage 2: get initial offset for receiver .thenComposeAsync((empty) -> this.partitionContext.getInitialOffset(), this.hostContext.getExecutor()) // Stage 3: set up other receiver options, create receiver if initial offset is valid - .thenComposeAsync((startAt) -> - { + .thenComposeAsync((startAt) -> { long epoch = this.lease.getEpoch(); TRACE_LOGGER.info(this.hostContext.withHostAndPartition(this.partitionContext, @@ -225,8 +225,7 @@ private CompletableFuture openClients() { return receiverFuture; }, this.hostContext.getExecutor()) // Stage 4: save PartitionReceiver on success, trace on error - .whenCompleteAsync((receiver, e) -> - { + .whenCompleteAsync((receiver, e) -> { if ((receiver != null) && (e == null)) { this.partitionReceiver = receiver; } else if (this.eventHubClient != null) { @@ -242,8 +241,7 @@ private CompletableFuture openClients() { this.internalOperationFuture = null; }, this.hostContext.getExecutor()) // Stage 5: on success, set up the receiver - .thenApplyAsync((receiver) -> - { + .thenApplyAsync((receiver) -> { this.partitionReceiver.setReceiveTimeout(this.hostContext.getEventProcessorOptions().getReceiveTimeOut()); TRACE_LOGGER.info(this.hostContext.withHostAndPartition(this.partitionContext, @@ -253,11 +251,9 @@ private CompletableFuture openClients() { }, this.hostContext.getExecutor()); } - private CompletableFuture cleanUpAll(CloseReason reason) // swallows all exceptions - { + private CompletableFuture cleanUpAll(CloseReason reason) { // swallows all exceptions return cleanUpClients() - .thenRunAsync(() -> - { + .thenRunAsync(() -> { if (this.processor != null) { try { synchronized (this.processingSynchronizer) { @@ -278,8 +274,7 @@ private CompletableFuture cleanUpAll(CloseReason reason) // swallows all e }, this.hostContext.getExecutor()); } - private CompletableFuture cleanUpClients() // swallows all exceptions - { + private CompletableFuture cleanUpClients() { // swallows all exceptions CompletableFuture cleanupFuture = null; if (this.partitionReceiver != null) { // Disconnect the processor from the receiver we're about to close. @@ -292,35 +287,30 @@ private CompletableFuture cleanUpClients() // swallows all exceptions TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(this.partitionContext, "partitionReceiver is null in cleanup")); cleanupFuture = CompletableFuture.completedFuture(null); } - cleanupFuture = cleanupFuture.handleAsync((empty, e) -> - { + cleanupFuture = cleanupFuture.handleAsync((empty, e) -> { if (e != null) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(this.partitionContext, "Got exception when ReceiveHandler is set to null."), LoggingUtils.unwrapException(e, null)); } return null; // stop propagation of exceptions }, this.hostContext.getExecutor()) - .thenApplyAsync((empty) -> - { + .thenApplyAsync((empty) -> { TRACE_LOGGER.info(this.hostContext.withHostAndPartition(this.partitionContext, "Closing EH receiver")); PartitionReceiver partitionReceiverTemp = this.partitionReceiver; this.partitionReceiver = null; return partitionReceiverTemp; }, this.hostContext.getExecutor()) - .thenComposeAsync((partitionReceiverTemp) -> - { + .thenComposeAsync((partitionReceiverTemp) -> { return (partitionReceiverTemp != null) ? partitionReceiverTemp.close() : CompletableFuture.completedFuture(null); }, this.hostContext.getExecutor()) - .handleAsync((empty, e) -> - { + .handleAsync((empty, e) -> { if (e != null) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(this.partitionContext, "Closing EH receiver failed."), LoggingUtils.unwrapException(e, null)); } return null; // stop propagation of exceptions }, this.hostContext.getExecutor()) - .thenApplyAsync((empty) -> - { + .thenApplyAsync((empty) -> { TRACE_LOGGER.info(this.hostContext.withHostAndPartition(this.partitionContext, "Closing EH client")); final EventHubClient eventHubClientTemp = this.eventHubClient; this.eventHubClient = null; @@ -330,12 +320,10 @@ private CompletableFuture cleanUpClients() // swallows all exceptions } return eventHubClientTemp; }, this.hostContext.getExecutor()) - .thenComposeAsync((eventHubClientTemp) -> - { + .thenComposeAsync((eventHubClientTemp) -> { return (eventHubClientTemp != null) ? eventHubClientTemp.close() : CompletableFuture.completedFuture(null); }, this.hostContext.getExecutor()) - .handleAsync((empty, e) -> - { + .handleAsync((empty, e) -> { if (e != null) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(this.partitionContext, "Closing EH client failed."), LoggingUtils.unwrapException(e, null)); @@ -360,16 +348,14 @@ protected Void cancelPendingOperations() { return null; } - private CompletableFuture releaseLeaseOnShutdown() // swallows all exceptions - { + private CompletableFuture releaseLeaseOnShutdown() { // swallows all exceptions CompletableFuture result = CompletableFuture.completedFuture(null); if (this.shutdownReason != CloseReason.LeaseLost) { // Since this pump is dead, release the lease. Don't care about any errors that may occur. Worst case is // that the lease eventually expires, since the lease renewer has been cancelled. result = PartitionPump.this.hostContext.getLeaseManager().releaseLease(this.lease) - .handleAsync((empty, e) -> - { + .handleAsync((empty, e) -> { if (e != null) { TRACE_LOGGER.warn(this.hostContext.withHostAndPartition(this.partitionContext, "Failure releasing lease on pump shutdown"), LoggingUtils.unwrapException(e, null)); @@ -415,8 +401,7 @@ private void leaseRenewer() { // Stage 0: renew the lease this.hostContext.getLeaseManager().renewLease(this.lease) // Stage 1: check result of renewing - .thenApplyAsync((renewed) -> - { + .thenApplyAsync((renewed) -> { Boolean scheduleNext = true; if (!renewed) { // False return from renewLease means that lease was lost. @@ -428,8 +413,7 @@ private void leaseRenewer() { return scheduleNext; }, this.hostContext.getExecutor()) // Stage 2: RUN REGARDLESS OF EXCEPTIONS -- trace exceptions, schedule next iteration - .whenCompleteAsync((scheduleNext, e) -> - { + .whenCompleteAsync((scheduleNext, e) -> { if (e != null) { // Failure renewing lease due to storage exception or whatever. // Trace error and leave scheduleNext as true to schedule another try. @@ -491,7 +475,7 @@ public void onReceive(Iterable events) { this.processor.onEvents(this.partitionContext, effectiveEvents); } } catch (Exception e) { - // TODO -- do we pass errors from IEventProcessor.onEvents to IEventProcessor.onError? + // TODO: do we pass errors from IEventProcessor.onEvents to IEventProcessor.onError? // Depending on how you look at it, that's either pointless (if the user's code throws, the user's code should already know about it) or // a convenient way of centralizing error handling. // In the meantime, just trace it. diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionScanner.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionScanner.java index d2f381b311356..3e0198b1c6446 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionScanner.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PartitionScanner.java @@ -6,7 +6,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -24,11 +30,11 @@ class PartitionScanner extends Closable { // Values populated by sortLeasesAndCalculateDesiredCount private int desiredCount; private int unownedCount; // updated by acquireExpiredInChunksParallel - final private ConcurrentHashMap leasesOwnedByOthers; // updated by acquireExpiredInChunksParallel + private final ConcurrentHashMap leasesOwnedByOthers; // updated by acquireExpiredInChunksParallel PartitionScanner(HostContext hostContext, Consumer addPump, Closable parent) { - super(parent); - + super(parent); + this.hostContext = hostContext; this.addPump = addPump; @@ -40,12 +46,12 @@ class PartitionScanner extends Closable { public CompletableFuture scan(boolean isFirst) { return getAllLeaseStates() .thenComposeAsync((unused) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); int ourLeasesCount = sortLeasesAndCalculateDesiredCount(isFirst); return acquireExpiredInChunksParallel(0, this.desiredCount - ourLeasesCount); }, this.hostContext.getExecutor()) .thenApplyAsync((remainingNeeded) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); ArrayList stealThese = new ArrayList(); if (remainingNeeded > 0) { TRACE_LOGGER.debug(this.hostContext.withHost("Looking to steal: " + remainingNeeded)); @@ -54,8 +60,8 @@ public CompletableFuture scan(boolean isFirst) { return stealThese; }, this.hostContext.getExecutor()) .thenComposeAsync((stealThese) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); - return stealLeases(stealThese); + throwIfClosingOrClosed("PartitionScanner is shutting down"); + return stealLeases(stealThese); }, this.hostContext.getExecutor()) .handleAsync((didSteal, e) -> { if ((e != null) && !(e instanceof ClosingException)) { @@ -71,10 +77,10 @@ public CompletableFuture scan(boolean isFirst) { } private CompletableFuture getAllLeaseStates() { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); return this.hostContext.getLeaseManager().getAllLeases() .thenAcceptAsync((states) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); this.allLeaseStates = states; Collections.sort(this.allLeaseStates); }, this.hostContext.getExecutor()); @@ -147,8 +153,8 @@ private int sortLeasesAndCalculateDesiredCount(boolean isFirst) { // Returns a CompletableFuture as a convenience for the caller private CompletableFuture> findExpiredLeases(int startAt, int endAt) { final ArrayList expiredLeases = new ArrayList(); - TRACE_LOGGER.debug(this.hostContext.withHost("Finding expired leases from '" + this.allLeaseStates.get(startAt).getPartitionId() + "'[" + startAt + "] up to '" + - ((endAt < this.allLeaseStates.size()) ? this.allLeaseStates.get(endAt).getPartitionId() : "end") + "'[" + endAt + "]")); + TRACE_LOGGER.debug(this.hostContext.withHost("Finding expired leases from '" + this.allLeaseStates.get(startAt).getPartitionId() + "'[" + startAt + "] up to '" + + ((endAt < this.allLeaseStates.size()) ? this.allLeaseStates.get(endAt).getPartitionId() : "end") + "'[" + endAt + "]")); for (BaseLease info : this.allLeaseStates.subList(startAt, endAt)) { if (!info.getIsOwned()) { @@ -161,7 +167,7 @@ private CompletableFuture> findExpiredLeases(int startAt, int en } private CompletableFuture acquireExpiredInChunksParallel(int startAt, int needed) { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); CompletableFuture resultFuture = CompletableFuture.completedFuture(needed); if (startAt < this.allLeaseStates.size()) { @@ -173,24 +179,24 @@ private CompletableFuture acquireExpiredInChunksParallel(int startAt, i if ((needed > 0) && (this.unownedCount > 0) && (startAt < this.allLeaseStates.size())) { final AtomicInteger runningNeeded = new AtomicInteger(needed); final int endAt = Math.min(startAt + needed, this.allLeaseStates.size()); - + resultFuture = findExpiredLeases(startAt, endAt) .thenComposeAsync((getThese) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); - CompletableFuture acquireFuture = CompletableFuture.completedFuture(null); + throwIfClosingOrClosed("PartitionScanner is shutting down"); + CompletableFuture acquireFuture = CompletableFuture.completedFuture(null); if (getThese.size() > 0) { ArrayList> getFutures = new ArrayList>(); for (BaseLease info : getThese) { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); final AcquisitionHolder holder = new AcquisitionHolder(); CompletableFuture getOneFuture = this.hostContext.getLeaseManager().getLease(info.getPartitionId()) .thenComposeAsync((lease) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); - holder.setAcquiredLease(lease); + throwIfClosingOrClosed("PartitionScanner is shutting down"); + holder.setAcquiredLease(lease); return this.hostContext.getLeaseManager().acquireLease(lease); }, this.hostContext.getExecutor()) .thenAcceptAsync((acquired) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); if (acquired) { runningNeeded.decrementAndGet(); TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(holder.getAcquiredLease().getPartitionId(), "Acquired unowned/expired")); @@ -281,26 +287,26 @@ private CompletableFuture stealLeases(List stealThese) { if (stealThese.size() > 0) { ArrayList> steals = new ArrayList>(); for (BaseLease info : stealThese) { - throwIfClosingOrClosed("PartitionScanner is shutting down"); + throwIfClosingOrClosed("PartitionScanner is shutting down"); - final AcquisitionHolder holder = new AcquisitionHolder(); + final AcquisitionHolder holder = new AcquisitionHolder(); CompletableFuture oneSteal = this.hostContext.getLeaseManager().getLease(info.getPartitionId()) - .thenComposeAsync((lease) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); - holder.setAcquiredLease(lease); - return this.hostContext.getLeaseManager().acquireLease(lease); - }, this.hostContext.getExecutor()) - .thenAcceptAsync((acquired) -> { - throwIfClosingOrClosed("PartitionScanner is shutting down"); - if (acquired) { - TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(holder.getAcquiredLease().getPartitionId(), "Stole lease")); - this.addPump.accept(holder.getAcquiredLease()); - } - }, this.hostContext.getExecutor()); + .thenComposeAsync((lease) -> { + throwIfClosingOrClosed("PartitionScanner is shutting down"); + holder.setAcquiredLease(lease); + return this.hostContext.getLeaseManager().acquireLease(lease); + }, this.hostContext.getExecutor()) + .thenAcceptAsync((acquired) -> { + throwIfClosingOrClosed("PartitionScanner is shutting down"); + if (acquired) { + TRACE_LOGGER.debug(this.hostContext.withHostAndPartition(holder.getAcquiredLease().getPartitionId(), "Stole lease")); + this.addPump.accept(holder.getAcquiredLease()); + } + }, this.hostContext.getExecutor()); steals.add(oneSteal); } - CompletableFuture dummy[] = new CompletableFuture[steals.size()]; + CompletableFuture[] dummy = new CompletableFuture[steals.size()]; allSteals = CompletableFuture.allOf(steals.toArray(dummy)).thenApplyAsync((empty) -> true, this.hostContext.getExecutor()); } @@ -308,14 +314,14 @@ private CompletableFuture stealLeases(List stealThese) { } private class AcquisitionHolder { - private CompleteLease acquiredLease; - - void setAcquiredLease(CompleteLease l) { - this.acquiredLease = l; - } - - CompleteLease getAcquiredLease() { - return this.acquiredLease; - } + private CompleteLease acquiredLease; + + void setAcquiredLease(CompleteLease l) { + this.acquiredLease = l; + } + + CompleteLease getAcquiredLease() { + return this.acquiredLease; + } } } diff --git a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PumpManager.java b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PumpManager.java index b097bd88e7229..46afe864b38a4 100644 --- a/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PumpManager.java +++ b/eventhubs/data-plane/azure-eventhubs-eph/src/main/java/com/microsoft/azure/eventprocessorhost/PumpManager.java @@ -17,23 +17,23 @@ class PumpManager extends Closable implements Consumer { protected ConcurrentHashMap pumpStates; // protected for testability public PumpManager(HostContext hostContext, Closable parent) { - super(parent); - + super(parent); + this.hostContext = hostContext; this.pumpStates = new ConcurrentHashMap(); } public void addPump(CompleteLease lease) { - if (getIsClosingOrClosed()) { - TRACE_LOGGER.info(this.hostContext.withHostAndPartition(lease, "Shutting down, not creating new pump")); - return; - } - + if (getIsClosingOrClosed()) { + TRACE_LOGGER.info(this.hostContext.withHostAndPartition(lease, "Shutting down, not creating new pump")); + return; + } + PartitionPump capturedPump = this.pumpStates.get(lease.getPartitionId()); // CONCURRENTHASHTABLE if (capturedPump != null) { // There already is a pump. This should never happen and it's not harmless if it does. If we get here, - // it implies that the existing pump is a zombie which is not renewing its lease. + // it implies that the existing pump is a zombie which is not renewing its lease. TRACE_LOGGER.error(this.hostContext.withHostAndPartition(lease, "throwing away zombie pump")); // Shutdown should remove the pump from the hashmap, but we don't know what state this pump is in so // remove it manually. ConcurrentHashMap specifies that removing an item that doesn't exist is a safe no-op. @@ -49,12 +49,12 @@ public void addPump(CompleteLease lease) { } // Callback used by pumps during pump shutdown. - @Override - public void accept(String partitionId) { - // These are fast, non-blocking actions. - this.pumpStates.remove(partitionId); - removingPumpTestHook(partitionId); - } + @Override + public void accept(String partitionId) { + // These are fast, non-blocking actions. + this.pumpStates.remove(partitionId); + removingPumpTestHook(partitionId); + } // Separated out so that tests can override and substitute their own pump class. protected PartitionPump createNewPump(CompleteLease lease) { @@ -77,15 +77,17 @@ public CompletableFuture removePump(String partitionId, final CloseReason } public CompletableFuture removeAllPumps(CloseReason reason) { - setClosing(); - + setClosing(); + CompletableFuture[] futures = new CompletableFuture[this.pumpStates.size()]; int i = 0; for (String partitionId : this.pumpStates.keySet()) { futures[i++] = removePump(partitionId, reason); } - - return CompletableFuture.allOf(futures).whenCompleteAsync((empty, e) -> { setClosed(); }, this.hostContext.getExecutor()); + + return CompletableFuture.allOf(futures).whenCompleteAsync((empty, e) -> { + setClosed(); + }, this.hostContext.getExecutor()); } protected void removingPumpTestHook(String partitionId) { diff --git a/eventhubs/data-plane/azure-eventhubs-extensions/src/main/java/com/microsoft/azure/eventhubs/extensions/appender/EventHubsAppender.java b/eventhubs/data-plane/azure-eventhubs-extensions/src/main/java/com/microsoft/azure/eventhubs/extensions/appender/EventHubsAppender.java index 140393d5b68f9..cf1f8dc6e5f89 100644 --- a/eventhubs/data-plane/azure-eventhubs-extensions/src/main/java/com/microsoft/azure/eventhubs/extensions/appender/EventHubsAppender.java +++ b/eventhubs/data-plane/azure-eventhubs-extensions/src/main/java/com/microsoft/azure/eventhubs/extensions/appender/EventHubsAppender.java @@ -15,9 +15,10 @@ import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; import org.apache.logging.log4j.core.util.StringEncoder; -import java.io.*; +import java.io.Serializable; import java.nio.charset.StandardCharsets; -import java.util.*; + +import java.util.Locale; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; @@ -116,8 +117,6 @@ public void append(LogEvent logEvent) { } } - ; - @Override public void start() { super.start(); @@ -137,4 +136,4 @@ public void stop() { super.stop(); this.eventHubsManager.release(); } -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ConnectionStringBuilder.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ConnectionStringBuilder.java index f5879173ce492..763e79835f27b 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ConnectionStringBuilder.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ConnectionStringBuilder.java @@ -20,11 +20,11 @@ *

Sample Code: *

{@code
  *  // Construct a new connection string
- * 	ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder()
- * 	    .setNamespaceName("EventHubsNamespaceName")
- * 	    .setEventHubName("EventHubsEntityName")
- * 	    .setSasKeyName("SharedAccessSignatureKeyName")
- * 	    .setSasKey("SharedAccessSignatureKey")
+ *  ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder()
+ *      .setNamespaceName("EventHubsNamespaceName")
+ *      .setEventHubName("EventHubsEntityName")
+ *      .setSasKeyName("SharedAccessSignatureKeyName")
+ *      .setSasKey("SharedAccessSignatureKey")
  *
  *  string connString = connectionStringBuilder.build();
  *
@@ -47,20 +47,20 @@
  */
 public final class ConnectionStringBuilder {
 
-    final static String endpointFormat = "sb://%s.%s";
-    final static String hostnameFormat = "sb://%s";
-    final static String defaultDomainName = "servicebus.windows.net";
-
-    final static String HostnameConfigName = "Hostname";    // Hostname is a key that is used in IoTHub.
-    final static String EndpointConfigName = "Endpoint";    // Endpoint key is used in EventHubs. It's identical to Hostname in IoTHub.
-    final static String EntityPathConfigName = "EntityPath";
-    final static String OperationTimeoutConfigName = "OperationTimeout";
-    final static String KeyValueSeparator = "=";
-    final static String KeyValuePairDelimiter = ";";
-    final static String SharedAccessKeyNameConfigName = "SharedAccessKeyName";  // We use a (KeyName, Key) pair OR the SAS token - never both.
-    final static String SharedAccessKeyConfigName = "SharedAccessKey";
-    final static String SharedAccessSignatureConfigName = "SharedAccessSignature";
-    final static String TransportTypeConfigName = "TransportType";
+    static final String endpointFormat = "sb://%s.%s";
+    static final String hostnameFormat = "sb://%s";
+    static final String defaultDomainName = "servicebus.windows.net";
+
+    static final String HostnameConfigName = "Hostname";    // Hostname is a key that is used in IoTHub.
+    static final String EndpointConfigName = "Endpoint";    // Endpoint key is used in EventHubs. It's identical to Hostname in IoTHub.
+    static final String EntityPathConfigName = "EntityPath";
+    static final String OperationTimeoutConfigName = "OperationTimeout";
+    static final String KeyValueSeparator = "=";
+    static final String KeyValuePairDelimiter = ";";
+    static final String SharedAccessKeyNameConfigName = "SharedAccessKeyName";  // We use a (KeyName, Key) pair OR the SAS token - never both.
+    static final String SharedAccessKeyConfigName = "SharedAccessKey";
+    static final String SharedAccessSignatureConfigName = "SharedAccessSignature";
+    static final String TransportTypeConfigName = "TransportType";
 
     private static final String AllKeyEnumerateRegex = "(" + HostnameConfigName + "|" + EndpointConfigName + "|" + SharedAccessKeyNameConfigName
             + "|" + SharedAccessKeyConfigName + "|" + SharedAccessSignatureConfigName + "|" + EntityPathConfigName + "|" + OperationTimeoutConfigName
diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventData.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventData.java
index f2f4b41472a4b..b1f4f364b39aa 100755
--- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventData.java
+++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventData.java
@@ -10,8 +10,10 @@
 import java.io.Serializable;
 import java.nio.ByteBuffer;
 import java.time.Instant;
-import java.util.*;
-import java.util.concurrent.ScheduledExecutorService;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * The data structure encapsulating the Event being sent-to and received-from EventHubs.
@@ -35,8 +37,8 @@ public interface EventData extends Serializable, Comparable {
      * Construct EventData to Send to EventHubs.
      * Typical pattern to create a Sending EventData is:
      * 
-     * i.	Serialize the sending ApplicationEvent to be sent to EventHubs into bytes.
-     * ii.	If complex serialization logic is involved (for example: multiple types of data) - add a Hint using the {@link #getProperties()} for the Consumer.
+     * i.   Serialize the sending ApplicationEvent to be sent to EventHubs into bytes.
+     * ii.  If complex serialization logic is involved (for example: multiple types of data) - add a Hint using the {@link #getProperties()} for the Consumer.
      * 
*

Sample Code: *

@@ -57,8 +59,8 @@ static EventData create(final byte[] data) {
      * Construct EventData to Send to EventHubs.
      * Typical pattern to create a Sending EventData is:
      * 
-     * i.	Serialize the sending ApplicationEvent to be sent to EventHubs into bytes.
-     * ii.	If complex serialization logic is involved (for example: multiple types of data) - add a Hint using the {@link #getProperties()} for the Consumer.
+     * i.   Serialize the sending ApplicationEvent to be sent to EventHubs into bytes.
+     * ii.  If complex serialization logic is involved (for example: multiple types of data) - add a Hint using the {@link #getProperties()} for the Consumer.
      *  
*

Illustration: *

 {@code
@@ -81,14 +83,14 @@ static EventData create(final byte[] data, final int offset, final int length) {
      * Construct EventData to Send to EventHubs.
      * Typical pattern to create a Sending EventData is:
      * 
-     * i.	Serialize the sending ApplicationEvent to be sent to EventHubs into bytes.
-     * ii.	If complex serialization logic is involved (for example: multiple types of data) - add a Hint using the {@link #getProperties()} for the Consumer.
+     * i.   Serialize the sending ApplicationEvent to be sent to EventHubs into bytes.
+     * ii.  If complex serialization logic is involved (for example: multiple types of data) - add a Hint using the {@link #getProperties()} for the Consumer.
      *  
*

Illustration: *

 {@code
      *  EventData eventData = EventData.create(telemetryEventByteBuffer);
      *  eventData.getProperties().put("eventType", "com.microsoft.azure.monitoring.EtlEvent");
-     * 	partitionSender.Send(eventData);
+     *  partitionSender.Send(eventData);
      *  }
* * @param buffer ByteBuffer which references the payload of the Event to be sent to EventHubs diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventHubClient.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventHubClient.java index 86fea27195580..0e943f0bcbb9a 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventHubClient.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/EventHubClient.java @@ -9,7 +9,6 @@ import java.io.IOException; import java.nio.channels.UnresolvedAddressException; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; /** @@ -126,9 +125,9 @@ default void sendSync(final EventData data) throws EventHubException { * Send {@link EventData} to EventHub. The sent {@link EventData} will land on any arbitrarily chosen EventHubs partition. *

There are 3 ways to send to EventHubs, each exposed as a method (along with its sendBatch overload): *

    - *
  • {@link #send(EventData)}, {@link #send(Iterable)}, or {@link #send(EventDataBatch)} - *
  • {@link #send(EventData, String)} or {@link #send(Iterable, String)} - *
  • {@link PartitionSender#send(EventData)}, {@link PartitionSender#send(Iterable)}, or {@link PartitionSender#send(EventDataBatch)} + *
  • {@link #send(EventData)}, {@link #send(Iterable)}, or {@link #send(EventDataBatch)} + *
  • {@link #send(EventData, String)} or {@link #send(Iterable, String)} + *
  • {@link PartitionSender#send(EventData)}, {@link PartitionSender#send(Iterable)}, or {@link PartitionSender#send(EventDataBatch)} *
*

Use this method to Send, if: *

@@ -168,8 +167,8 @@ default void sendSync(final Iterable eventDatas) throws EventHubExcep
      * Use this overload versus {@link #send(EventData)}, if you need to send a batch of {@link EventData}.
      * 

Sending a batch of {@link EventData}'s is useful in the following cases: *

-     * i.	Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.
-     * ii.	Send multiple {@link EventData}'s in a Transaction. To achieve ACID properties, the Gateway Service will forward all {@link EventData}'s in the batch to a single EventHubs' partition.
+     * i.   Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.
+     * ii.  Send multiple {@link EventData}'s in a Transaction. To achieve ACID properties, the Gateway Service will forward all {@link EventData}'s in the batch to a single EventHubs' partition.
      * 
*

* Sample code (sample uses sync version of the api but concept are identical): @@ -283,8 +282,8 @@ default void sendSync(final Iterable eventDatas, final String partiti *

There are 3 ways to send to EventHubs, to understand this particular type of Send refer to the overload {@link #send(EventData, String)}, which is the same type of Send and is used to send single {@link EventData}. *

Sending a batch of {@link EventData}'s is useful in the following cases: *

-     * i.	Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs service.
-     * ii.	Send multiple events in One Transaction. This is the reason why all events sent in a batch needs to have same partitionKey (so that they are sent to one partition only).
+     * i.   Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs service.
+     * ii.  Send multiple events in One Transaction. This is the reason why all events sent in a batch needs to have same partitionKey (so that they are sent to one partition only).
      * 
* * @param eventDatas the batch of events to send to EventHub diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiveHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiveHandler.java index a972e30c05727..e51c203fa868b 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiveHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiveHandler.java @@ -33,4 +33,4 @@ public interface PartitionReceiveHandler { * @param error fatal error encountered while running the {@link PartitionReceiveHandler} pump */ void onError(final Throwable error); -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiver.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiver.java index 542f5d1fcfdc0..e724e49f17d9e 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiver.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionReceiver.java @@ -140,4 +140,4 @@ default Iterable receiveSync(final int maxEventCount) throws EventHub CompletableFuture close(); void closeSync() throws EventHubException; -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionSender.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionSender.java index 578fe8292932f..fc93495744709 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionSender.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/PartitionSender.java @@ -6,7 +6,6 @@ import com.microsoft.azure.eventhubs.impl.ExceptionUtil; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ScheduledExecutorService; /** * This sender class is a logical representation of sending events to a specific EventHub partition. Do not use this class @@ -93,8 +92,8 @@ default void sendSync(final Iterable eventDatas) throws EventHubExcep *

* Sending a batch of {@link EventData}'s is useful in the following cases: *

-     * i.	Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.
-     * ii.	Send multiple {@link EventData}'s in a Transaction. To achieve ACID properties, the Gateway Service will forward all {@link EventData}'s in the batch to a single EventHubs' partition.
+     * i.   Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.
+     * ii.  Send multiple {@link EventData}'s in a Transaction. To achieve ACID properties, the Gateway Service will forward all {@link EventData}'s in the batch to a single EventHubs' partition.
      * 
*

* Sample code (sample uses sync version of the api but concept are identical): @@ -143,8 +142,8 @@ default void sendSync(final EventDataBatch eventDatas) throws EventHubException *

* Sending a batch of {@link EventData}'s is useful in the following cases: *

-     * i.	Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.
-     * ii.	Send multiple {@link EventData}'s in a Transaction. To achieve ACID properties, the Gateway Service will forward all {@link EventData}'s in the batch to a single EventHubs' partition.
+     * i.   Efficient send - sending a batch of {@link EventData} maximizes the overall throughput by optimally using the number of sessions created to EventHubs' service.
+     * ii.  Send multiple {@link EventData}'s in a Transaction. To achieve ACID properties, the Gateway Service will forward all {@link EventData}'s in the batch to a single EventHubs' partition.
      * 
* * @param eventDatas EventDataBatch to send to EventHub diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ReceiverOptions.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ReceiverOptions.java index 4302817c0c2a5..315927bf8e672 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ReceiverOptions.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/ReceiverOptions.java @@ -22,8 +22,8 @@ public ReceiverOptions() { private static void validateReceiverIdentifier(final String receiverName) { - if (receiverName != null && - receiverName.length() > ClientConstants.MAX_RECEIVER_NAME_LENGTH) { + if (receiverName != null + && receiverName.length() > ClientConstants.MAX_RECEIVER_NAME_LENGTH) { throw new IllegalArgumentException("receiverIdentifier length cannot exceed 64"); } } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/RetryPolicy.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/RetryPolicy.java index d3b04b49ac32d..b5d9f02463c68 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/RetryPolicy.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/RetryPolicy.java @@ -76,8 +76,8 @@ protected int getRetryCount(String clientId) { public Duration getNextRetryInterval(String clientId, Exception lastException, Duration remainingTime) { int baseWaitTime = 0; synchronized (this.serverBusySync) { - if (lastException != null && - (lastException instanceof ServerBusyException || (lastException.getCause() != null && lastException.getCause() instanceof ServerBusyException))) { + if (lastException != null + && (lastException instanceof ServerBusyException || (lastException.getCause() != null && lastException.getCause() instanceof ServerBusyException))) { baseWaitTime += ClientConstants.SERVER_BUSY_BASE_SLEEP_TIME_IN_SECS; } } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/TransportType.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/TransportType.java index f681277296de7..ac95d9ca9739f 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/TransportType.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/TransportType.java @@ -37,4 +37,4 @@ static TransportType fromString(final String value) { throw new IllegalArgumentException(); } -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/AmqpConstants.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/AmqpConstants.java index acc30c3995621..eac5f39c9caa1 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/AmqpConstants.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/AmqpConstants.java @@ -48,20 +48,20 @@ public final class AmqpConstants { public static final String AMQP_PROPERTY_REPLY_TO_GROUP_ID = "reply-to-group-id"; @SuppressWarnings("serial") public static final Set RESERVED_PROPERTY_NAMES = Collections.unmodifiableSet(new HashSet() {{ - add(AMQP_PROPERTY_MESSAGE_ID); - add(AMQP_PROPERTY_USER_ID); - add(AMQP_PROPERTY_TO); - add(AMQP_PROPERTY_SUBJECT); - add(AMQP_PROPERTY_REPLY_TO); - add(AMQP_PROPERTY_CORRELATION_ID); - add(AMQP_PROPERTY_CONTENT_TYPE); - add(AMQP_PROPERTY_CONTENT_ENCODING); - add(AMQP_PROPERTY_ABSOLUTE_EXPRITY_TIME); - add(AMQP_PROPERTY_CREATION_TIME); - add(AMQP_PROPERTY_GROUP_ID); - add(AMQP_PROPERTY_GROUP_SEQUENCE); - add(AMQP_PROPERTY_REPLY_TO_GROUP_ID); - }}); + add(AMQP_PROPERTY_MESSAGE_ID); + add(AMQP_PROPERTY_USER_ID); + add(AMQP_PROPERTY_TO); + add(AMQP_PROPERTY_SUBJECT); + add(AMQP_PROPERTY_REPLY_TO); + add(AMQP_PROPERTY_CORRELATION_ID); + add(AMQP_PROPERTY_CONTENT_TYPE); + add(AMQP_PROPERTY_CONTENT_ENCODING); + add(AMQP_PROPERTY_ABSOLUTE_EXPRITY_TIME); + add(AMQP_PROPERTY_CREATION_TIME); + add(AMQP_PROPERTY_GROUP_ID); + add(AMQP_PROPERTY_GROUP_SEQUENCE); + add(AMQP_PROPERTY_REPLY_TO_GROUP_ID); + }}); public static final Symbol ENABLE_RECEIVER_RUNTIME_METRIC_NAME = Symbol.valueOf(VENDOR + ":enable-receiver-runtime-metric"); public static final Symbol RECEIVER_IDENTIFIER_NAME = Symbol.valueOf(AmqpConstants.VENDOR + ":receiver-name"); private AmqpConstants() { diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/BaseLinkHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/BaseLinkHandler.java index 6ef7d610b5216..991c3b1cf9b20 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/BaseLinkHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/BaseLinkHandler.java @@ -4,7 +4,11 @@ package com.microsoft.azure.eventhubs.impl; import org.apache.qpid.proton.amqp.transport.ErrorCondition; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Event; +import org.apache.qpid.proton.engine.Link; +import org.apache.qpid.proton.engine.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ClientConstants.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ClientConstants.java index 31a9e4b0dde21..9d140815aef10 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ClientConstants.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ClientConstants.java @@ -8,35 +8,35 @@ import java.time.Duration; public final class ClientConstants { - public final static int AMQPS_PORT = 5671; - public final static int HTTPS_PORT = 443; - public final static int MAX_PARTITION_KEY_LENGTH = 128; - public final static Symbol SERVER_BUSY_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":server-busy"); - public final static Symbol ARGUMENT_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":argument-error"); - public final static Symbol ARGUMENT_OUT_OF_RANGE_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":argument-out-of-range"); - public final static Symbol ENTITY_DISABLED_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":entity-disabled"); - public final static Symbol PARTITION_NOT_OWNED_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":partition-not-owned"); - public final static Symbol STORE_LOCK_LOST_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":store-lock-lost"); - public final static Symbol PUBLISHER_REVOKED_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":publisher-revoked"); - public final static Symbol TIMEOUT_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":timeout"); - public final static Symbol TRACKING_ID_PROPERTY = Symbol.getSymbol(AmqpConstants.VENDOR + ":tracking-id"); + public static final int AMQPS_PORT = 5671; + public static final int HTTPS_PORT = 443; + public static final int MAX_PARTITION_KEY_LENGTH = 128; + public static final Symbol SERVER_BUSY_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":server-busy"); + public static final Symbol ARGUMENT_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":argument-error"); + public static final Symbol ARGUMENT_OUT_OF_RANGE_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":argument-out-of-range"); + public static final Symbol ENTITY_DISABLED_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":entity-disabled"); + public static final Symbol PARTITION_NOT_OWNED_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":partition-not-owned"); + public static final Symbol STORE_LOCK_LOST_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":store-lock-lost"); + public static final Symbol PUBLISHER_REVOKED_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":publisher-revoked"); + public static final Symbol TIMEOUT_ERROR = Symbol.getSymbol(AmqpConstants.VENDOR + ":timeout"); + public static final Symbol TRACKING_ID_PROPERTY = Symbol.getSymbol(AmqpConstants.VENDOR + ":tracking-id"); public static final int MAX_MESSAGE_LENGTH_BYTES = 256 * 1024; public static final int MAX_FRAME_SIZE_BYTES = 64 * 1024; public static final int MAX_EVENTHUB_AMQP_HEADER_SIZE_BYTES = 512; - public final static Duration TIMER_TOLERANCE = Duration.ofSeconds(1); - public final static Duration DEFAULT_RETRY_MIN_BACKOFF = Duration.ofSeconds(0); - public final static Duration DEFAULT_RETRY_MAX_BACKOFF = Duration.ofSeconds(30); - public final static Duration TOKEN_REFRESH_INTERVAL = Duration.ofMinutes(10); // renew every 10 mins, which expires 20 mins - public final static Duration TOKEN_VALIDITY = Duration.ofMinutes(20); - public final static int DEFAULT_MAX_RETRY_COUNT = 10; - public final static boolean DEFAULT_IS_TRANSIENT = true; - public final static int REACTOR_IO_POLL_TIMEOUT = 20; - public final static int SERVER_BUSY_BASE_SLEEP_TIME_IN_SECS = 4; - public final static int MGMT_CHANNEL_MIN_RETRY_IN_MILLIS = 5; - public final static String NO_RETRY = "NoRetry"; - public final static String DEFAULT_RETRY = "Default"; - public final static String PRODUCT_NAME = "MSJavaClient"; - public final static String CURRENT_JAVACLIENT_VERSION = "2.0.0"; + public static final Duration TIMER_TOLERANCE = Duration.ofSeconds(1); + public static final Duration DEFAULT_RETRY_MIN_BACKOFF = Duration.ofSeconds(0); + public static final Duration DEFAULT_RETRY_MAX_BACKOFF = Duration.ofSeconds(30); + public static final Duration TOKEN_REFRESH_INTERVAL = Duration.ofMinutes(10); // renew every 10 mins, which expires 20 mins + public static final Duration TOKEN_VALIDITY = Duration.ofMinutes(20); + public static final int DEFAULT_MAX_RETRY_COUNT = 10; + public static final boolean DEFAULT_IS_TRANSIENT = true; + public static final int REACTOR_IO_POLL_TIMEOUT = 20; + public static final int SERVER_BUSY_BASE_SLEEP_TIME_IN_SECS = 4; + public static final int MGMT_CHANNEL_MIN_RETRY_IN_MILLIS = 5; + public static final String NO_RETRY = "NoRetry"; + public static final String DEFAULT_RETRY = "Default"; + public static final String PRODUCT_NAME = "MSJavaClient"; + public static final String CURRENT_JAVACLIENT_VERSION = "2.0.0"; public static final String PLATFORM_INFO = getPlatformInfo(); public static final String FRAMEWORK_INFO = getFrameworkInfo(); public static final String CBS_ADDRESS = "$cbs"; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ConnectionHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ConnectionHandler.java index d5aab0d41e946..f3f98809160bd 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ConnectionHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ConnectionHandler.java @@ -7,7 +7,12 @@ import org.apache.qpid.proton.Proton; import org.apache.qpid.proton.amqp.Symbol; import org.apache.qpid.proton.amqp.transport.ErrorCondition; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.Connection; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Event; +import org.apache.qpid.proton.engine.SslDomain; +import org.apache.qpid.proton.engine.Transport; import org.apache.qpid.proton.engine.impl.TransportInternal; import org.apache.qpid.proton.reactor.Handshaker; import org.slf4j.Logger; @@ -82,9 +87,9 @@ public void onConnectionInit(Event event) { final String userAgent = EventHubClientImpl.USER_AGENT; if (userAgent != null) { - connectionProperties.put(AmqpConstants.USER_AGENT, userAgent.length() < AmqpConstants.MAX_USER_AGENT_LENGTH ? - userAgent : - userAgent.substring(0, AmqpConstants.MAX_USER_AGENT_LENGTH)); + connectionProperties.put(AmqpConstants.USER_AGENT, userAgent.length() < AmqpConstants.MAX_USER_AGENT_LENGTH + ? userAgent + : userAgent.substring(0, AmqpConstants.MAX_USER_AGENT_LENGTH)); } connection.setProperties(connectionProperties); diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataImpl.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataImpl.java index 00eca81c66f1e..93be1ce8b2d60 100755 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataImpl.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataImpl.java @@ -7,7 +7,12 @@ import org.apache.qpid.proton.Proton; import org.apache.qpid.proton.amqp.Binary; import org.apache.qpid.proton.amqp.Symbol; -import org.apache.qpid.proton.amqp.messaging.*; +import org.apache.qpid.proton.amqp.messaging.AmqpSequence; +import org.apache.qpid.proton.amqp.messaging.AmqpValue; +import org.apache.qpid.proton.amqp.messaging.ApplicationProperties; +import org.apache.qpid.proton.amqp.messaging.Data; +import org.apache.qpid.proton.amqp.messaging.MessageAnnotations; +import org.apache.qpid.proton.amqp.messaging.Section; import org.apache.qpid.proton.message.Message; import java.io.IOException; @@ -22,8 +27,8 @@ public final class EventDataImpl implements EventData { private static final long serialVersionUID = -5631628195600014255L; private static final int BODY_DATA_NULL = -1; - transient private Binary bodyData; - transient private Object amqpBody; + private transient Binary bodyData; + private transient Object amqpBody; private Map properties; private SystemProperties systemProperties; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataUtil.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataUtil.java index 35263f2c1542b..dba9d1e999745 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataUtil.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventDataUtil.java @@ -7,7 +7,11 @@ import com.microsoft.azure.eventhubs.EventPosition; import org.apache.qpid.proton.message.Message; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; import java.util.function.Consumer; /* @@ -17,12 +21,12 @@ final class EventDataUtil { @SuppressWarnings("serial") static final Set RESERVED_SYSTEM_PROPERTIES = Collections.unmodifiableSet(new HashSet() {{ - add(AmqpConstants.OFFSET_ANNOTATION_NAME); - add(AmqpConstants.PARTITION_KEY_ANNOTATION_NAME); - add(AmqpConstants.SEQUENCE_NUMBER_ANNOTATION_NAME); - add(AmqpConstants.ENQUEUED_TIME_UTC_ANNOTATION_NAME); - add(AmqpConstants.PUBLISHER_ANNOTATION_NAME); - }}); + add(AmqpConstants.OFFSET_ANNOTATION_NAME); + add(AmqpConstants.PARTITION_KEY_ANNOTATION_NAME); + add(AmqpConstants.SEQUENCE_NUMBER_ANNOTATION_NAME); + add(AmqpConstants.ENQUEUED_TIME_UTC_ANNOTATION_NAME); + add(AmqpConstants.PUBLISHER_ANNOTATION_NAME); + }}); private EventDataUtil() { } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventHubClientImpl.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventHubClientImpl.java index 453f800b7849b..d8bcf45a4065c 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventHubClientImpl.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventHubClientImpl.java @@ -3,7 +3,20 @@ package com.microsoft.azure.eventhubs.impl; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.BatchOptions; +import com.microsoft.azure.eventhubs.ConnectionStringBuilder; +import com.microsoft.azure.eventhubs.EventData; +import com.microsoft.azure.eventhubs.EventDataBatch; +import com.microsoft.azure.eventhubs.EventHubClient; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.EventHubRuntimeInformation; +import com.microsoft.azure.eventhubs.EventPosition; +import com.microsoft.azure.eventhubs.OperationCancelledException; +import com.microsoft.azure.eventhubs.PartitionReceiver; +import com.microsoft.azure.eventhubs.PartitionRuntimeInformation; +import com.microsoft.azure.eventhubs.PartitionSender; +import com.microsoft.azure.eventhubs.ReceiverOptions; +import com.microsoft.azure.eventhubs.RetryPolicy; import java.io.IOException; import java.security.InvalidKeyException; @@ -44,7 +57,7 @@ private EventHubClientImpl(final ConnectionStringBuilder connectionString, final } public static CompletableFuture create( - final String connectionString, final RetryPolicy retryPolicy, final ScheduledExecutorService executor) + final String connectionString, final RetryPolicy retryPolicy, final ScheduledExecutorService executor) throws EventHubException, IOException { final ConnectionStringBuilder connStr = new ConnectionStringBuilder(connectionString); final EventHubClientImpl eventHubClient = new EventHubClientImpl(connStr, executor); @@ -67,20 +80,20 @@ public String getEventHubName() { public final EventDataBatch createBatch(BatchOptions options) throws EventHubException { return ExceptionUtil.sync(() -> { - int maxSize = this.createInternalSender().thenApplyAsync( - (aVoid) -> this.sender.getMaxMessageSize(), - this.executor).get(); - if (options.maxMessageSize == null) { - return new EventDataBatchImpl(maxSize, options.partitionKey); - } - - if (options.maxMessageSize > maxSize) { - throw new IllegalArgumentException("The maxMessageSize set in BatchOptions is too large. You set a maxMessageSize of " + - options.maxMessageSize + ". The maximum allowed size is " + maxSize + "."); - } + int maxSize = this.createInternalSender().thenApplyAsync( + (aVoid) -> this.sender.getMaxMessageSize(), + this.executor).get(); + if (options.maxMessageSize == null) { + return new EventDataBatchImpl(maxSize, options.partitionKey); + } - return new EventDataBatchImpl(options.maxMessageSize, options.partitionKey); + if (options.maxMessageSize > maxSize) { + throw new IllegalArgumentException("The maxMessageSize set in BatchOptions is too large. You set a maxMessageSize of " + + options.maxMessageSize + ". The maximum allowed size is " + maxSize + "."); } + + return new EventDataBatchImpl(options.maxMessageSize, options.partitionKey); + } ); } @@ -119,9 +132,9 @@ public final CompletableFuture send(final EventDataBatch eventDatas) { } final EventDataBatchImpl eventDataBatch = (EventDataBatchImpl) eventDatas; - return eventDataBatch.getPartitionKey() != null ? - this.send(eventDataBatch.getInternalIterable(), eventDataBatch.getPartitionKey()) : - this.send(eventDataBatch.getInternalIterable()); + return eventDataBatch.getPartitionKey() != null + ? this.send(eventDataBatch.getInternalIterable(), eventDataBatch.getPartitionKey()) + : this.send(eventDataBatch.getInternalIterable()); } @Override @@ -201,11 +214,11 @@ public CompletableFuture onClose() { synchronized (this.senderCreateSync) { final CompletableFuture internalSenderClose = this.sender != null ? this.sender.close().thenComposeAsync(new Function>() { - @Override - public CompletableFuture apply(Void voidArg) { - return EventHubClientImpl.this.underlyingFactory.close(); - } - }, this.executor) + @Override + public CompletableFuture apply(Void voidArg) { + return EventHubClientImpl.this.underlyingFactory.close(); + } + }, this.executor) : this.underlyingFactory.close(); return internalSenderClose; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventPositionImpl.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventPositionImpl.java index 26f126c34da9b..af8a99b26d793 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventPositionImpl.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/EventPositionImpl.java @@ -72,15 +72,15 @@ public boolean getInclusiveFlag() { String getExpression() { // order of preference if (this.offset != null) { - return this.inclusiveFlag ? - String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.OFFSET_ANNOTATION_NAME, "=", this.offset) : - String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.OFFSET_ANNOTATION_NAME, StringUtil.EMPTY, this.offset); + return this.inclusiveFlag + ? String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.OFFSET_ANNOTATION_NAME, "=", this.offset) + : String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.OFFSET_ANNOTATION_NAME, StringUtil.EMPTY, this.offset); } if (this.sequenceNumber != null) { - return this.inclusiveFlag ? - String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.SEQUENCE_NUMBER_ANNOTATION_NAME, "=", this.sequenceNumber) : - String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.SEQUENCE_NUMBER_ANNOTATION_NAME, StringUtil.EMPTY, this.sequenceNumber); + return this.inclusiveFlag + ? String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.SEQUENCE_NUMBER_ANNOTATION_NAME, "=", this.sequenceNumber) + : String.format(AmqpConstants.AMQP_ANNOTATION_FORMAT, AmqpConstants.SEQUENCE_NUMBER_ANNOTATION_NAME, StringUtil.EMPTY, this.sequenceNumber); } if (this.dateTime != null) { diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ExceptionUtil.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ExceptionUtil.java index ef091bb755469..66b7617e5cbf2 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ExceptionUtil.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ExceptionUtil.java @@ -3,7 +3,15 @@ package com.microsoft.azure.eventhubs.impl; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.AuthorizationFailedException; +import com.microsoft.azure.eventhubs.ErrorContext; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.IllegalEntityException; +import com.microsoft.azure.eventhubs.PayloadSizeExceededException; +import com.microsoft.azure.eventhubs.QuotaExceededException; +import com.microsoft.azure.eventhubs.ReceiverDisconnectedException; +import com.microsoft.azure.eventhubs.ServerBusyException; +import com.microsoft.azure.eventhubs.TimeoutException; import org.apache.qpid.proton.amqp.Symbol; import org.apache.qpid.proton.amqp.transport.ErrorCondition; @@ -27,7 +35,7 @@ static Exception toException(ErrorCondition errorCondition) { } else if (errorCondition.getCondition() == ClientConstants.SERVER_BUSY_ERROR) { return new ServerBusyException(errorCondition.getDescription()); } else if (errorCondition.getCondition() == AmqpErrorCode.NotFound) { - return ExceptionUtil.distinguishNotFound(errorCondition.getDescription()); + return ExceptionUtil.distinguishNotFound(errorCondition.getDescription()); } else if (errorCondition.getCondition() == ClientConstants.ENTITY_DISABLED_ERROR) { return new IllegalEntityException(errorCondition.getDescription()); } else if (errorCondition.getCondition() == AmqpErrorCode.Stolen) { @@ -77,15 +85,15 @@ static Exception amqpResponseCodeToException(final int statusCode, final String return new EventHubException(true, String.format(ClientConstants.AMQP_REQUEST_FAILED_ERROR, statusCode, statusDescription)); } } - + static Exception distinguishNotFound(final String message) { Pattern p = Pattern.compile("The messaging entity .* could not be found"); Matcher m = p.matcher(message); - if (m.find()) { - return new IllegalEntityException(message); - } else { - return new EventHubException(true, String.format(ClientConstants.AMQP_REQUEST_FAILED_ERROR, AmqpResponseCode.NOT_FOUND, message)); - } + if (m.find()) { + return new IllegalEntityException(message); + } else { + return new EventHubException(true, String.format(ClientConstants.AMQP_REQUEST_FAILED_ERROR, AmqpResponseCode.NOT_FOUND, message)); + } } static void completeExceptionally(CompletableFuture future, Exception exception, ErrorContextProvider contextProvider) { @@ -154,7 +162,7 @@ public static Throwable getExceptionFromCompletedFuture( return null; } - static Exception stripOuterException(final Exception exception) { + static Exception stripOuterException(final Exception exception) { Throwable throwable = exception.getCause(); if (throwable instanceof EventHubException) { return (EventHubException) throwable; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/FaultTolerantObject.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/FaultTolerantObject.java index 3140af48cad5c..2b57c9c6c5557 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/FaultTolerantObject.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/FaultTolerantObject.java @@ -46,8 +46,8 @@ public void runOnOpenedObject( @Override public void onEvent() { if (!creatingNewInnerObject - && (innerObject == null || innerObject.getState() == IOObject.IOObjectState.CLOSED || - innerObject.getState() == IOObject.IOObjectState.CLOSING)) { + && (innerObject == null || innerObject.getState() == IOObject.IOObjectState.CLOSED + || innerObject.getState() == IOObject.IOObjectState.CLOSING)) { creatingNewInnerObject = true; try { diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageReceiver.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageReceiver.java index 473e70004554a..41f84f3bc8ea3 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageReceiver.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageReceiver.java @@ -14,7 +14,11 @@ import org.apache.qpid.proton.amqp.transport.ErrorCondition; import org.apache.qpid.proton.amqp.transport.ReceiverSettleMode; import org.apache.qpid.proton.amqp.transport.SenderSettleMode; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.Delivery; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Receiver; +import org.apache.qpid.proton.engine.Session; import org.apache.qpid.proton.message.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,7 +29,11 @@ import java.time.Duration; import java.time.Instant; import java.time.ZonedDateTime; -import java.util.*; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; @@ -647,19 +655,18 @@ public void run() { setClosed(); } } - } - , timeout.remaining()); + }, timeout.remaining()); this.openTimer.handleAsync( - (unUsed, exception) -> { - if (exception != null - && exception instanceof Exception - && !(exception instanceof CancellationException)) { - ExceptionUtil.completeExceptionally(linkOpen.getWork(), (Exception) exception, MessageReceiver.this); - } + (unUsed, exception) -> { + if (exception != null + && exception instanceof Exception + && !(exception instanceof CancellationException)) { + ExceptionUtil.completeExceptionally(linkOpen.getWork(), (Exception) exception, MessageReceiver.this); + } - return null; - }, this.executor); + return null; + }, this.executor); } private void scheduleLinkCloseTimeout(final TimeoutTracker timeout) { @@ -687,17 +694,16 @@ public void run() { MessageReceiver.this.onError((Exception) null); } } - } - , timeout.remaining()); + }, timeout.remaining()); this.closeTimer.handleAsync( - (unUsed, exception) -> { - if (exception != null && exception instanceof Exception && !(exception instanceof CancellationException)) { - ExceptionUtil.completeExceptionally(linkClose, (Exception) exception, MessageReceiver.this); - } + (unUsed, exception) -> { + if (exception != null && exception instanceof Exception && !(exception instanceof CancellationException)) { + ExceptionUtil.completeExceptionally(linkClose, (Exception) exception, MessageReceiver.this); + } - return null; - }, this.executor); + return null; + }, this.executor); } private boolean shouldScheduleOperationTimeoutTimer() { diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageSender.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageSender.java index 5350ef22a31c9..b34473d6eae49 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageSender.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessageSender.java @@ -3,15 +3,30 @@ package com.microsoft.azure.eventhubs.impl; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.ErrorContext; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.OperationCancelledException; +import com.microsoft.azure.eventhubs.PayloadSizeExceededException; +import com.microsoft.azure.eventhubs.RetryPolicy; +import com.microsoft.azure.eventhubs.ServerBusyException; +import com.microsoft.azure.eventhubs.TimeoutException; import org.apache.qpid.proton.Proton; import org.apache.qpid.proton.amqp.Binary; import org.apache.qpid.proton.amqp.UnsignedLong; -import org.apache.qpid.proton.amqp.messaging.*; +import org.apache.qpid.proton.amqp.messaging.Accepted; +import org.apache.qpid.proton.amqp.messaging.Data; +import org.apache.qpid.proton.amqp.messaging.Rejected; +import org.apache.qpid.proton.amqp.messaging.Released; +import org.apache.qpid.proton.amqp.messaging.Source; +import org.apache.qpid.proton.amqp.messaging.Target; import org.apache.qpid.proton.amqp.transport.DeliveryState; import org.apache.qpid.proton.amqp.transport.ErrorCondition; import org.apache.qpid.proton.amqp.transport.SenderSettleMode; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.Delivery; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Sender; +import org.apache.qpid.proton.engine.Session; import org.apache.qpid.proton.engine.impl.DeliveryImpl; import org.apache.qpid.proton.message.Message; import org.slf4j.Logger; @@ -24,7 +39,14 @@ import java.time.Duration; import java.time.Instant; import java.time.ZonedDateTime; -import java.util.*; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; @@ -178,9 +200,9 @@ private CompletableFuture sendCore( final CompletableFuture onSendFuture = (onSend == null) ? new CompletableFuture<>() : onSend; - final ReplayableWorkItem sendWaiterData = (tracker == null) ? - new ReplayableWorkItem<>(bytes, arrayOffset, messageFormat, onSendFuture, this.operationTimeout) : - new ReplayableWorkItem<>(bytes, arrayOffset, messageFormat, onSendFuture, tracker); + final ReplayableWorkItem sendWaiterData = (tracker == null) + ? new ReplayableWorkItem<>(bytes, arrayOffset, messageFormat, onSendFuture, this.operationTimeout) + : new ReplayableWorkItem<>(bytes, arrayOffset, messageFormat, onSendFuture, tracker); final TimeoutTracker currentSendTracker = sendWaiterData.getTimeoutTracker(); final String deliveryTag = UUID.randomUUID().toString().replace("-", StringUtil.EMPTY) + "_" + currentSendTracker.elapsed().getSeconds(); @@ -199,15 +221,15 @@ private CompletableFuture sendCore( // if the timeoutTask completed with scheduling error - notify sender if (timeoutTimerTask.isCompletedExceptionally()) { timeoutTimerTask.handleAsync( - (unUsed, exception) -> { - if (exception != null && !(exception instanceof CancellationException)) - onSendFuture.completeExceptionally( - new OperationCancelledException(String.format(Locale.US, - "Entity(%s): send failed while dispatching to Reactor, see cause for more details.", - this.sendPath), exception)); + (unUsed, exception) -> { + if (exception != null && !(exception instanceof CancellationException)) + onSendFuture.completeExceptionally( + new OperationCancelledException(String.format(Locale.US, + "Entity(%s): send failed while dispatching to Reactor, see cause for more details.", + this.sendPath), exception)); - return null; - }, this.executor); + return null; + }, this.executor); return onSendFuture; } @@ -717,19 +739,18 @@ public void run() { setClosed(); } } - } - , timeout.remaining()); + }, timeout.remaining()); this.openTimer.handleAsync( - (unUsed, exception) -> { - if (exception != null - && exception instanceof Exception - && !(exception instanceof CancellationException)) { - ExceptionUtil.completeExceptionally(linkFirstOpen, (Exception) exception, this); - } + (unUsed, exception) -> { + if (exception != null + && exception instanceof Exception + && !(exception instanceof CancellationException)) { + ExceptionUtil.completeExceptionally(linkFirstOpen, (Exception) exception, this); + } - return null; - }, this.executor); + return null; + }, this.executor); } @Override @@ -912,17 +933,16 @@ public void run() { MessageSender.this.onError((Exception) null); } } - } - , timeout.remaining()); + }, timeout.remaining()); this.closeTimer.handleAsync( - (unUsed, exception) -> { - if (exception != null && exception instanceof Exception && !(exception instanceof CancellationException)) { - ExceptionUtil.completeExceptionally(linkClose, (Exception) exception, MessageSender.this); - } + (unUsed, exception) -> { + if (exception != null && exception instanceof Exception && !(exception instanceof CancellationException)) { + ExceptionUtil.completeExceptionally(linkClose, (Exception) exception, MessageSender.this); + } - return null; - }, this.executor); + return null; + }, this.executor); } @Override diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessagingFactory.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessagingFactory.java index ded7245e6e4c5..a737b4bdbd61f 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessagingFactory.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/MessagingFactory.java @@ -4,10 +4,21 @@ package com.microsoft.azure.eventhubs.impl; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.CommunicationException; +import com.microsoft.azure.eventhubs.ConnectionStringBuilder; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.OperationCancelledException; +import com.microsoft.azure.eventhubs.RetryPolicy; import com.microsoft.azure.eventhubs.TimeoutException; import org.apache.qpid.proton.amqp.transport.ErrorCondition; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.Connection; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Event; +import org.apache.qpid.proton.engine.Handler; +import org.apache.qpid.proton.engine.HandlerException; +import org.apache.qpid.proton.engine.Link; +import org.apache.qpid.proton.engine.Session; import org.apache.qpid.proton.reactor.Reactor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,7 +30,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.concurrent.*; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -114,14 +129,14 @@ public void run() { // if scheduling messagingfactory openTimer fails - notify user and stop messagingFactory.openTimer.handleAsync( - (unUsed, exception) -> { - if (exception != null && !(exception instanceof CancellationException)) { - messagingFactory.open.completeExceptionally(exception); - messagingFactory.getReactor().stop(); - } + (unUsed, exception) -> { + if (exception != null && !(exception instanceof CancellationException)) { + messagingFactory.open.completeExceptionally(exception); + messagingFactory.getReactor().stop(); + } - return null; - }, messagingFactory.executor); + return null; + }, messagingFactory.executor); return messagingFactory.open; } @@ -324,7 +339,7 @@ private void onReactorError(Exception cause) { this.getClientId(), this.getHostName(), ExceptionUtil.toStackTraceString(e, "Re-starting reactor failed with error"))); - // TODO - stop retrying on the error after multiple attempts. + // TODO: stop retrying on the error after multiple attempts. this.onReactorError(cause); } @@ -355,15 +370,14 @@ protected CompletableFuture onClose() { if (!this.getIsClosed()) { final Timer timer = new Timer(this); this.closeTimer = timer.schedule(new Runnable() { - @Override - public void run() { - if (!closeTask.isDone()) { - closeTask.completeExceptionally(new TimeoutException("Closing MessagingFactory timed out.")); - getReactor().stop(); - } - } - }, - operationTimeout); + @Override + public void run() { + if (!closeTask.isDone()) { + closeTask.completeExceptionally(new TimeoutException("Closing MessagingFactory timed out.")); + getReactor().stop(); + } + } + }, operationTimeout); if (this.closeTimer.isCompletedExceptionally()) { this.closeTask.completeExceptionally(ExceptionUtil.getExceptionFromCompletedFuture(this.closeTimer)); @@ -468,8 +482,8 @@ public void onError(Exception error) { } private class RunReactor implements Runnable { - final private Reactor rctr; - final private ScheduledExecutorService executor; + private final Reactor rctr; + private final ScheduledExecutorService executor; volatile boolean hasStarted; @@ -529,11 +543,11 @@ public void run() { "Unhandled exception while processing events in reactor, report this error."))); } - final String message = !StringUtil.isNullOrEmpty(cause.getMessage()) ? - cause.getMessage() : - !StringUtil.isNullOrEmpty(handlerException.getMessage()) ? - handlerException.getMessage() : - "Reactor encountered unrecoverable error"; + final String message = !StringUtil.isNullOrEmpty(cause.getMessage()) + ? cause.getMessage() + : !StringUtil.isNullOrEmpty(handlerException.getMessage()) + ? handlerException.getMessage() + : "Reactor encountered unrecoverable error"; final EventHubException sbException; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionReceiverImpl.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionReceiverImpl.java index 8e6d73029217d..51e0452de82be 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionReceiverImpl.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionReceiverImpl.java @@ -3,7 +3,12 @@ package com.microsoft.azure.eventhubs.impl; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.EventData; +import com.microsoft.azure.eventhubs.EventPosition; +import com.microsoft.azure.eventhubs.PartitionReceiveHandler; +import com.microsoft.azure.eventhubs.PartitionReceiver; +import com.microsoft.azure.eventhubs.ReceiverOptions; +import com.microsoft.azure.eventhubs.ReceiverRuntimeInformation; import org.apache.qpid.proton.amqp.Symbol; import org.apache.qpid.proton.amqp.UnknownDescribedType; import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations; @@ -12,7 +17,11 @@ import org.slf4j.LoggerFactory; import java.time.Duration; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; import java.util.function.Consumer; @@ -247,8 +256,8 @@ public Map getFilter(final Message lastReceivedMes @Override public Map getProperties() { - if (!this.isEpochReceiver && - (this.receiverOptions == null || this.receiverOptions.getIdentifier() == null)) { + if (!this.isEpochReceiver + && (this.receiverOptions == null || this.receiverOptions.getIdentifier() == null)) { return null; } @@ -272,4 +281,4 @@ public Symbol[] getDesiredCapabilities() { ? new Symbol[]{AmqpConstants.ENABLE_RECEIVER_RUNTIME_METRIC_NAME} : null; } -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionSenderImpl.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionSenderImpl.java index 20ec9cd874599..39e3a37c37ea6 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionSenderImpl.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/PartitionSenderImpl.java @@ -3,7 +3,11 @@ package com.microsoft.azure.eventhubs.impl; -import com.microsoft.azure.eventhubs.*; +import com.microsoft.azure.eventhubs.BatchOptions; +import com.microsoft.azure.eventhubs.EventData; +import com.microsoft.azure.eventhubs.EventDataBatch; +import com.microsoft.azure.eventhubs.EventHubException; +import com.microsoft.azure.eventhubs.PartitionSender; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ScheduledExecutorService; @@ -54,8 +58,8 @@ public String getPartitionId() { public EventDataBatch createBatch(BatchOptions options) { if (!StringUtil.isNullOrEmpty(options.partitionKey)) { - throw new IllegalArgumentException("A partition key cannot be set when using PartitionSenderImpl. If you'd like to " + - "continue using PartitionSenderImpl with EventDataBatches, then please do not set a partition key in your BatchOptions."); + throw new IllegalArgumentException("A partition key cannot be set when using PartitionSenderImpl. If you'd like to " + + "continue using PartitionSenderImpl with EventDataBatches, then please do not set a partition key in your BatchOptions."); } int maxSize = this.internalSender.getMaxMessageSize(); @@ -65,8 +69,8 @@ public EventDataBatch createBatch(BatchOptions options) { } if (options.maxMessageSize > maxSize) { - throw new IllegalArgumentException("The maxMessageSize set in BatchOptions is too large. You set a maxMessageSize of " + - options.maxMessageSize + ". The maximum allowed size is " + maxSize + "."); + throw new IllegalArgumentException("The maxMessageSize set in BatchOptions is too large. You set a maxMessageSize of " + + options.maxMessageSize + ". The maximum allowed size is " + maxSize + "."); } return new EventDataBatchImpl(options.maxMessageSize, null); @@ -90,8 +94,8 @@ public final CompletableFuture send(EventDataBatch eventDatas) { } if (!StringUtil.isNullOrEmpty(((EventDataBatchImpl) eventDatas).getPartitionKey())) { - throw new IllegalArgumentException("A partition key cannot be set when using PartitionSenderImpl. If you'd like to " + - "continue using PartitionSenderImpl with EventDataBatches, then please do not set a partition key in your BatchOptions"); + throw new IllegalArgumentException("A partition key cannot be set when using PartitionSenderImpl. If you'd like to " + + "continue using PartitionSenderImpl with EventDataBatches, then please do not set a partition key in your BatchOptions"); } return this.internalSender.send(EventDataUtil.toAmqpMessages(((EventDataBatchImpl) eventDatas).getInternalIterable())); diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiveLinkHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiveLinkHandler.java index ce40fec488bbd..e3d56bdd09e58 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiveLinkHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiveLinkHandler.java @@ -59,8 +59,8 @@ public void onLinkRemoteOpen(Event event) { } else { if (TRACE_LOGGER.isInfoEnabled()) { TRACE_LOGGER.info( - String.format(Locale.US, "onLinkRemoteOpen linkName[%s], remoteTarget[null], " + - "remoteSource[null], action[waitingForError]", receiver.getName())); + String.format(Locale.US, "onLinkRemoteOpen linkName[%s], remoteTarget[null], " + + "remoteSource[null], action[waitingForError]", receiver.getName())); } } } @@ -90,8 +90,8 @@ public void onDelivery(Event event) { if (TRACE_LOGGER.isWarnEnabled()) { TRACE_LOGGER.warn( receiveLink != null - ? String.format(Locale.US, "onDelivery linkName[%s], updatedLinkCredit[%s], remoteCredit[%s], " + - "remoteCondition[%s], delivery.isSettled[%s]", + ? String.format(Locale.US, "onDelivery linkName[%s], updatedLinkCredit[%s], remoteCredit[%s], " + + "remoteCondition[%s], delivery.isSettled[%s]", receiveLink.getName(), receiveLink.getCredit(), receiveLink.getRemoteCredit(), receiveLink.getRemoteCondition(), delivery.isSettled()) : String.format(Locale.US, "delivery.isSettled[%s]", delivery.isSettled())); } @@ -102,8 +102,8 @@ public void onDelivery(Event event) { if (TRACE_LOGGER.isTraceEnabled() && receiveLink != null) { TRACE_LOGGER.trace( - String.format(Locale.US, "onDelivery linkName[%s], updatedLinkCredit[%s], remoteCredit[%s], " + - "remoteCondition[%s], delivery.isPartial[%s]", + String.format(Locale.US, "onDelivery linkName[%s], updatedLinkCredit[%s], remoteCredit[%s], " + + "remoteCondition[%s], delivery.isPartial[%s]", receiveLink.getName(), receiveLink.getCredit(), receiveLink.getRemoteCredit(), receiveLink.getRemoteCondition(), delivery.isPartial())); } } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceivePump.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceivePump.java index 7711b4a5a12c4..c3f60cb519a7e 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceivePump.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceivePump.java @@ -55,8 +55,8 @@ public void run() { } catch (final Exception exception) { if (TRACE_LOGGER.isErrorEnabled()) { TRACE_LOGGER.error( - String.format("Receive pump for eventHub (%s), consumerGroup (%s), partition (%s) " + - "encountered unrecoverable error and exited with exception %s.", + String.format("Receive pump for eventHub (%s), consumerGroup (%s), partition (%s) " + + "encountered unrecoverable error and exited with exception %s.", this.eventHubName, this.consumerGroupName, this.receiver.getPartitionId(), exception.toString())); } @@ -111,8 +111,8 @@ private void handleUserCodeExceptions(final Throwable userCodeException) { this.isPumpHealthy = false; if (TRACE_LOGGER.isErrorEnabled()) { TRACE_LOGGER.error( - String.format("Receive pump for eventHub (%s), consumerGroup (%s), partition (%s) " + - "exiting after user-code exception %s", + String.format("Receive pump for eventHub (%s), consumerGroup (%s), partition (%s) " + + "exiting after user-code exception %s", this.eventHubName, this.consumerGroupName, this.receiver.getPartitionId(), userCodeException.toString())); } @@ -160,8 +160,8 @@ public Void apply(final Iterable receivedEvents, final Throwable clie try { // don't invoke user call back - if stop is already raised / pump is unhealthy - if (ReceivePump.this.shouldContinue() && - (receivedEvents != null + if (ReceivePump.this.shouldContinue() + && (receivedEvents != null || (receivedEvents == null && ReceivePump.this.invokeOnTimeout))) { ReceivePump.this.onReceiveHandler.onReceive(receivedEvents); } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiverContext.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiverContext.java index db68225fc60a5..ee6b45052dcf8 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiverContext.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/ReceiverContext.java @@ -8,8 +8,8 @@ import java.util.Locale; public class ReceiverContext extends ErrorContext { - final static boolean EPOCH_RECEIVER_TYPE = true; - final static boolean NON_EPOCH_RECEIVER_TYPE = !ReceiverContext.EPOCH_RECEIVER_TYPE; + static final boolean EPOCH_RECEIVER_TYPE = true; + static final boolean NON_EPOCH_RECEIVER_TYPE = !ReceiverContext.EPOCH_RECEIVER_TYPE; final String receivePath; final String referenceId; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/RequestResponseChannel.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/RequestResponseChannel.java index 2d7ceca5c2387..5300d7775ad34 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/RequestResponseChannel.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/RequestResponseChannel.java @@ -11,7 +11,12 @@ import org.apache.qpid.proton.amqp.transport.ErrorCondition; import org.apache.qpid.proton.amqp.transport.ReceiverSettleMode; import org.apache.qpid.proton.amqp.transport.SenderSettleMode; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.Delivery; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Receiver; +import org.apache.qpid.proton.engine.Sender; +import org.apache.qpid.proton.engine.Session; import org.apache.qpid.proton.message.Message; import java.util.HashMap; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SendLinkHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SendLinkHandler.java index 7df9cfd2b0cc7..620363dab961b 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SendLinkHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SendLinkHandler.java @@ -69,9 +69,9 @@ public void onDelivery(Event event) { if (TRACE_LOGGER.isTraceEnabled()) { TRACE_LOGGER.trace( - "onDelivery linkName[" + sender.getName() + - "], unsettled[" + sender.getUnsettled() + "], credit[" + sender.getRemoteCredit() + "], deliveryState[" + delivery.getRemoteState() + - "], delivery.isBuffered[" + delivery.isBuffered() + "], delivery.id[" + new String(delivery.getTag()) + "]"); + "onDelivery linkName[" + sender.getName() + + "], unsettled[" + sender.getUnsettled() + "], credit[" + sender.getRemoteCredit() + "], deliveryState[" + delivery.getRemoteState() + + "], delivery.isBuffered[" + delivery.isBuffered() + "], delivery.id[" + new String(delivery.getTag()) + "]"); } msgSender.onSendComplete(delivery); diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionHandler.java index 869feffdb23a9..f57455fcc4710 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionHandler.java @@ -5,7 +5,11 @@ import com.microsoft.azure.eventhubs.EventHubException; import org.apache.qpid.proton.amqp.transport.ErrorCondition; -import org.apache.qpid.proton.engine.*; +import org.apache.qpid.proton.engine.BaseHandler; +import org.apache.qpid.proton.engine.EndpointState; +import org.apache.qpid.proton.engine.Event; +import org.apache.qpid.proton.engine.Handler; +import org.apache.qpid.proton.engine.Session; import org.apache.qpid.proton.reactor.Reactor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionProvider.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionProvider.java index 5dcf60ba464e3..afc87d4ba1391 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionProvider.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/SessionProvider.java @@ -14,4 +14,4 @@ Session getSession( final String path, final Consumer onSessionOpen, final BiConsumer onSessionOpenError); -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/StringUtil.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/StringUtil.java index 6168960476e70..0c0b1ac57af01 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/StringUtil.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/StringUtil.java @@ -6,7 +6,7 @@ import java.util.UUID; public final class StringUtil { - public final static String EMPTY = ""; + public static final String EMPTY = ""; public static boolean isNullOrEmpty(String string) { return (string == null || string.isEmpty()); diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TimeoutTracker.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TimeoutTracker.java index 74e43b7deafb1..8a52e6bc28832 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TimeoutTracker.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TimeoutTracker.java @@ -3,7 +3,9 @@ package com.microsoft.azure.eventhubs.impl; -import java.time.*; + +import java.time.Duration; +import java.time.Instant; public class TimeoutTracker { private final Duration originalTimeout; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/Timer.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/Timer.java index b7365e651f870..00f011c7e675e 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/Timer.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/Timer.java @@ -31,7 +31,7 @@ public CompletableFuture schedule( return taskHandle; } - final static class ScheduledTask extends DispatchHandler { + static final class ScheduledTask extends DispatchHandler { final CompletableFuture scheduledFuture; final Runnable runnable; diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TrackingUtil.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TrackingUtil.java index fd0c6f5a51692..74cde83b1ff42 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TrackingUtil.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/TrackingUtil.java @@ -29,10 +29,10 @@ static String parseRoleIdentifier(final String trackingId) { public static String getLinkName(final Session session) { // returned linkName lookslike: ea9cac_8b_G27_1479943074829 final String linkNamePrefix = StringUtil.getRandomString(); - final String linkNameWithServiceRoleTracker = session.getConnection() != null && !StringUtil.isNullOrEmpty(session.getConnection().getRemoteContainer()) ? - linkNamePrefix.concat(TrackingUtil.TRACKING_ID_TOKEN_SEPARATOR).concat(session.getConnection().getRemoteContainer() - .substring(Math.max(session.getConnection().getRemoteContainer().length() - 7, 0), session.getConnection().getRemoteContainer().length())) : - linkNamePrefix; + final String linkNameWithServiceRoleTracker = session.getConnection() != null && !StringUtil.isNullOrEmpty(session.getConnection().getRemoteContainer()) + ? linkNamePrefix.concat(TrackingUtil.TRACKING_ID_TOKEN_SEPARATOR).concat(session.getConnection().getRemoteContainer() + .substring(Math.max(session.getConnection().getRemoteContainer().length() - 7, 0), session.getConnection().getRemoteContainer().length())) + : linkNamePrefix; return linkNameWithServiceRoleTracker.concat(TrackingUtil.TRACKING_ID_TOKEN_SEPARATOR).concat(String.valueOf(Instant.now().toEpochMilli())); } } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketConnectionHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketConnectionHandler.java index 63c4d55dd5588..5c97f42b71b2c 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketConnectionHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketConnectionHandler.java @@ -33,7 +33,7 @@ protected void addTransportLayers(final Event event, final TransportInternal tra transport.addTransportLayer(webSocket); if (TRACE_LOGGER.isInfoEnabled()) { - TRACE_LOGGER.info("addWebsocketHandshake: hostname[" + hostName +"]"); + TRACE_LOGGER.info("addWebsocketHandshake: hostname[" + hostName + "]"); } super.addTransportLayers(event, transport); diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketProxyConnectionHandler.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketProxyConnectionHandler.java index 0cfdd427ff080..9974ac05da869 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketProxyConnectionHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WebSocketProxyConnectionHandler.java @@ -63,7 +63,7 @@ protected void addTransportLayers(final Event event, final TransportInternal tra transport.addTransportLayer(proxy); if (TRACE_LOGGER.isInfoEnabled()) { - TRACE_LOGGER.info("addProxyHandshake: hostname[" + hostName +"]"); + TRACE_LOGGER.info("addProxyHandshake: hostname[" + hostName + "]"); } } @@ -95,7 +95,7 @@ protected void notifyTransportErrors(final Event event) { int port; try { port = Integer.parseInt(hostNameParts[1]); - } catch (NumberFormatException ignore){ + } catch (NumberFormatException ignore) { return; } diff --git a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WorkItem.java b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WorkItem.java index e65513703afe2..af00d91ae7e14 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WorkItem.java +++ b/eventhubs/data-plane/azure-eventhubs/src/main/java/com/microsoft/azure/eventhubs/impl/WorkItem.java @@ -3,8 +3,8 @@ package com.microsoft.azure.eventhubs.impl; -import java.time.*; -import java.util.concurrent.*; +import java.time.Duration; +import java.util.concurrent.CompletableFuture; public class WorkItem { private final TimeoutTracker tracker; diff --git a/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyNegotiationHandler.java b/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyNegotiationHandler.java index c4001c165975d..14543dd5a60cc 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyNegotiationHandler.java +++ b/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyNegotiationHandler.java @@ -241,4 +241,4 @@ public void failed(Throwable exc, ReadWriteState attachment) { } } } -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyServer.java b/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyServer.java index 40cbfbddf5543..e8795445fc59d 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyServer.java +++ b/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/ProxyServer.java @@ -15,4 +15,4 @@ static ProxyServer create(final String hostName, final int port) { void start(final Consumer onError) throws IOException; void stop() throws IOException; -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/SimpleProxy.java b/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/SimpleProxy.java index 320130fcc53ea..396955d89ccea 100644 --- a/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/SimpleProxy.java +++ b/eventhubs/data-plane/azure-eventhubs/src/test/java/com/microsoft/azure/eventhubs/jproxy/SimpleProxy.java @@ -85,4 +85,4 @@ public void failed(Throwable exc, AsynchronousServerSocketChannel attachment) { } }); } -} \ No newline at end of file +} diff --git a/eventhubs/data-plane/pom.xml b/eventhubs/data-plane/pom.xml index 2f0276ce8eff8..f2d254e1811b0 100644 --- a/eventhubs/data-plane/pom.xml +++ b/eventhubs/data-plane/pom.xml @@ -32,11 +32,6 @@ scm:git:https://github.com/Azure/azure-sdk-for-java - - 0.31.0 - 1.1.0 - - org.apache.qpid