com.microsoft.azure.eventhubs.impl.EventHubClientImpl Maven / Gradle / Ivy
/*
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
package com.microsoft.azure.eventhubs.impl;
import com.microsoft.azure.eventhubs.*;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
public final class EventHubClientImpl extends ClientEntity implements EventHubClient {
/**
* It will be truncated to 128 characters
*/
public static String USER_AGENT = null;
private final String eventHubName;
private final Object senderCreateSync;
private volatile boolean isSenderCreateStarted;
private volatile MessagingFactory underlyingFactory;
private volatile MessageSender sender;
private volatile Timer timer;
private CompletableFuture createSender;
private EventHubClientImpl(final ConnectionStringBuilder connectionString, final Executor executor) throws IOException, IllegalEntityException {
super(StringUtil.getRandomString(), null, executor);
this.eventHubName = connectionString.getEventHubName();
this.senderCreateSync = new Object();
}
public static CompletableFuture create(
final String connectionString, final RetryPolicy retryPolicy, final Executor executor)
throws EventHubException, IOException {
final ConnectionStringBuilder connStr = new ConnectionStringBuilder(connectionString);
final EventHubClientImpl eventHubClient = new EventHubClientImpl(connStr, executor);
return MessagingFactory.createFromConnectionString(connectionString.toString(), retryPolicy, executor)
.thenApplyAsync(new Function() {
@Override
public EventHubClient apply(MessagingFactory factory) {
eventHubClient.underlyingFactory = factory;
eventHubClient.timer = new Timer(factory);
return eventHubClient;
}
}, executor);
}
public String getEventHubName() {
return eventHubName;
}
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 + ".");
}
return new EventDataBatchImpl(options.maxMessageSize, options.partitionKey);
}
);
}
@Override
public final CompletableFuture send(final EventData data) {
if (data == null) {
throw new IllegalArgumentException("EventData cannot be empty.");
}
return this.createInternalSender().thenComposeAsync(new Function>() {
@Override
public CompletableFuture apply(Void voidArg) {
return EventHubClientImpl.this.sender.send(((EventDataImpl) data).toAmqpMessage());
}
}, this.executor);
}
@Override
public final CompletableFuture send(final Iterable eventDatas) {
if (eventDatas == null || IteratorUtil.sizeEquals(eventDatas, 0)) {
throw new IllegalArgumentException("Empty batch of EventData cannot be sent.");
}
return this.createInternalSender().thenComposeAsync(new Function>() {
@Override
public CompletableFuture apply(Void voidArg) {
return EventHubClientImpl.this.sender.send(EventDataUtil.toAmqpMessages(eventDatas));
}
}, this.executor);
}
@Override
public final CompletableFuture send(final EventDataBatch eventDatas) {
if (eventDatas == null || Integer.compare(eventDatas.getSize(), 0) == 0) {
throw new IllegalArgumentException("Empty batch of EventData cannot be sent.");
}
final EventDataBatchImpl eventDataBatch = (EventDataBatchImpl) eventDatas;
return eventDataBatch.getPartitionKey() != null ?
this.send(eventDataBatch.getInternalIterable(), eventDataBatch.getPartitionKey()) :
this.send(eventDataBatch.getInternalIterable());
}
@Override
public final CompletableFuture send(final EventData eventData, final String partitionKey) {
if (eventData == null) {
throw new IllegalArgumentException("EventData cannot be null.");
}
if (partitionKey == null) {
throw new IllegalArgumentException("partitionKey cannot be null");
}
return this.createInternalSender().thenComposeAsync(new Function>() {
@Override
public CompletableFuture apply(Void voidArg) {
return EventHubClientImpl.this.sender.send(((EventDataImpl) eventData).toAmqpMessage(partitionKey));
}
}, this.executor);
}
@Override
public final CompletableFuture send(final Iterable eventDatas, final String partitionKey) {
if (eventDatas == null || IteratorUtil.sizeEquals(eventDatas, 0)) {
throw new IllegalArgumentException("Empty batch of EventData cannot be sent.");
}
if (partitionKey == null) {
throw new IllegalArgumentException("partitionKey cannot be null");
}
if (partitionKey.length() > ClientConstants.MAX_PARTITION_KEY_LENGTH) {
throw new IllegalArgumentException(
String.format(Locale.US, "PartitionKey exceeds the maximum allowed length of partitionKey: %s", ClientConstants.MAX_PARTITION_KEY_LENGTH));
}
return this.createInternalSender().thenComposeAsync(new Function>() {
@Override
public CompletableFuture apply(Void voidArg) {
return EventHubClientImpl.this.sender.send(EventDataUtil.toAmqpMessages(eventDatas, partitionKey));
}
}, this.executor);
}
@Override
public final CompletableFuture createPartitionSender(final String partitionId)
throws EventHubException {
return PartitionSenderImpl.Create(this.underlyingFactory, this.eventHubName, partitionId, this.executor);
}
@Override
public final CompletableFuture createReceiver(final String consumerGroupName, final String partitionId, final EventPosition eventPosition)
throws EventHubException {
return this.createReceiver(consumerGroupName, partitionId, eventPosition, null);
}
@Override
public final CompletableFuture createReceiver(final String consumerGroupName, final String partitionId, final EventPosition eventPosition, final ReceiverOptions receiverOptions)
throws EventHubException {
return PartitionReceiverImpl.create(this.underlyingFactory, this.eventHubName, consumerGroupName, partitionId, eventPosition, PartitionReceiverImpl.NULL_EPOCH, false, receiverOptions, this.executor);
}
@Override
public final CompletableFuture createEpochReceiver(final String consumerGroupName, final String partitionId, final EventPosition eventPosition, final long epoch)
throws EventHubException {
return this.createEpochReceiver(consumerGroupName, partitionId, eventPosition, epoch, null);
}
@Override
public final CompletableFuture createEpochReceiver(final String consumerGroupName, final String partitionId, final EventPosition eventPosition, final long epoch, final ReceiverOptions receiverOptions)
throws EventHubException {
return PartitionReceiverImpl.create(this.underlyingFactory, this.eventHubName, consumerGroupName, partitionId, eventPosition, epoch, true, receiverOptions, this.executor);
}
@Override
public CompletableFuture onClose() {
if (this.underlyingFactory != null) {
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)
: this.underlyingFactory.close();
return internalSenderClose;
}
}
return CompletableFuture.completedFuture(null);
}
private CompletableFuture createInternalSender() {
if (!this.isSenderCreateStarted) {
synchronized (this.senderCreateSync) {
if (!this.isSenderCreateStarted) {
this.createSender = MessageSender.create(this.underlyingFactory, StringUtil.getRandomString(), this.eventHubName)
.thenAcceptAsync(new Consumer() {
public void accept(MessageSender a) {
EventHubClientImpl.this.sender = a;
}
}, this.executor);
this.isSenderCreateStarted = true;
}
}
}
return this.createSender;
}
@Override
public CompletableFuture getRuntimeInformation() {
CompletableFuture future1 = null;
throwIfClosed();
Map request = new HashMap();
request.put(ClientConstants.MANAGEMENT_ENTITY_TYPE_KEY, ClientConstants.MANAGEMENT_EVENTHUB_ENTITY_TYPE);
request.put(ClientConstants.MANAGEMENT_ENTITY_NAME_KEY, this.eventHubName);
request.put(ClientConstants.MANAGEMENT_OPERATION_KEY, ClientConstants.READ_OPERATION_VALUE);
future1 = this.addManagementToken(request);
if (future1 == null) {
future1 = managementWithRetry(request).thenComposeAsync(new Function
© 2015 - 2025 Weber Informatics LLC | Privacy Policy