From 3851f19a9c46bc4ee0c7b01e955e3274097ce23f Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 12:45:50 -0800
Subject: [PATCH 01/29] AmqpConnection implements AutoCloseable. Add
getEndpointStates().
---
.../com/azure/core/amqp/AmqpConnection.java | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
index ef8e7a89705d..164d14b5c277 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
@@ -3,15 +3,24 @@
package com.azure.core.amqp;
+import com.azure.core.amqp.exception.AmqpException;
+import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.io.Closeable;
import java.util.Map;
/**
* Represents a TCP connection between the client and a service that uses the AMQP protocol.
*/
-public interface AmqpConnection extends EndpointStateNotifier, Closeable {
+public interface AmqpConnection extends AutoCloseable {
+ /**
+ * Gets the endpoint states for the AMQP connection. {@link AmqpException AmqpExceptions} that occur on the link are
+ * reported in the connection state. When the stream terminates, the connection is closed.
+ *
+ * @return A stream of endpoint states for the AMQP connection.
+ */
+ Flux getEndpointStates();
+
/**
* Gets the connection identifier.
*
@@ -62,4 +71,10 @@ public interface AmqpConnection extends EndpointStateNotifier, Closeable {
* @return {@code true} if a session with the name was removed; {@code false} otherwise.
*/
boolean removeSession(String sessionName);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ void close();
}
From 0c6c6a939ebc2ad4eae67aa18eaf1e7260dd103f Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 12:47:47 -0800
Subject: [PATCH 02/29] AmqpConnection/Link/Session. implements AutoCloseable.
Add getEndpointStates().
---
.../com/azure/core/amqp/AmqpConnection.java | 2 +-
.../java/com/azure/core/amqp/AmqpLink.java | 19 +++++++++++++++++--
.../java/com/azure/core/amqp/AmqpSession.java | 19 +++++++++++++++++--
3 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
index 164d14b5c277..eaa5c64b8da2 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
@@ -73,7 +73,7 @@ public interface AmqpConnection extends AutoCloseable {
boolean removeSession(String sessionName);
/**
- * {@inheritDoc}
+ * Closes the AMQP connection.
*/
@Override
void close();
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java
index b1387c7adc92..04d9adbbf622 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java
@@ -3,12 +3,21 @@
package com.azure.core.amqp;
-import java.io.Closeable;
+import com.azure.core.amqp.exception.AmqpException;
+import reactor.core.publisher.Flux;
/**
* Represents a unidirectional AMQP link.
*/
-public interface AmqpLink extends EndpointStateNotifier, Closeable {
+public interface AmqpLink extends AutoCloseable {
+ /**
+ * Gets the endpoint states for the AMQP link. {@link AmqpException AmqpExceptions} that occur on the link are
+ * reported in the connection state. When the stream terminates, the link is closed.
+ *
+ * @return A stream of endpoint states for the AMQP link.
+ */
+ Flux getEndpointStates();
+
/**
* Gets the name of the link.
*
@@ -29,4 +38,10 @@ public interface AmqpLink extends EndpointStateNotifier, Closeable {
* @return The host name of the message broker that this link that is connected to.
*/
String getHostname();
+
+ /**
+ * Closes the AMQP link.
+ */
+ @Override
+ void close();
}
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java
index c5cd8fefd7f2..dc49bbc86fd5 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java
@@ -3,15 +3,24 @@
package com.azure.core.amqp;
+import com.azure.core.amqp.exception.AmqpException;
+import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.io.Closeable;
import java.time.Duration;
/**
* An AMQP session representing bidirectional communication that supports multiple {@link AmqpLink AMQP links}.
*/
-public interface AmqpSession extends EndpointStateNotifier, Closeable {
+public interface AmqpSession extends AutoCloseable {
+ /**
+ * Gets the endpoint states for the AMQP session. {@link AmqpException AmqpExceptions} that occur on the link are
+ * reported in the connection state. When the stream terminates, the session is closed.
+ *
+ * @return A stream of endpoint states for the AMQP session.
+ */
+ Flux getEndpointStates();
+
/**
* Gets the name for this AMQP session.
*
@@ -55,4 +64,10 @@ public interface AmqpSession extends EndpointStateNotifier, Closeable {
* @return {@code true} if the link was removed; {@code false} otherwise.
*/
boolean removeLink(String linkName);
+
+ /**
+ * Closes the AMQP session.
+ */
+ @Override
+ void close();
}
From 278ae19cd650a95edc92e0dad6874ba55c15bb5f Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 12:51:13 -0800
Subject: [PATCH 03/29] CBSNode implements AutoCloseable.
---
.../com/azure/core/amqp/ClaimsBasedSecurityNode.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/ClaimsBasedSecurityNode.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/ClaimsBasedSecurityNode.java
index 2b97bf066b59..218f379a6509 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/ClaimsBasedSecurityNode.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/ClaimsBasedSecurityNode.java
@@ -6,7 +6,6 @@
import com.azure.core.credential.TokenCredential;
import reactor.core.publisher.Mono;
-import java.io.Closeable;
import java.time.OffsetDateTime;
/**
@@ -15,7 +14,7 @@
* @see
* AMPQ Claims-based Security v1.0
*/
-public interface ClaimsBasedSecurityNode extends EndpointStateNotifier, Closeable {
+public interface ClaimsBasedSecurityNode extends AutoCloseable {
/**
* Authorizes the caller with the CBS node to access resources for the {@code audience}.
*
@@ -26,4 +25,10 @@ public interface ClaimsBasedSecurityNode extends EndpointStateNotifier, Closeabl
* CBS node.
*/
Mono authorize(String audience, String scopes);
+
+ /**
+ * Closes session to the claims-based security node.
+ */
+ @Override
+ void close();
}
From d299eb3d9cb8a55b7209f068d0bb27ce84a0a35e Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 12:53:27 -0800
Subject: [PATCH 04/29] Delete EndpointStateNotifier. Add ShutdownSignals to
Connection.
---
.../com/azure/core/amqp/AmqpConnection.java | 23 +++++++----
.../java/com/azure/core/amqp/AmqpLink.java | 16 ++++----
.../java/com/azure/core/amqp/AmqpSession.java | 16 ++++----
.../core/amqp/EndpointStateNotifier.java | 40 -------------------
4 files changed, 31 insertions(+), 64 deletions(-)
delete mode 100644 sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/EndpointStateNotifier.java
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
index eaa5c64b8da2..f66f95c6976f 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpConnection.java
@@ -13,14 +13,6 @@
* Represents a TCP connection between the client and a service that uses the AMQP protocol.
*/
public interface AmqpConnection extends AutoCloseable {
- /**
- * Gets the endpoint states for the AMQP connection. {@link AmqpException AmqpExceptions} that occur on the link are
- * reported in the connection state. When the stream terminates, the connection is closed.
- *
- * @return A stream of endpoint states for the AMQP connection.
- */
- Flux getEndpointStates();
-
/**
* Gets the connection identifier.
*
@@ -72,6 +64,21 @@ public interface AmqpConnection extends AutoCloseable {
*/
boolean removeSession(String sessionName);
+ /**
+ * Gets the endpoint states for the AMQP connection. {@link AmqpException AmqpExceptions} that occur on the link are
+ * reported in the connection state. When the stream terminates, the connection is closed.
+ *
+ * @return A stream of endpoint states for the AMQP connection.
+ */
+ Flux getEndpointStates();
+
+ /**
+ * Gets any shutdown signals that occur in the AMQP endpoint.
+ *
+ * @return A stream of shutdown signals that occur in the AMQP endpoint.
+ */
+ Flux getShutdownSignals();
+
/**
* Closes the AMQP connection.
*/
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java
index 04d9adbbf622..2ff5f9c54bf0 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpLink.java
@@ -10,14 +10,6 @@
* Represents a unidirectional AMQP link.
*/
public interface AmqpLink extends AutoCloseable {
- /**
- * Gets the endpoint states for the AMQP link. {@link AmqpException AmqpExceptions} that occur on the link are
- * reported in the connection state. When the stream terminates, the link is closed.
- *
- * @return A stream of endpoint states for the AMQP link.
- */
- Flux getEndpointStates();
-
/**
* Gets the name of the link.
*
@@ -39,6 +31,14 @@ public interface AmqpLink extends AutoCloseable {
*/
String getHostname();
+ /**
+ * Gets the endpoint states for the AMQP link. {@link AmqpException AmqpExceptions} that occur on the link are
+ * reported in the connection state. When the stream terminates, the link is closed.
+ *
+ * @return A stream of endpoint states for the AMQP link.
+ */
+ Flux getEndpointStates();
+
/**
* Closes the AMQP link.
*/
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java
index dc49bbc86fd5..a268f253248b 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpSession.java
@@ -13,14 +13,6 @@
* An AMQP session representing bidirectional communication that supports multiple {@link AmqpLink AMQP links}.
*/
public interface AmqpSession extends AutoCloseable {
- /**
- * Gets the endpoint states for the AMQP session. {@link AmqpException AmqpExceptions} that occur on the link are
- * reported in the connection state. When the stream terminates, the session is closed.
- *
- * @return A stream of endpoint states for the AMQP session.
- */
- Flux getEndpointStates();
-
/**
* Gets the name for this AMQP session.
*
@@ -65,6 +57,14 @@ public interface AmqpSession extends AutoCloseable {
*/
boolean removeLink(String linkName);
+ /**
+ * Gets the endpoint states for the AMQP session. {@link AmqpException AmqpExceptions} that occur on the link are
+ * reported in the connection state. When the stream terminates, the session is closed.
+ *
+ * @return A stream of endpoint states for the AMQP session.
+ */
+ Flux getEndpointStates();
+
/**
* Closes the AMQP session.
*/
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/EndpointStateNotifier.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/EndpointStateNotifier.java
deleted file mode 100644
index 56ebb9b50ee2..000000000000
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/EndpointStateNotifier.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-package com.azure.core.amqp;
-
-import reactor.core.publisher.Flux;
-
-/**
- * Notifies subscribers of the endpoint state and any errors that occur with the object.
- */
-public interface EndpointStateNotifier {
-
- /**
- * Gets the current state of the endpoint.
- *
- * @return The current state of the endpoint.
- */
- AmqpEndpointState getCurrentState();
-
- /**
- * Gets the errors that occurred in the AMQP endpoint.
- *
- * @return A stream of errors that occurred in the AMQP endpoint.
- */
- Flux getErrors();
-
- /**
- * Gets the endpoint states for the AMQP endpoint.
- *
- * @return A stream of endpoint states as they occur in the endpoint.
- */
- Flux getConnectionStates();
-
- /**
- * Gets any shutdown signals that occur in the AMQP endpoint.
- *
- * @return A stream of shutdown signals that occur in the AMQP endpoint.
- */
- Flux getShutdownSignals();
-}
From d71e863eb9c7da53efccf04d78bf86771fd00c14 Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 20:55:30 -0800
Subject: [PATCH 05/29] Delete EndpointStateNotifierBase.
---
.../EndpointStateNotifierBase.java | 98 -------------------
1 file changed, 98 deletions(-)
delete mode 100644 sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/EndpointStateNotifierBase.java
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/EndpointStateNotifierBase.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/EndpointStateNotifierBase.java
deleted file mode 100644
index 3c18e009d5fb..000000000000
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/EndpointStateNotifierBase.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-package com.azure.core.amqp.implementation;
-
-import com.azure.core.amqp.AmqpEndpointState;
-import com.azure.core.amqp.AmqpShutdownSignal;
-import com.azure.core.amqp.EndpointStateNotifier;
-import com.azure.core.util.logging.ClientLogger;
-import org.apache.qpid.proton.engine.EndpointState;
-import reactor.core.Disposable;
-import reactor.core.publisher.DirectProcessor;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.ReplayProcessor;
-
-import java.io.Closeable;
-import java.util.Objects;
-
-public abstract class EndpointStateNotifierBase implements EndpointStateNotifier, Closeable {
- private final ReplayProcessor connectionStateProcessor =
- ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
- private final DirectProcessor errorContextProcessor = DirectProcessor.create();
- private final DirectProcessor shutdownSignalProcessor = DirectProcessor.create();
- private final Disposable subscription;
-
- protected ClientLogger logger;
- private volatile AmqpEndpointState state;
-
- public EndpointStateNotifierBase(ClientLogger logger) {
- Objects.requireNonNull(logger);
-
- this.logger = logger;
- this.subscription = connectionStateProcessor.subscribe(s -> this.state = s);
- }
-
- @Override
- public AmqpEndpointState getCurrentState() {
- return state;
- }
-
- @Override
- public Flux getErrors() {
- return errorContextProcessor;
- }
-
- @Override
- public Flux getConnectionStates() {
- return connectionStateProcessor;
- }
-
- @Override
- public Flux getShutdownSignals() {
- return shutdownSignalProcessor;
- }
-
- void notifyError(Throwable error) {
- Objects.requireNonNull(error);
-
- logger.error("Error occurred. {}", error.toString());
- errorContextProcessor.onNext(error);
- }
-
- void notifyShutdown(AmqpShutdownSignal shutdownSignal) {
- Objects.requireNonNull(shutdownSignal);
-
- logger.info("Notify shutdown signal: {}", shutdownSignal);
- shutdownSignalProcessor.onNext(shutdownSignal);
- }
-
- void notifyEndpointState(EndpointState endpointState) {
- Objects.requireNonNull(endpointState);
-
- logger.verbose("Connection state: {}", endpointState);
- final AmqpEndpointState state = getConnectionState(endpointState);
- connectionStateProcessor.onNext(state);
- }
-
- private static AmqpEndpointState getConnectionState(EndpointState state) {
- switch (state) {
- case ACTIVE:
- return AmqpEndpointState.ACTIVE;
- case UNINITIALIZED:
- return AmqpEndpointState.UNINITIALIZED;
- case CLOSED:
- return AmqpEndpointState.CLOSED;
- default:
- throw new UnsupportedOperationException("This endpoint state is not supported. State:" + state);
- }
- }
-
- @Override
- public void close() {
- subscription.dispose();
- connectionStateProcessor.onComplete();
- errorContextProcessor.onComplete();
- shutdownSignalProcessor.onComplete();
- }
-}
From 6a4ccce0f0b20de2b215cd219eb2f7b73d422269 Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 20:57:59 -0800
Subject: [PATCH 06/29] Update parameter name for MessageConstant.fromValue
---
.../java/com/azure/core/amqp/AmqpMessageConstant.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpMessageConstant.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpMessageConstant.java
index 15f72417770c..4f250ca9719f 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpMessageConstant.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpMessageConstant.java
@@ -120,13 +120,13 @@ public String getValue() {
/**
* Parses an header value to its message constant.
*
- * @param headerValue the messaging header value to parse.
+ * @param value the messaging header value to parse.
* @return the parsed MessageConstant object, or {@code null} if unable to parse.
* @throws NullPointerException if {@code constant} is {@code null}.
*/
- public static AmqpMessageConstant fromString(String headerValue) {
- Objects.requireNonNull(headerValue, "'headerValue' cannot be null.");
+ public static AmqpMessageConstant fromString(String value) {
+ Objects.requireNonNull(value, "'value' cannot be null.");
- return RESERVED_CONSTANTS_MAP.get(headerValue);
+ return RESERVED_CONSTANTS_MAP.get(value);
}
}
From c813b11cf02d9b53a0257ff35fb9366c5595a1d5 Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 21:01:11 -0800
Subject: [PATCH 07/29] Move AmqpExceptionHandler into implementation class.
---
.../{ => implementation}/AmqpExceptionHandler.java | 11 ++++++-----
.../core/amqp/implementation/ReactorConnection.java | 3 +--
.../core/amqp/implementation/ReactorExecutor.java | 1 -
3 files changed, 7 insertions(+), 8 deletions(-)
rename sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/{ => implementation}/AmqpExceptionHandler.java (76%)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpExceptionHandler.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpExceptionHandler.java
similarity index 76%
rename from sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpExceptionHandler.java
rename to sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpExceptionHandler.java
index c451bdc2439f..be2c8bbcc2e6 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/AmqpExceptionHandler.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpExceptionHandler.java
@@ -1,20 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-package com.azure.core.amqp;
+package com.azure.core.amqp.implementation;
+import com.azure.core.amqp.AmqpShutdownSignal;
import com.azure.core.util.logging.ClientLogger;
/**
* Handles exceptions generated by AMQP connections, sessions, and/or links.
*/
-public abstract class AmqpExceptionHandler {
+abstract class AmqpExceptionHandler {
private final ClientLogger logger = new ClientLogger(AmqpExceptionHandler.class);
/**
* Creates a new instance of the exception handler.
*/
- protected AmqpExceptionHandler() {
+ AmqpExceptionHandler() {
}
/**
@@ -22,7 +23,7 @@ protected AmqpExceptionHandler() {
*
* @param exception The exception that caused the connection error.
*/
- public void onConnectionError(Throwable exception) {
+ void onConnectionError(Throwable exception) {
logger.warning("Connection exception encountered: " + exception.toString(), exception);
}
@@ -31,7 +32,7 @@ public void onConnectionError(Throwable exception) {
*
* @param shutdownSignal The shutdown signal that was received.
*/
- public void onConnectionShutdown(AmqpShutdownSignal shutdownSignal) {
+ void onConnectionShutdown(AmqpShutdownSignal shutdownSignal) {
logger.info("Shutdown received: {}", shutdownSignal);
}
}
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
index 99a21e1dcb27..05c9537b5f95 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
@@ -5,7 +5,6 @@
import com.azure.core.amqp.AmqpConnection;
import com.azure.core.amqp.AmqpEndpointState;
-import com.azure.core.amqp.AmqpExceptionHandler;
import com.azure.core.amqp.AmqpRetryPolicy;
import com.azure.core.amqp.AmqpSession;
import com.azure.core.amqp.ClaimsBasedSecurityNode;
@@ -28,7 +27,7 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
-public class ReactorConnection extends EndpointStateNotifierBase implements AmqpConnection {
+public class ReactorConnection implements AmqpConnection {
private static final String CBS_SESSION_NAME = "cbs-session";
private static final String CBS_ADDRESS = "$cbs";
private static final String CBS_LINK_NAME = "cbs";
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorExecutor.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorExecutor.java
index 4fb28b0e4954..f3b9a067a3c9 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorExecutor.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorExecutor.java
@@ -3,7 +3,6 @@
package com.azure.core.amqp.implementation;
-import com.azure.core.amqp.AmqpExceptionHandler;
import com.azure.core.amqp.AmqpShutdownSignal;
import com.azure.core.amqp.exception.AmqpErrorContext;
import com.azure.core.amqp.exception.AmqpException;
From 91bca87d544ea03922257304fa2f32825d065eab Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 21:02:28 -0800
Subject: [PATCH 08/29] Update documentation in AmqpReceiveLink.
---
.../com/azure/core/amqp/implementation/AmqpReceiveLink.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpReceiveLink.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpReceiveLink.java
index 7c889a90088a..574e8db71673 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpReceiveLink.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpReceiveLink.java
@@ -7,7 +7,6 @@
import org.apache.qpid.proton.message.Message;
import reactor.core.publisher.Flux;
-import java.io.Closeable;
import java.util.function.Supplier;
/**
@@ -21,7 +20,7 @@ public interface AmqpReceiveLink extends AmqpLink {
* Initialises the link from the client to the message broker and begins to receive messages from the broker.
*
* @return A Flux of AMQP messages which completes when the client calls
- * {@link Closeable#close() AmqpReceiveLink.close()} or an unrecoverable error occurs on the AMQP link.
+ * {@link AutoCloseable#close() AmqpReceiveLink.close()} or an unrecoverable error occurs on the AMQP link.
*/
Flux receive();
From 39633d174d813136d5826350c2d763accf5a0aad Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 21:20:15 -0800
Subject: [PATCH 09/29] Update CBS -> Cbs.
---
.../implementation/AzureTokenManagerProvider.java | 4 ++--
...horizationType.java => CbsAuthorizationType.java} | 4 ++--
.../implementation/ClaimsBasedSecurityChannel.java | 4 ++--
.../core/amqp/implementation/ConnectionOptions.java | 6 +++---
.../AzureTokenManagerProviderTest.java | 12 ++++++------
.../core/amqp/implementation/CBSChannelTest.java | 4 ++--
.../amqp/implementation/ReactorConnectionTest.java | 4 ++--
.../core/amqp/implementation/ReactorSessionTest.java | 2 +-
.../messaging/eventhubs/EventHubClientBuilder.java | 8 ++++----
.../messaging/eventhubs/EventHubConnectionTest.java | 4 ++--
.../eventhubs/EventHubConsumerAsyncClientTest.java | 4 ++--
.../eventhubs/EventHubConsumerClientTest.java | 4 ++--
.../eventhubs/EventHubProducerAsyncClientTest.java | 4 ++--
.../eventhubs/EventHubProducerClientTest.java | 4 ++--
.../eventhubs/implementation/CBSChannelTest.java | 2 +-
.../EventHubReactorConnectionTest.java | 4 ++--
.../ReactorConnectionIntegrationTest.java | 6 +++---
17 files changed, 40 insertions(+), 40 deletions(-)
rename sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/{CBSAuthorizationType.java => CbsAuthorizationType.java} (92%)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AzureTokenManagerProvider.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AzureTokenManagerProvider.java
index c58957ae56a5..b8540e388d86 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AzureTokenManagerProvider.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AzureTokenManagerProvider.java
@@ -17,7 +17,7 @@ public class AzureTokenManagerProvider implements TokenManagerProvider {
static final String TOKEN_AUDIENCE_FORMAT = "amqp://%s/%s";
private final ClientLogger logger = new ClientLogger(AzureTokenManagerProvider.class);
- private final CBSAuthorizationType authorizationType;
+ private final CbsAuthorizationType authorizationType;
private final String fullyQualifiedNamespace;
private final String activeDirectoryScope;
@@ -29,7 +29,7 @@ public class AzureTokenManagerProvider implements TokenManagerProvider {
* @param fullyQualifiedNamespace Fully-qualified namespace of the message broker.
* @param activeDirectoryScope Scope used to access AD resources for the Azure service.
*/
- public AzureTokenManagerProvider(CBSAuthorizationType authorizationType, String fullyQualifiedNamespace,
+ public AzureTokenManagerProvider(CbsAuthorizationType authorizationType, String fullyQualifiedNamespace,
String activeDirectoryScope) {
this.activeDirectoryScope = Objects.requireNonNull(activeDirectoryScope,
"'activeDirectoryScope' cannot be null.");
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/CBSAuthorizationType.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/CbsAuthorizationType.java
similarity index 92%
rename from sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/CBSAuthorizationType.java
rename to sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/CbsAuthorizationType.java
index 03fe0adcb0af..92390dd50305 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/CBSAuthorizationType.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/CbsAuthorizationType.java
@@ -8,7 +8,7 @@
/**
* An enumeration of supported authorization methods with the {@link ClaimsBasedSecurityNode}.
*/
-public enum CBSAuthorizationType {
+public enum CbsAuthorizationType {
/**
* Authorize with CBS through a shared access signature.
*/
@@ -23,7 +23,7 @@ public enum CBSAuthorizationType {
private final String scheme;
- CBSAuthorizationType(String scheme) {
+ CbsAuthorizationType(String scheme) {
this.scheme = scheme;
}
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java
index 3494072a071a..4e0173cbe071 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java
@@ -27,11 +27,11 @@ public class ClaimsBasedSecurityChannel extends EndpointStateNotifierBase implem
private final TokenCredential credential;
private final Mono cbsChannelMono;
- private final CBSAuthorizationType authorizationType;
+ private final CbsAuthorizationType authorizationType;
private final AmqpRetryOptions retryOptions;
public ClaimsBasedSecurityChannel(Mono responseChannelMono, TokenCredential tokenCredential,
- CBSAuthorizationType authorizationType, AmqpRetryOptions retryOptions) {
+ CbsAuthorizationType authorizationType, AmqpRetryOptions retryOptions) {
super(new ClientLogger(ClaimsBasedSecurityChannel.class));
this.authorizationType = Objects.requireNonNull(authorizationType, "'authorizationType' cannot be null.");
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ConnectionOptions.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ConnectionOptions.java
index 86c2998c5448..8b2d9a6c9a2e 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ConnectionOptions.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ConnectionOptions.java
@@ -24,10 +24,10 @@ public class ConnectionOptions {
private final Scheduler scheduler;
private final String fullyQualifiedNamespace;
private final String entityPath;
- private final CBSAuthorizationType authorizationType;
+ private final CbsAuthorizationType authorizationType;
public ConnectionOptions(String fullyQualifiedNamespace, String entityPath, TokenCredential tokenCredential,
- CBSAuthorizationType authorizationType, AmqpTransportType transport, AmqpRetryOptions retryOptions,
+ CbsAuthorizationType authorizationType, AmqpTransportType transport, AmqpRetryOptions retryOptions,
ProxyOptions proxyOptions, Scheduler scheduler) {
this.fullyQualifiedNamespace = Objects.requireNonNull(fullyQualifiedNamespace,
"'fullyQualifiedNamespace' is required.");
@@ -52,7 +52,7 @@ public TokenCredential getTokenCredential() {
return tokenCredential;
}
- public CBSAuthorizationType getAuthorizationType() {
+ public CbsAuthorizationType getAuthorizationType() {
return authorizationType;
}
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/AzureTokenManagerProviderTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/AzureTokenManagerProviderTest.java
index fc7edb118ffa..1c59251da4dc 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/AzureTokenManagerProviderTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/AzureTokenManagerProviderTest.java
@@ -49,20 +49,20 @@ public void constructorNullType() {
@Test
public void constructorNullHost() {
- assertThrows(NullPointerException.class, () -> new AzureTokenManagerProvider(CBSAuthorizationType.JSON_WEB_TOKEN, null, "some-scope"));
+ assertThrows(NullPointerException.class, () -> new AzureTokenManagerProvider(CbsAuthorizationType.JSON_WEB_TOKEN, null, "some-scope"));
}
@Test
public void constructorNullScope() {
- assertThrows(NullPointerException.class, () -> new AzureTokenManagerProvider(CBSAuthorizationType.JSON_WEB_TOKEN, HOST_NAME, null));
+ assertThrows(NullPointerException.class, () -> new AzureTokenManagerProvider(CbsAuthorizationType.JSON_WEB_TOKEN, HOST_NAME, null));
}
/**
* Verifies that the correct resource string is returned when we pass in different authorization types.
*/
@ParameterizedTest
- @EnumSource(CBSAuthorizationType.class)
- public void getResourceString(CBSAuthorizationType authorizationType) {
+ @EnumSource(CbsAuthorizationType.class)
+ public void getResourceString(CbsAuthorizationType authorizationType) {
// Arrange
final String scope = "some-scope";
final AzureTokenManagerProvider provider = new AzureTokenManagerProvider(authorizationType, HOST_NAME, scope);
@@ -93,7 +93,7 @@ public void getResourceString(CBSAuthorizationType authorizationType) {
public void getCorrectTokenManagerSasToken() {
// Arrange
final String aadScope = "some-active-directory-scope";
- final AzureTokenManagerProvider provider = new AzureTokenManagerProvider(CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, HOST_NAME, aadScope);
+ final AzureTokenManagerProvider provider = new AzureTokenManagerProvider(CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, HOST_NAME, aadScope);
final String entityPath = "event-hub-test-2/partition/2";
final AccessToken token = new AccessToken("a-new-access-token", OffsetDateTime.now().plusMinutes(10));
final String tokenAudience = String.format(Locale.US, TOKEN_AUDIENCE_FORMAT, HOST_NAME, entityPath);
@@ -118,7 +118,7 @@ public void getCorrectTokenManagerSasToken() {
public void getCorrectTokenManagerJwt() {
// Arrange
final String aadScope = "some-active-directory-scope";
- final AzureTokenManagerProvider provider = new AzureTokenManagerProvider(CBSAuthorizationType.JSON_WEB_TOKEN, HOST_NAME, aadScope);
+ final AzureTokenManagerProvider provider = new AzureTokenManagerProvider(CbsAuthorizationType.JSON_WEB_TOKEN, HOST_NAME, aadScope);
final String entityPath = "event-hub-test-2/partition/2";
final AccessToken token = new AccessToken("a-new-access-token", OffsetDateTime.now().plusMinutes(10));
final String tokenAudience = String.format(Locale.US, TOKEN_AUDIENCE_FORMAT, HOST_NAME, entityPath);
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/CBSChannelTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/CBSChannelTest.java
index a180b0a8b8be..52122a48f0ab 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/CBSChannelTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/CBSChannelTest.java
@@ -70,7 +70,7 @@ public void authorizesSasToken() {
final String scopes = "scopes.cbs.foo";
final AccessToken accessToken = new AccessToken("an-access-token?", OffsetDateTime.of(2019, 11, 10, 15, 2, 5, 0, ZoneOffset.UTC));
final ClaimsBasedSecurityChannel cbsChannel = new ClaimsBasedSecurityChannel(Mono.just(requestResponseChannel), tokenCredential,
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, options);
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, options);
when(tokenCredential.getToken(argThat(arg -> arg.getScopes().contains(scopes))))
.thenReturn(Mono.just(accessToken));
@@ -104,7 +104,7 @@ public void authorizesJwt() {
final String scopes = "scopes.cbs.foo";
final AccessToken accessToken = new AccessToken("an-access-token?", OffsetDateTime.of(2019, 11, 10, 15, 2, 5, 0, ZoneOffset.UTC));
final ClaimsBasedSecurityChannel cbsChannel = new ClaimsBasedSecurityChannel(Mono.just(requestResponseChannel), tokenCredential,
- CBSAuthorizationType.JSON_WEB_TOKEN, options);
+ CbsAuthorizationType.JSON_WEB_TOKEN, options);
when(tokenCredential.getToken(argThat(arg -> arg.getScopes().contains(scopes))))
.thenReturn(Mono.just(accessToken));
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
index 0fcaf9bd423f..365c294c6666 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
@@ -95,7 +95,7 @@ public void setup() throws IOException {
final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(TEST_DURATION);
final ConnectionOptions connectionOptions = new ConnectionOptions(CREDENTIAL_INFO.getEndpoint().getHost(),
- CREDENTIAL_INFO.getEntityPath(), tokenProvider, CBSAuthorizationType.SHARED_ACCESS_SIGNATURE,
+ CREDENTIAL_INFO.getEntityPath(), tokenProvider, CbsAuthorizationType.SHARED_ACCESS_SIGNATURE,
AmqpTransportType.AMQP, retryOptions, ProxyOptions.SYSTEM_DEFAULTS, SCHEDULER);
connection = new ReactorConnection(CONNECTION_ID, connectionOptions, reactorProvider, reactorHandlerProvider,
tokenManager, messageSerializer);
@@ -292,7 +292,7 @@ public void createCBSNodeTimeoutException() {
.setMode(AmqpRetryMode.FIXED)
.setTryTimeout(timeout);
ConnectionOptions parameters = new ConnectionOptions(CREDENTIAL_INFO.getEndpoint().getHost(),
- CREDENTIAL_INFO.getEntityPath(), tokenProvider, CBSAuthorizationType.SHARED_ACCESS_SIGNATURE,
+ CREDENTIAL_INFO.getEntityPath(), tokenProvider, CbsAuthorizationType.SHARED_ACCESS_SIGNATURE,
AmqpTransportType.AMQP, retryOptions, ProxyOptions.SYSTEM_DEFAULTS, Schedulers.parallel());
// Act and Assert
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
index 9762b0fbdbe2..c5669df3e776 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
@@ -67,7 +67,7 @@ public void setup() throws IOException {
MockReactorHandlerProvider handlerProvider = new MockReactorHandlerProvider(reactorProvider, null, handler, null, null);
AzureTokenManagerProvider azureTokenManagerProvider = new AzureTokenManagerProvider(
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, HOST, "a-test-scope");
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, HOST, "a-test-scope");
this.reactorSession = new ReactorSession(session, handler, NAME, reactorProvider, handlerProvider,
Mono.just(cbsNode), azureTokenManagerProvider, serializer, TIMEOUT);
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java
index 57a07bab1fbe..0bea6f6cbb0c 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubClientBuilder.java
@@ -8,7 +8,7 @@
import com.azure.core.amqp.ProxyAuthenticationType;
import com.azure.core.amqp.ProxyOptions;
import com.azure.core.amqp.implementation.AzureTokenManagerProvider;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.ConnectionStringProperties;
import com.azure.core.amqp.implementation.MessageSerializer;
@@ -544,9 +544,9 @@ private ConnectionOptions getConnectionOptions() {
proxyOptions = getDefaultProxyConfiguration(configuration);
}
- final CBSAuthorizationType authorizationType = credentials instanceof EventHubSharedKeyCredential
- ? CBSAuthorizationType.SHARED_ACCESS_SIGNATURE
- : CBSAuthorizationType.JSON_WEB_TOKEN;
+ final CbsAuthorizationType authorizationType = credentials instanceof EventHubSharedKeyCredential
+ ? CbsAuthorizationType.SHARED_ACCESS_SIGNATURE
+ : CbsAuthorizationType.JSON_WEB_TOKEN;
return new ConnectionOptions(fullyQualifiedNamespace, eventHubName, credentials, authorizationType,
transport, retryOptions, proxyOptions, scheduler);
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConnectionTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConnectionTest.java
index 120f871bd0ac..cb21b35b7b4d 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConnectionTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConnectionTest.java
@@ -11,7 +11,7 @@
import com.azure.core.amqp.ProxyOptions;
import com.azure.core.amqp.implementation.AmqpReceiveLink;
import com.azure.core.amqp.implementation.AmqpSendLink;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.credential.TokenCredential;
import com.azure.messaging.eventhubs.implementation.EventHubAmqpConnection;
@@ -59,7 +59,7 @@ public class EventHubConnectionTest {
public void setup() {
MockitoAnnotations.initMocks(this);
ConnectionOptions connectionOptions = new ConnectionOptions(HOST_NAME, "event-hub-path", tokenCredential,
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, retryOptions,
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, retryOptions,
ProxyOptions.SYSTEM_DEFAULTS, Schedulers.parallel());
provider = new EventHubConnection(Mono.just(connection), connectionOptions);
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
index 4a8ba36dc0ba..5ccebcce0be9 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
@@ -9,7 +9,7 @@
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyOptions;
import com.azure.core.amqp.implementation.AmqpReceiveLink;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.credential.TokenCredential;
@@ -116,7 +116,7 @@ public void setup() {
when(amqpReceiveLink.getShutdownSignals()).thenReturn(shutdownProcessor);
connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, new AmqpRetryOptions(),
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, new AmqpRetryOptions(),
ProxyOptions.SYSTEM_DEFAULTS, Schedulers.parallel());
eventHubConnection = new EventHubConnection(Mono.just(connection), connectionOptions);
when(connection.createSession(any())).thenReturn(Mono.just(session));
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java
index 1f783b6f8a5d..355f6fe2bcfe 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java
@@ -7,7 +7,7 @@
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyOptions;
import com.azure.core.amqp.implementation.AmqpReceiveLink;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.credential.TokenCredential;
@@ -100,7 +100,7 @@ public void setup() {
when(amqpReceiveLink.getCredits()).thenReturn(10);
connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, new AmqpRetryOptions(),
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, new AmqpRetryOptions(),
ProxyOptions.SYSTEM_DEFAULTS, Schedulers.parallel());
linkProvider = new EventHubConnection(Mono.just(connection), connectionOptions);
when(connection.createSession(argThat(name -> name.endsWith(PARTITION_ID))))
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java
index 3798de2137fb..3d018ac84471 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java
@@ -10,7 +10,7 @@
import com.azure.core.amqp.exception.AmqpErrorCondition;
import com.azure.core.amqp.exception.AmqpException;
import com.azure.core.amqp.implementation.AmqpSendLink;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.amqp.implementation.TracerProvider;
@@ -89,7 +89,7 @@ public void setup() {
tracerProvider = new TracerProvider(Collections.emptyList());
ConnectionOptions connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, retryOptions,
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, retryOptions,
ProxyOptions.SYSTEM_DEFAULTS, Schedulers.parallel());
eventHubConnection = new EventHubConnection(Mono.just(connection), connectionOptions);
producer = new EventHubProducerAsyncClient(HOSTNAME, EVENT_HUB_NAME, eventHubConnection, retryOptions, tracerProvider,
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerClientTest.java
index 581c41a725da..c26330c72cf4 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerClientTest.java
@@ -11,7 +11,7 @@
import com.azure.core.amqp.exception.AmqpErrorContext;
import com.azure.core.amqp.exception.AmqpException;
import com.azure.core.amqp.implementation.AmqpSendLink;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.amqp.implementation.TracerProvider;
@@ -93,7 +93,7 @@ public void setup() {
final TracerProvider tracerProvider = new TracerProvider(Collections.emptyList());
ConnectionOptions connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, retryOptions,
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, retryOptions,
ProxyOptions.SYSTEM_DEFAULTS, Schedulers.parallel());
linkProvider = new EventHubConnection(Mono.just(connection), connectionOptions);
asyncProducer = new EventHubProducerAsyncClient(HOSTNAME, EVENT_HUB_NAME, linkProvider, retryOptions,
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java
index d74548dfa62b..3a6b4bb3aa93 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/CBSChannelTest.java
@@ -34,7 +34,7 @@
import java.time.Duration;
import java.time.OffsetDateTime;
-import static com.azure.core.amqp.implementation.CBSAuthorizationType.SHARED_ACCESS_SIGNATURE;
+import static com.azure.core.amqp.implementation.CbsAuthorizationType.SHARED_ACCESS_SIGNATURE;
public class CBSChannelTest extends IntegrationTestBase {
private static final String CONNECTION_ID = "CbsChannelTest-Connection";
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java
index 0bebe993c2ae..485612210e05 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/EventHubReactorConnectionTest.java
@@ -6,7 +6,7 @@
import com.azure.core.amqp.AmqpRetryOptions;
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyOptions;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.amqp.implementation.ReactorDispatcher;
@@ -69,7 +69,7 @@ public void setup() throws IOException {
final ProxyOptions proxy = ProxyOptions.SYSTEM_DEFAULTS;
connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-name",
- tokenCredential, CBSAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP, new AmqpRetryOptions(),
+ tokenCredential, CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP, new AmqpRetryOptions(),
proxy, scheduler);
final ReactorDispatcher reactorDispatcher = new ReactorDispatcher(reactor);
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java
index 703de36e2faf..9e38bdc0a5d1 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/implementation/ReactorConnectionIntegrationTest.java
@@ -6,7 +6,7 @@
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyOptions;
import com.azure.core.amqp.implementation.AzureTokenManagerProvider;
-import com.azure.core.amqp.implementation.CBSAuthorizationType;
+import com.azure.core.amqp.implementation.CbsAuthorizationType;
import com.azure.core.amqp.implementation.ClaimsBasedSecurityChannel;
import com.azure.core.amqp.implementation.ConnectionOptions;
import com.azure.core.amqp.implementation.ConnectionStringProperties;
@@ -27,7 +27,7 @@
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
-import static com.azure.core.amqp.implementation.CBSAuthorizationType.SHARED_ACCESS_SIGNATURE;
+import static com.azure.core.amqp.implementation.CbsAuthorizationType.SHARED_ACCESS_SIGNATURE;
public class ReactorConnectionIntegrationTest extends IntegrationTestBase {
@@ -80,7 +80,7 @@ public void getCbsNode() {
public void getCbsNodeAuthorize() {
// Arrange
final AzureTokenManagerProvider provider = new AzureTokenManagerProvider(
- CBSAuthorizationType.SHARED_ACCESS_SIGNATURE,
+ CbsAuthorizationType.SHARED_ACCESS_SIGNATURE,
getConnectionStringProperties().getEndpoint().getHost(),
ClientConstants.AZURE_ACTIVE_DIRECTORY_SCOPE);
From d6e3a0b14cfa93dbee69e5f44f6a224c77ffed1b Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 21:24:23 -0800
Subject: [PATCH 10/29] Fix CBSChannel.
---
.../amqp/implementation/ClaimsBasedSecurityChannel.java | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java
index 4e0173cbe071..fca3990555b9 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java
@@ -7,7 +7,6 @@
import com.azure.core.amqp.ClaimsBasedSecurityNode;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
-import com.azure.core.util.logging.ClientLogger;
import org.apache.qpid.proton.Proton;
import org.apache.qpid.proton.amqp.messaging.AmqpValue;
import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
@@ -19,11 +18,11 @@
import java.util.Map;
import java.util.Objects;
-public class ClaimsBasedSecurityChannel extends EndpointStateNotifierBase implements ClaimsBasedSecurityNode {
- static final String PUT_TOKEN_OPERATION = "operation";
- static final String PUT_TOKEN_OPERATION_VALUE = "put-token";
+public class ClaimsBasedSecurityChannel implements ClaimsBasedSecurityNode {
static final String PUT_TOKEN_TYPE = "type";
static final String PUT_TOKEN_AUDIENCE = "name";
+ private static final String PUT_TOKEN_OPERATION = "operation";
+ private static final String PUT_TOKEN_OPERATION_VALUE = "put-token";
private final TokenCredential credential;
private final Mono cbsChannelMono;
@@ -32,7 +31,6 @@ public class ClaimsBasedSecurityChannel extends EndpointStateNotifierBase implem
public ClaimsBasedSecurityChannel(Mono responseChannelMono, TokenCredential tokenCredential,
CbsAuthorizationType authorizationType, AmqpRetryOptions retryOptions) {
- super(new ClientLogger(ClaimsBasedSecurityChannel.class));
this.authorizationType = Objects.requireNonNull(authorizationType, "'authorizationType' cannot be null.");
this.retryOptions = Objects.requireNonNull(retryOptions, "'retryOptions' cannot be null.");
From 9dfae9cb4954a55828067e27257bf659f70f77ad Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 21:25:48 -0800
Subject: [PATCH 11/29] Add AmqpEndpointStateUtil.
---
.../implementation/AmqpEndpointStateUtil.java | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpEndpointStateUtil.java
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpEndpointStateUtil.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpEndpointStateUtil.java
new file mode 100644
index 000000000000..8d67e6d2d951
--- /dev/null
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/AmqpEndpointStateUtil.java
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.core.amqp.implementation;
+
+import com.azure.core.amqp.AmqpEndpointState;
+import org.apache.qpid.proton.engine.EndpointState;
+
+/**
+ * Helper class for managing endpoint states from proton-j.
+ */
+class AmqpEndpointStateUtil {
+ /**
+ * Translates proton-j endpoint states into an AMQP endpoint state.
+ * @param state proton-j endpoint state.
+ * @return The corresponding {@link AmqpEndpointState}.
+ * @throws IllegalArgumentException if {@code state} is not a supported {@link AmqpEndpointState}.
+ */
+ static AmqpEndpointState getConnectionState(EndpointState state) {
+ switch (state) {
+ case ACTIVE:
+ return AmqpEndpointState.ACTIVE;
+ case UNINITIALIZED:
+ return AmqpEndpointState.UNINITIALIZED;
+ case CLOSED:
+ return AmqpEndpointState.CLOSED;
+ default:
+ throw new IllegalArgumentException("This endpoint state is not supported. State:" + state);
+ }
+ }
+}
From b6ed6c0c4b6c3436f19f31dd9dc1d75502239c18 Mon Sep 17 00:00:00 2001
From: Connie
Date: Thu, 21 Nov 2019 21:34:02 -0800
Subject: [PATCH 12/29] Fix ReactorConnection.
---
.../implementation/ReactorConnection.java | 59 +++++++++++++------
1 file changed, 41 insertions(+), 18 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
index 05c9537b5f95..bd149653b33c 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
@@ -7,20 +7,25 @@
import com.azure.core.amqp.AmqpEndpointState;
import com.azure.core.amqp.AmqpRetryPolicy;
import com.azure.core.amqp.AmqpSession;
+import com.azure.core.amqp.AmqpShutdownSignal;
import com.azure.core.amqp.ClaimsBasedSecurityNode;
import com.azure.core.amqp.implementation.handler.ConnectionHandler;
import com.azure.core.amqp.implementation.handler.SessionHandler;
import com.azure.core.util.logging.ClientLogger;
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.Session;
import org.apache.qpid.proton.reactor.Reactor;
import reactor.core.Disposable;
import reactor.core.Disposables;
+import reactor.core.publisher.DirectProcessor;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.FluxSink;
import reactor.core.publisher.Mono;
+import reactor.core.publisher.ReplayProcessor;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@@ -32,8 +37,14 @@ public class ReactorConnection implements AmqpConnection {
private static final String CBS_ADDRESS = "$cbs";
private static final String CBS_LINK_NAME = "cbs";
+ private final ClientLogger logger = new ClientLogger(ReactorConnection.class);
private final ConcurrentMap sessionMap = new ConcurrentHashMap<>();
private final AtomicBoolean hasConnection = new AtomicBoolean();
+ private final DirectProcessor shutdownSignals = DirectProcessor.create();
+ private final ReplayProcessor connectionStates =
+ ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
+ private final FluxSink connectionStateSink =
+ connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
private final String connectionId;
private final Mono connectionMono;
@@ -65,7 +76,6 @@ public class ReactorConnection implements AmqpConnection {
public ReactorConnection(String connectionId, ConnectionOptions connectionOptions, ReactorProvider reactorProvider,
ReactorHandlerProvider handlerProvider, TokenManagerProvider tokenManagerProvider,
MessageSerializer messageSerializer) {
- super(new ClientLogger(ReactorConnection.class));
this.connectionOptions = connectionOptions;
this.reactorProvider = reactorProvider;
@@ -84,13 +94,29 @@ public ReactorConnection(String connectionId, ConnectionOptions connectionOption
this.subscriptions = Disposables.composite(
this.handler.getEndpointStates().subscribe(
- this::notifyEndpointState,
- this::notifyError,
- () -> notifyEndpointState(EndpointState.CLOSED)),
- this.handler.getErrors().subscribe(
- this::notifyError,
- this::notifyError,
- () -> notifyEndpointState(EndpointState.CLOSED)));
+ state -> {
+ logger.verbose("Connection state: {}", state);
+ connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ }, error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }, () -> {
+ connectionStateSink.next(AmqpEndpointState.CLOSED);
+ connectionStateSink.complete();
+ }));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Flux getEndpointStates() {
+ return connectionStates;
+ }
+
+ @Override
+ public Flux getShutdownSignals() {
+ return shutdownSignals;
}
/**
@@ -99,7 +125,7 @@ public ReactorConnection(String connectionId, ConnectionOptions connectionOption
@Override
public Mono getClaimsBasedSecurityNode() {
final Mono cbsNodeMono = RetryUtil.withRetry(
- getConnectionStates().takeUntil(x -> x == AmqpEndpointState.ACTIVE),
+ getEndpointStates().takeUntil(x -> x == AmqpEndpointState.ACTIVE),
connectionOptions.getRetry().getTryTimeout(), retryPolicy)
.then(Mono.fromCallable(this::getOrCreateCBSNode));
@@ -190,14 +216,11 @@ public void close() {
}
subscriptions.dispose();
- sessionMap.forEach((name, session) -> {
- try {
- session.close();
- } catch (IOException e) {
- logger.error("Could not close session: " + name, e);
- }
- });
- super.close();
+
+ final HashMap map = new HashMap<>(sessionMap);
+
+ sessionMap.clear();
+ map.forEach((name, session) -> session.close());
}
/**
From a3e203aeb10b10d74879a0ee667d6dbd9c4bae0a Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 12:33:44 -0800
Subject: [PATCH 13/29] Fix errors in updated sender and receiver.
---
.../implementation/ReactorConnection.java | 16 +++-
.../amqp/implementation/ReactorReceiver.java | 76 ++++++++-----------
.../amqp/implementation/ReactorSender.java | 56 ++++++++------
.../amqp/implementation/TokenManager.java | 10 ++-
4 files changed, 86 insertions(+), 72 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
index bd149653b33c..5c4c85c5f3b4 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
@@ -40,11 +40,11 @@ public class ReactorConnection implements AmqpConnection {
private final ClientLogger logger = new ClientLogger(ReactorConnection.class);
private final ConcurrentMap sessionMap = new ConcurrentHashMap<>();
private final AtomicBoolean hasConnection = new AtomicBoolean();
+ private final AtomicBoolean isDisposed = new AtomicBoolean();
private final DirectProcessor shutdownSignals = DirectProcessor.create();
private final ReplayProcessor connectionStates =
ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
- private final FluxSink connectionStateSink =
- connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
+ private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
private final String connectionId;
private final Mono connectionMono;
@@ -103,7 +103,12 @@ public ReactorConnection(String connectionId, ConnectionOptions connectionOption
}, () -> {
connectionStateSink.next(AmqpEndpointState.CLOSED);
connectionStateSink.complete();
- }));
+ }),
+
+ this.handler.getErrors().subscribe(error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }));
}
/**
@@ -211,11 +216,16 @@ public boolean removeSession(String sessionName) {
*/
@Override
public void close() {
+ if (isDisposed.getAndSet(true)) {
+ return;
+ }
+
if (executor != null) {
executor.close();
}
subscriptions.dispose();
+ connectionStateSink.complete();
final HashMap map = new HashMap<>(sessionMap);
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
index 6aaf12d8813f..9965cd670ab8 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
@@ -3,13 +3,11 @@
package com.azure.core.amqp.implementation;
-import com.azure.core.amqp.AmqpShutdownSignal;
-import com.azure.core.amqp.exception.AmqpException;
+import com.azure.core.amqp.AmqpEndpointState;
import com.azure.core.amqp.implementation.handler.ReceiveLinkHandler;
import com.azure.core.util.logging.ClientLogger;
import org.apache.qpid.proton.Proton;
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.message.Message;
import reactor.core.Disposable;
@@ -17,8 +15,8 @@
import reactor.core.publisher.EmitterProcessor;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;
+import reactor.core.publisher.ReplayProcessor;
-import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
@@ -26,7 +24,7 @@
/**
* Handles receiving events from Event Hubs service and translating them to proton-j messages.
*/
-public class ReactorReceiver extends EndpointStateNotifierBase implements AmqpReceiveLink {
+public class ReactorReceiver implements AmqpReceiveLink {
// Initial value is true because we could not have created this receiver without authorising against the CBS node
// first.
private final AtomicBoolean hasAuthorized = new AtomicBoolean(true);
@@ -36,50 +34,43 @@ public class ReactorReceiver extends EndpointStateNotifierBase implements AmqpRe
private final ReceiveLinkHandler handler;
private final TokenManager tokenManager;
private final Disposable.Composite subscriptions;
+ private final AtomicBoolean isDisposed = new AtomicBoolean();
private final EmitterProcessor messagesProcessor = EmitterProcessor.create();
- private final AtomicBoolean isDisposed;
private FluxSink messageSink = messagesProcessor.sink();
+ private final ClientLogger logger = new ClientLogger(ReactorReceiver.class);
+ private final ReplayProcessor connectionStates =
+ ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
+ private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
private volatile Supplier creditSupplier;
ReactorReceiver(String entityPath, Receiver receiver, ReceiveLinkHandler handler, TokenManager tokenManager) {
- super(new ClientLogger(ReactorReceiver.class));
- this.isDisposed = new AtomicBoolean();
this.entityPath = entityPath;
this.receiver = receiver;
this.handler = handler;
this.tokenManager = tokenManager;
this.subscriptions = Disposables.composite(
- handler.getDeliveredMessages().subscribe(this::decodeDelivery),
-
- handler.getEndpointStates().subscribe(
- this::notifyEndpointState,
- error -> logger.error("Error encountered getting endpointState", error),
- () -> {
- logger.verbose("getEndpointStates completed.");
- notifyEndpointState(EndpointState.CLOSED);
+ this.handler.getDeliveredMessages().subscribe(this::decodeDelivery),
+
+ this.handler.getEndpointStates().subscribe(
+ state -> {
+ logger.verbose("Connection state: {}", state);
+ connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ }, error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }, () -> {
+ connectionStateSink.next(AmqpEndpointState.CLOSED);
+ connectionStateSink.complete();
}),
- handler.getErrors().subscribe(error -> {
- if (!(error instanceof AmqpException)) {
- logger.error("Error occurred that is not an AmqpException.", error);
- notifyShutdown(new AmqpShutdownSignal(false, false, error.toString()));
- close();
- return;
- }
-
- final AmqpException amqpException = (AmqpException) error;
- if (!amqpException.isTransient()) {
- logger.warning("Error occurred that is not retriable.", amqpException);
- notifyShutdown(new AmqpShutdownSignal(false, false, amqpException.toString()));
- close();
- } else {
- notifyError(error);
- }
+ this.handler.getErrors().subscribe(error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
}),
- tokenManager.getAuthorizationResults().subscribe(
+ this.tokenManager.getAuthorizationResults().subscribe(
response -> {
logger.verbose("Token refreshed: {}", response);
hasAuthorized.set(true);
@@ -87,8 +78,12 @@ public class ReactorReceiver extends EndpointStateNotifierBase implements AmqpRe
logger.info("clientId[{}], path[{}], linkName[{}] - tokenRenewalFailure[{}]",
handler.getConnectionId(), this.entityPath, getLinkName(), error.getMessage());
hasAuthorized.set(false);
- }, () -> hasAuthorized.set(false))
- );
+ }, () -> hasAuthorized.set(false)));
+ }
+
+ @Override
+ public Flux getEndpointStates() {
+ return connectionStates;
}
@Override
@@ -134,17 +129,10 @@ public void close() {
}
subscriptions.dispose();
-
- try {
- tokenManager.close();
- } catch (IOException e) {
- logger.warning("IOException occurred trying to close tokenManager for {}.", entityPath, e);
- }
-
+ connectionStateSink.complete();
messageSink.complete();
-
+ tokenManager.close();
handler.close();
- super.close();
}
private void decodeDelivery(Delivery delivery) {
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
index 2525bb39dda5..e8e3452aeaab 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
@@ -3,6 +3,7 @@
package com.azure.core.amqp.implementation;
+import com.azure.core.amqp.AmqpEndpointState;
import com.azure.core.amqp.AmqpRetryPolicy;
import com.azure.core.amqp.exception.AmqpErrorCondition;
import com.azure.core.amqp.exception.AmqpErrorContext;
@@ -26,7 +27,10 @@
import org.apache.qpid.proton.message.Message;
import reactor.core.Disposable;
import reactor.core.Disposables;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.FluxSink;
import reactor.core.publisher.Mono;
+import reactor.core.publisher.ReplayProcessor;
import java.io.IOException;
import java.io.Serializable;
@@ -50,7 +54,7 @@
/**
* Handles scheduling and transmitting events through proton-j to Event Hubs service.
*/
-class ReactorSender extends EndpointStateNotifierBase implements AmqpSendLink {
+class ReactorSender implements AmqpSendLink {
private final String entityPath;
private final Sender sender;
private final SendLinkHandler handler;
@@ -65,6 +69,11 @@ class ReactorSender extends EndpointStateNotifierBase implements AmqpSendLink {
private final ConcurrentHashMap pendingSendsMap = new ConcurrentHashMap<>();
private final PriorityQueue pendingSendsQueue =
new PriorityQueue<>(1000, new DeliveryTagComparator());
+ private final ClientLogger logger = new ClientLogger(ReactorReceiver.class);
+ private final ReplayProcessor connectionStates =
+ ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
+ private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
+
private final TokenManager tokenManager;
private final MessageSerializer messageSerializer;
@@ -86,7 +95,6 @@ class ReactorSender extends EndpointStateNotifierBase implements AmqpSendLink {
ReactorSender(String entityPath, Sender sender, SendLinkHandler handler, ReactorProvider reactorProvider,
TokenManager tokenManager, MessageSerializer messageSerializer, Duration timeout, AmqpRetryPolicy retry,
int maxMessageSize) {
- super(new ClientLogger(ReactorSender.class));
this.entityPath = entityPath;
this.sender = sender;
this.handler = handler;
@@ -98,25 +106,31 @@ class ReactorSender extends EndpointStateNotifierBase implements AmqpSendLink {
this.maxMessageSize = maxMessageSize;
this.subscriptions = Disposables.composite(
- handler.getDeliveredMessages().subscribe(this::processDeliveredMessage),
+ this.handler.getDeliveredMessages().subscribe(this::processDeliveredMessage),
- handler.getLinkCredits().subscribe(credit -> {
+ this.handler.getLinkCredits().subscribe(credit -> {
logger.verbose("Credits on link: {}", credit);
this.scheduleWorkOnDispatcher();
}),
- handler.getEndpointStates().subscribe(
+ this.handler.getEndpointStates().subscribe(
state -> {
- this.hasConnected.set(state == EndpointState.ACTIVE);
- this.notifyEndpointState(state);
- },
- error -> logger.error("Error encountered getting endpointState", error),
- () -> {
- logger.verbose("getLinkCredits completed.");
- hasConnected.set(false);
+ logger.verbose("Connection state: {}", state);
+ connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ }, error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }, () -> {
+ connectionStateSink.next(AmqpEndpointState.CLOSED);
+ connectionStateSink.complete();
}),
- tokenManager.getAuthorizationResults().subscribe(
+ this.handler.getErrors().subscribe(error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }),
+
+ this.tokenManager.getAuthorizationResults().subscribe(
response -> {
logger.verbose("Token refreshed: {}", response);
hasAuthorized.set(true);
@@ -129,6 +143,11 @@ class ReactorSender extends EndpointStateNotifierBase implements AmqpSendLink {
);
}
+ @Override
+ public Flux getEndpointStates() {
+ return connectionStates;
+ }
+
@Override
public Mono send(Message message) {
final int payloadSize = messageSerializer.getSize(message);
@@ -246,14 +265,8 @@ public Mono getLinkSize() {
@Override
public void close() {
subscriptions.dispose();
-
- try {
- tokenManager.close();
- } catch (IOException e) {
- logger.warning("IOException occurred trying to close tokenManager for {}.", entityPath, e);
- }
-
- super.close();
+ connectionStateSink.complete();
+ tokenManager.close();
}
private Mono send(byte[] bytes, int arrayOffset, int messageFormat) {
@@ -436,7 +449,6 @@ private void scheduleWorkOnDispatcher() {
reactorProvider.getReactorDispatcher().invoke(this::processSendWork);
} catch (IOException e) {
logger.error("Error scheduling work on reactor.", e);
- notifyError(e);
}
}
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/TokenManager.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/TokenManager.java
index cf7decc12e27..9985a6ed1b84 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/TokenManager.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/TokenManager.java
@@ -7,12 +7,10 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.io.Closeable;
-
/**
* Manages the authorization of the client to the CBS node.
*/
-public interface TokenManager extends Closeable {
+public interface TokenManager extends AutoCloseable {
/**
* Invokes an authorization call on the CBS node.
*
@@ -27,4 +25,10 @@ public interface TokenManager extends Closeable {
* @return A {@link Flux} of authorization results from the CBS node.
*/
Flux getAuthorizationResults();
+
+ /**
+ * Closes the token manager.
+ */
+ @Override
+ void close();
}
From c3cf06d39982c3c277e040d4a80fcc695d9cee25 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 13:31:39 -0800
Subject: [PATCH 14/29] Fix test errors.
---
.../EndpointStateNotifierBaseTest.java | 115 ------------------
.../implementation/ReactorConnectionTest.java | 16 +--
.../implementation/ReactorReceiverTest.java | 2 +-
.../implementation/ReactorSessionTest.java | 2 +-
.../EventHubConsumerAsyncClientTest.java | 14 +--
.../eventhubs/EventHubConsumerClientTest.java | 8 +-
6 files changed, 15 insertions(+), 142 deletions(-)
delete mode 100644 sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/EndpointStateNotifierBaseTest.java
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/EndpointStateNotifierBaseTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/EndpointStateNotifierBaseTest.java
deleted file mode 100644
index 976146091b39..000000000000
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/EndpointStateNotifierBaseTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-package com.azure.core.amqp.implementation;
-
-import com.azure.core.amqp.AmqpEndpointState;
-import com.azure.core.amqp.AmqpShutdownSignal;
-import com.azure.core.amqp.exception.AmqpErrorContext;
-import com.azure.core.amqp.exception.AmqpException;
-import com.azure.core.util.logging.ClientLogger;
-import org.apache.qpid.proton.engine.EndpointState;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import reactor.test.StepVerifier;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class EndpointStateNotifierBaseTest {
- private EndpointStateNotifierBase notifier;
-
- @BeforeEach
- public void setup() {
- notifier = new TestEndpointStateNotifierBase();
- }
-
- @AfterEach
- public void teardown() {
- notifier.close();
- }
-
- /**
- * Verify ErrorContexts are propagated to subscribers.
- */
- @Test
- public void notifyError() {
- // Arrange
- final Throwable error1 = new IllegalStateException("bad state");
- final Throwable error2 = new AmqpException(false, "test error", new AmqpErrorContext("test-namespace2"));
-
- // Act & Assert
- StepVerifier.create(notifier.getErrors())
- .then(() -> notifier.notifyError(error1))
- .expectNext(error1)
- .then(() -> notifier.notifyError(error2))
- .expectNext(error2)
- .then(() -> notifier.close())
- .verifyComplete();
- }
-
- /**
- * Verify AmqpShutdownSignals are propagated to subscribers.
- */
- @Test
- public void notifyShutdown() {
- // Arrange
- final AmqpShutdownSignal shutdownSignal = new AmqpShutdownSignal(false, true, "test-shutdown");
- final AmqpShutdownSignal shutdownSignal2 = new AmqpShutdownSignal(true, false, "test-shutdown2");
-
- // Act & Assert
- StepVerifier.create(notifier.getShutdownSignals())
- .then(() -> {
- notifier.notifyShutdown(shutdownSignal);
- notifier.notifyShutdown(shutdownSignal2);
- })
- .expectNext(shutdownSignal, shutdownSignal2)
- .then(() -> notifier.close())
- .verifyComplete();
- }
-
- /**
- * Verify endpoint states are propagated to subscribers and the connection state property is updated.
- */
- @Test
- public void notifyEndpointState() {
- Assertions.assertEquals(AmqpEndpointState.UNINITIALIZED, notifier.getCurrentState());
-
- StepVerifier.create(notifier.getConnectionStates())
- .expectNext(AmqpEndpointState.UNINITIALIZED)
- .then(() -> notifier.notifyEndpointState(EndpointState.ACTIVE))
- .assertNext(state -> {
- Assertions.assertEquals(AmqpEndpointState.ACTIVE, state);
- Assertions.assertEquals(AmqpEndpointState.ACTIVE, notifier.getCurrentState());
- })
- .then(() -> {
- notifier.notifyEndpointState(EndpointState.CLOSED);
- notifier.notifyEndpointState(EndpointState.UNINITIALIZED);
- })
- .expectNext(AmqpEndpointState.CLOSED, AmqpEndpointState.UNINITIALIZED)
- .then(() -> notifier.close())
- .verifyComplete();
- }
-
- @Test
- public void notifyErrorNull() {
- assertThrows(NullPointerException.class, () -> notifier.notifyError(null));
- }
-
- @Test
- public void notifyShutdownNull() {
- assertThrows(NullPointerException.class, () -> notifier.notifyShutdown(null));
- }
-
- @Test
- public void notifyEndpointStateStateNull() {
- assertThrows(NullPointerException.class, () -> notifier.notifyEndpointState(null));
- }
-
- private static class TestEndpointStateNotifierBase extends EndpointStateNotifierBase {
- TestEndpointStateNotifierBase() {
- super(new ClientLogger(TestEndpointStateNotifierBase.class));
- }
- }
-}
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
index 365c294c6666..daa507c317e1 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
@@ -216,14 +216,10 @@ public void removeSessionThatDoesNotExist() {
@Test
public void initialConnectionState() {
// Assert
- StepVerifier.create(connection.getConnectionStates())
+ StepVerifier.create(connection.getEndpointStates())
.expectNext(AmqpEndpointState.UNINITIALIZED)
.then(() -> {
- try {
- connection.close();
- } catch (IOException e) {
- Assertions.fail("Should not have thrown an error.");
- }
+ connection.close();
})
.verifyComplete();
}
@@ -241,18 +237,14 @@ public void onConnectionStateOpen() {
when(connectionProtonJ.getRemoteState()).thenReturn(EndpointState.ACTIVE);
// Act & Assert
- StepVerifier.create(connection.getConnectionStates())
+ StepVerifier.create(connection.getEndpointStates())
.expectNext(AmqpEndpointState.UNINITIALIZED)
.then(() -> connectionHandler.onConnectionRemoteOpen(event))
.expectNext(AmqpEndpointState.ACTIVE)
// getConnectionStates is distinct. We don't expect to see another event with the same status.
.then(() -> connectionHandler.onConnectionRemoteOpen(event))
.then(() -> {
- try {
- connection.close();
- } catch (IOException e) {
- Assertions.fail("Should not have thrown an error.");
- }
+ connection.close();
})
.verifyComplete();
}
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java
index 1f9e125b04c2..2eef8f7b0783 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java
@@ -85,7 +85,7 @@ public void addCredits() {
*/
@Test
public void updateEndpointState() {
- StepVerifier.create(reactorReceiver.getConnectionStates())
+ StepVerifier.create(reactorReceiver.getEndpointStates())
.expectNext(AmqpEndpointState.UNINITIALIZED)
.then(() -> receiverHandler.onLinkRemoteOpen(event))
.expectNext(AmqpEndpointState.ACTIVE)
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
index c5669df3e776..1b55148e6775 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
@@ -97,7 +97,7 @@ public void verifyConstructor() {
public void verifyEndpointStates() {
when(session.getLocalState()).thenReturn(EndpointState.ACTIVE);
- StepVerifier.create(reactorSession.getConnectionStates())
+ StepVerifier.create(reactorSession.getEndpointStates())
.expectNext(AmqpEndpointState.UNINITIALIZED)
.then(() -> handler.onSessionRemoteOpen(event))
.expectNext(AmqpEndpointState.ACTIVE)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
index 5ccebcce0be9..b07d38c91159 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
@@ -112,7 +112,7 @@ public void setup() {
when(amqpReceiveLink.receive()).thenReturn(messageProcessor);
when(amqpReceiveLink.getErrors()).thenReturn(errorProcessor);
- when(amqpReceiveLink.getConnectionStates()).thenReturn(endpointProcessor);
+ when(amqpReceiveLink.getEndpointStates()).thenReturn(endpointProcessor);
when(amqpReceiveLink.getShutdownSignals()).thenReturn(shutdownProcessor);
connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
@@ -224,13 +224,13 @@ public void returnsNewListener() {
when(link2.receive()).thenReturn(processor2);
when(link2.getErrors()).thenReturn(Flux.never());
- when(link2.getConnectionStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
when(link2.getShutdownSignals()).thenReturn(Flux.never());
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
when(link3.getErrors()).thenReturn(Flux.never());
- when(link3.getConnectionStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
when(link3.getShutdownSignals()).thenReturn(Flux.never());
when(link3.getCredits()).thenReturn(numberOfEvents);
@@ -542,13 +542,13 @@ public void receivesMultiplePartitions() {
when(link2.receive()).thenReturn(processor2);
when(link2.getErrors()).thenReturn(Flux.never());
- when(link2.getConnectionStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
when(link2.getShutdownSignals()).thenReturn(Flux.never());
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
when(link3.getErrors()).thenReturn(Flux.never());
- when(link3.getConnectionStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
when(link3.getShutdownSignals()).thenReturn(Flux.never());
when(link3.getCredits()).thenReturn(numberOfEvents);
@@ -620,13 +620,13 @@ public void receivesMultiplePartitionsWhenOneCloses() {
when(link2.receive()).thenReturn(processor2);
when(link2.getErrors()).thenReturn(Flux.never());
- when(link2.getConnectionStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
when(link2.getShutdownSignals()).thenReturn(Flux.never());
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
when(link3.getErrors()).thenReturn(Flux.never());
- when(link3.getConnectionStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
when(link3.getShutdownSignals()).thenReturn(Flux.never());
when(link3.getCredits()).thenReturn(numberOfEvents);
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java
index 355f6fe2bcfe..b6d2774faa0c 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerClientTest.java
@@ -94,9 +94,7 @@ public void setup() {
MockitoAnnotations.initMocks(this);
when(amqpReceiveLink.receive()).thenReturn(messageProcessor);
- when(amqpReceiveLink.getErrors()).thenReturn(Flux.never());
- when(amqpReceiveLink.getConnectionStates()).thenReturn(Flux.never());
- when(amqpReceiveLink.getShutdownSignals()).thenReturn(Flux.never());
+ when(amqpReceiveLink.getEndpointStates()).thenReturn(Flux.never());
when(amqpReceiveLink.getCredits()).thenReturn(10);
connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
@@ -237,9 +235,7 @@ public void receivesMultipleTimes() {
EmitterProcessor processor = EmitterProcessor.create(100, false);
FluxSink sink2 = processor.sink(FluxSink.OverflowStrategy.BUFFER);
when(amqpReceiveLink2.receive()).thenReturn(processor);
- when(amqpReceiveLink2.getErrors()).thenReturn(Flux.never());
- when(amqpReceiveLink2.getConnectionStates()).thenReturn(Flux.never());
- when(amqpReceiveLink2.getShutdownSignals()).thenReturn(Flux.never());
+ when(amqpReceiveLink2.getEndpointStates()).thenReturn(Flux.never());
when(amqpReceiveLink2.getCredits()).thenReturn(10);
// Act
From 815c7897da45b54e16b454fb548d454d135a6a05 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 14:11:49 -0800
Subject: [PATCH 15/29] Fix close build issue.
---
.../amqp/implementation/ReactorSession.java | 65 +++++++++++--------
.../eventhubs/EventHubConnection.java | 14 +---
.../EventHubPartitionAsyncConsumer.java | 28 +++-----
.../EventHubManagementNode.java | 8 +--
.../EventHubReactorSession.java | 3 +
.../implementation/ManagementChannel.java | 5 +-
6 files changed, 57 insertions(+), 66 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java
index ec1de026de24..803a57e7e22a 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java
@@ -19,26 +19,34 @@
import org.apache.qpid.proton.amqp.transport.ReceiverSettleMode;
import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
import org.apache.qpid.proton.engine.BaseHandler;
-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 reactor.core.Disposable;
import reactor.core.Disposables;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.FluxSink;
import reactor.core.publisher.Mono;
+import reactor.core.publisher.ReplayProcessor;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Represents an AMQP session using proton-j reactor.
*/
-public class ReactorSession extends EndpointStateNotifierBase implements AmqpSession {
+public class ReactorSession implements AmqpSession {
private final ConcurrentMap openSendLinks = new ConcurrentHashMap<>();
private final ConcurrentMap openReceiveLinks = new ConcurrentHashMap<>();
+ private final AtomicBoolean isDisposed = new AtomicBoolean();
+ private final ClientLogger logger = new ClientLogger(ReactorSession.class);
+ private final ReplayProcessor connectionStates =
+ ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
+ private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
private final Session session;
private final SessionHandler sessionHandler;
@@ -68,7 +76,6 @@ public ReactorSession(Session session, SessionHandler sessionHandler, String ses
ReactorHandlerProvider handlerProvider, Mono cbsNodeSupplier,
TokenManagerProvider tokenManagerProvider, MessageSerializer messageSerializer,
Duration openTimeout) {
- super(new ClientLogger(ReactorSession.class));
this.session = session;
this.sessionHandler = sessionHandler;
this.handlerProvider = handlerProvider;
@@ -81,13 +88,21 @@ public ReactorSession(Session session, SessionHandler sessionHandler, String ses
this.subscriptions = Disposables.composite(
this.sessionHandler.getEndpointStates().subscribe(
- this::notifyEndpointState,
- this::notifyError,
- () -> notifyEndpointState(EndpointState.CLOSED)),
- this.sessionHandler.getErrors().subscribe(
- this::notifyError,
- this::notifyError,
- () -> notifyEndpointState(EndpointState.CLOSED)));
+ state -> {
+ logger.verbose("Connection state: {}", state);
+ connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ }, error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }, () -> {
+ connectionStateSink.next(AmqpEndpointState.CLOSED);
+ connectionStateSink.complete();
+ }),
+
+ this.sessionHandler.getErrors().subscribe(error -> {
+ logger.error("Error occurred in connection.", error);
+ connectionStateSink.error(error);
+ }));
session.open();
}
@@ -96,30 +111,26 @@ Session session() {
return this.session;
}
+ @Override
+ public Flux getEndpointStates() {
+ return connectionStates;
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void close() {
- openReceiveLinks.forEach((key, link) -> {
- try {
- link.close();
- } catch (IOException e) {
- logger.error("Error closing send link: " + key, e);
- }
- });
+ if (isDisposed.getAndSet(true)) {
+ return;
+ }
+
+ openReceiveLinks.forEach((key, link) -> link.close());
openReceiveLinks.clear();
- openSendLinks.forEach((key, link) -> {
- try {
- link.close();
- } catch (IOException e) {
- logger.error("Error closing receive link: " + key, e);
- }
- });
+ openSendLinks.forEach((key, link) -> link.close());
openSendLinks.clear();
subscriptions.dispose();
- super.close();
}
/**
@@ -146,7 +157,7 @@ public Mono createProducer(String linkName, String entityPath, Duratio
final TokenManager tokenManager = tokenManagerProvider.getTokenManager(cbsNodeSupplier, entityPath);
return RetryUtil.withRetry(
- getConnectionStates().takeUntil(state -> state == AmqpEndpointState.ACTIVE),
+ getEndpointStates().takeUntil(state -> state == AmqpEndpointState.ACTIVE),
timeout, retry)
.then(tokenManager.authorize().then(Mono.create(sink -> {
final AmqpSendLink existingSender = openSendLinks.get(linkName);
@@ -224,7 +235,7 @@ protected Mono createConsumer(String linkName, String entityPat
final TokenManager tokenManager = tokenManagerProvider.getTokenManager(cbsNodeSupplier, entityPath);
return RetryUtil.withRetry(
- getConnectionStates().takeUntil(state -> state == AmqpEndpointState.ACTIVE), timeout, retry)
+ getEndpointStates().takeUntil(state -> state == AmqpEndpointState.ACTIVE), timeout, retry)
.then(tokenManager.authorize().then(Mono.create(sink -> {
final AmqpReceiveLink existingReceiver = openReceiveLinks.get(linkName);
if (existingReceiver != null) {
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
index c3fa8c6f5053..ef7d03c6b977 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
@@ -6,7 +6,6 @@
import com.azure.core.amqp.AmqpConnection;
import com.azure.core.amqp.AmqpRetryOptions;
import com.azure.core.amqp.AmqpRetryPolicy;
-import com.azure.core.amqp.exception.AmqpErrorContext;
import com.azure.core.amqp.exception.AmqpException;
import com.azure.core.amqp.implementation.AmqpReceiveLink;
import com.azure.core.amqp.implementation.AmqpSendLink;
@@ -21,7 +20,6 @@
import reactor.core.publisher.Mono;
import java.io.Closeable;
-import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -124,15 +122,9 @@ Mono createReceiveLink(String linkName, String entityPath, Even
@Override
public void close() {
if (hasConnection.getAndSet(false)) {
- try {
- final AmqpConnection connection = currentConnection.block(connectionOptions.getRetry().getTryTimeout());
- if (connection != null) {
- connection.close();
- }
- } catch (IOException exception) {
- throw logger.logExceptionAsError(
- new AmqpException(false, "Unable to close connection to service", exception,
- new AmqpErrorContext(connectionOptions.getFullyQualifiedNamespace())));
+ final AmqpConnection connection = currentConnection.block(connectionOptions.getRetry().getTryTimeout());
+ if (connection != null) {
+ connection.close();
}
}
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java
index d7ac5006c42f..eb0b8ac77826 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java
@@ -15,8 +15,6 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.io.Closeable;
-import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@@ -26,7 +24,7 @@
* A package-private consumer responsible for reading {@link EventData} from a specific Event Hub partition in the
* context of a specific consumer group.
*/
-class EventHubPartitionAsyncConsumer implements Closeable {
+class EventHubPartitionAsyncConsumer implements AutoCloseable {
private static final AtomicReferenceFieldUpdater
RECEIVE_LINK_FIELD_UPDATER = AtomicReferenceFieldUpdater.newUpdater(
EventHubPartitionAsyncConsumer.class, AmqpReceiveLink.class, "receiveLink");
@@ -80,22 +78,13 @@ class EventHubPartitionAsyncConsumer implements Closeable {
}
});
- link.getErrors().subscribe(error -> {
- logger.info("Error received in ReceiveLink. {}", error.toString());
+ link.getEndpointStates().subscribe(
+ unused -> { },
+ error -> {
+ logger.info("Error received in AmqpReceiveLink. {}", error.toString());
- //TODO (conniey): Surface error to EmitterProcessor.
- });
-
- link.getShutdownSignals().subscribe(signal -> {
- logger.info("Shutting down. Initiated by client? {}. Reason: {}",
- signal.isInitiatedByClient(), signal.toString());
-
- try {
- close();
- } catch (IOException e) {
- logger.error("Error closing consumer: {}", e.toString());
- }
- });
+ //TODO (conniey): Propagate error to emitter and re-resubscribe for a link if it is transient.
+ });
}
return link.receive().map(message -> onMessageReceived(message));
@@ -133,10 +122,9 @@ class EventHubPartitionAsyncConsumer implements Closeable {
/**
* Disposes of the consumer by closing the underlying connection to the service.
*
- * @throws IOException if the underlying transport and its resources could not be disposed.
*/
@Override
- public void close() throws IOException {
+ public void close() {
if (!isDisposed.getAndSet(true)) {
final AmqpReceiveLink receiveLink = RECEIVE_LINK_FIELD_UPDATER.getAndSet(this, null);
if (receiveLink != null) {
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubManagementNode.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubManagementNode.java
index 871ec49a8a0f..d9d365723af2 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubManagementNode.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubManagementNode.java
@@ -3,17 +3,14 @@
package com.azure.messaging.eventhubs.implementation;
-import com.azure.core.amqp.EndpointStateNotifier;
import com.azure.messaging.eventhubs.EventHubProperties;
import com.azure.messaging.eventhubs.PartitionProperties;
import reactor.core.publisher.Mono;
-import java.io.Closeable;
-
/**
* The management node for fetching metadata about the Event Hub and its partitions.
*/
-public interface EventHubManagementNode extends EndpointStateNotifier, Closeable {
+public interface EventHubManagementNode extends AutoCloseable {
/**
* Gets the metadata associated with the Event Hub.
*
@@ -28,4 +25,7 @@ public interface EventHubManagementNode extends EndpointStateNotifier, Closeable
* @return The metadata associated with the partition.
*/
Mono getPartitionProperties(String partitionId);
+
+ @Override
+ void close();
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorSession.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorSession.java
index 5271c048e776..d6e637e26e07 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorSession.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/EventHubReactorSession.java
@@ -14,6 +14,7 @@
import com.azure.core.amqp.implementation.TokenManager;
import com.azure.core.amqp.implementation.TokenManagerProvider;
import com.azure.core.amqp.implementation.handler.SessionHandler;
+import com.azure.core.util.logging.ClientLogger;
import com.azure.messaging.eventhubs.models.EventPosition;
import com.azure.messaging.eventhubs.models.ReceiveOptions;
import org.apache.qpid.proton.amqp.Symbol;
@@ -40,6 +41,8 @@ class EventHubReactorSession extends ReactorSession implements EventHubSession {
private static final Symbol ENABLE_RECEIVER_RUNTIME_METRIC_NAME =
Symbol.valueOf(VENDOR + ":enable-receiver-runtime-metric");
+ private final ClientLogger logger = new ClientLogger(EventHubReactorSession.class);
+
/**
* Creates a new AMQP session using proton-j.
*
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/ManagementChannel.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/ManagementChannel.java
index 299679ab30ec..b5911aaa991f 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/ManagementChannel.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/implementation/ManagementChannel.java
@@ -4,13 +4,11 @@
package com.azure.messaging.eventhubs.implementation;
import com.azure.core.amqp.implementation.AmqpConstants;
-import com.azure.core.amqp.implementation.EndpointStateNotifierBase;
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.amqp.implementation.RequestResponseChannel;
import com.azure.core.amqp.implementation.TokenManagerProvider;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
-import com.azure.core.util.logging.ClientLogger;
import com.azure.messaging.eventhubs.EventHubProperties;
import com.azure.messaging.eventhubs.PartitionProperties;
import org.apache.qpid.proton.Proton;
@@ -27,7 +25,7 @@
* Channel responsible for Event Hubs related metadata and management plane operations. Management plane operations
* include another partition, increasing quotas, etc.
*/
-public class ManagementChannel extends EndpointStateNotifierBase implements EventHubManagementNode {
+public class ManagementChannel implements EventHubManagementNode {
// Well-known keys from the management service responses and requests.
public static final String MANAGEMENT_ENTITY_NAME_KEY = "name";
public static final String MANAGEMENT_PARTITION_NAME_KEY = "partition";
@@ -67,7 +65,6 @@ public class ManagementChannel extends EndpointStateNotifierBase implements Even
*/
ManagementChannel(Mono responseChannelMono, String eventHubName, TokenCredential credential,
TokenManagerProvider tokenManagerProvider, MessageSerializer messageSerializer) {
- super(new ClientLogger(ManagementChannel.class));
this.tokenManagerProvider = Objects.requireNonNull(tokenManagerProvider,
"'tokenManagerProvider' cannot be null.");
From 15b2dde277d9dbbddd8a04f8af69ac5b2296f741 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 14:19:58 -0800
Subject: [PATCH 16/29] Fix try/catch IOException.
---
.../EventHubConsumerAsyncClient.java | 63 ++++++++-----------
.../EventHubProducerAsyncClient.java | 30 +++++----
2 files changed, 40 insertions(+), 53 deletions(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClient.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClient.java
index 3190620dc142..3af7f25ef199 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClient.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClient.java
@@ -20,7 +20,6 @@
import reactor.core.publisher.Mono;
import java.io.Closeable;
-import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@@ -35,26 +34,23 @@
*
* Creating an {@link EventHubConsumerAsyncClient}
* Required parameters are {@code consumerGroup}, and credentials are required when
- * creating a consumer.
- * {@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.instantiation}
+ * creating a consumer.
{@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.instantiation}
*
* Consuming events a single partition from Event Hub
* {@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.receive#string-eventposition}
*
* Rate limiting consumption of events from Event Hub
* For event consumers that need to limit the number of events they receive at a given time, they can use {@link
- * BaseSubscriber#request(long)}.
- * {@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.receive#string-eventposition-basesubscriber}
+ * BaseSubscriber#request(long)}. {@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.receive#string-eventposition-basesubscriber}
*
* Viewing latest partition information
* Latest partition information as events are received can by setting
- * {@link ReceiveOptions#setTrackLastEnqueuedEventProperties(boolean) setTrackLastEnqueuedEventProperties} to
- * {@code true}. As events come in, explore the {@link PartitionContext} object.
- * {@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.receive#boolean-receiveoptions}
+ * {@link ReceiveOptions#setTrackLastEnqueuedEventProperties(boolean) setTrackLastEnqueuedEventProperties} to {@code
+ * true}. As events come in, explore the {@link PartitionContext} object. {@codesnippet
+ * com.azure.messaging.eventhubs.eventhubconsumerasyncclient.receive#boolean-receiveoptions}
*
*
Receiving from all partitions
* {@codesnippet com.azure.messaging.eventhubs.eventhubconsumerasyncclient.receive#boolean}
- *
*/
@ServiceClient(builder = EventHubClientBuilder.class, isAsync = true)
public class EventHubConsumerAsyncClient implements Closeable {
@@ -71,9 +67,8 @@ public class EventHubConsumerAsyncClient implements Closeable {
private final int prefetchCount;
private final boolean isSharedConnection;
/**
- * Keeps track of the open partition consumers keyed by linkName. The link name is generated as:
- * {@code "partitionId_GUID"}. For receiving from all partitions, links are prefixed with
- * {@code "all-GUID-partitionId"}.
+ * Keeps track of the open partition consumers keyed by linkName. The link name is generated as: {@code
+ * "partitionId_GUID"}. For receiving from all partitions, links are prefixed with {@code "all-GUID-partitionId"}.
*/
private final ConcurrentHashMap openPartitionConsumers =
new ConcurrentHashMap<>();
@@ -171,8 +166,8 @@ public Flux receiveFromPartition(String partitionId, EventPositi
}
/**
- * Consumes events from a single partition starting at {@code startingPosition} with a set of
- * {@link ReceiveOptions receive options}.
+ * Consumes events from a single partition starting at {@code startingPosition} with a set of {@link ReceiveOptions
+ * receive options}.
*
*
* - If receive is invoked where {@link ReceiveOptions#getOwnerLevel()} has a value, then Event Hubs service will
@@ -190,7 +185,8 @@ public Flux receiveFromPartition(String partitionId, EventPositi
* @return A stream of events for this partition. If a stream for the events was opened before, the same position
* within that partition is returned. Otherwise, events are read starting from {@code startingPosition}.
*
- * @throws NullPointerException if {@code partitionId}, {@code startingPosition}, {@code receiveOptions} is null.
+ * @throws NullPointerException if {@code partitionId}, {@code startingPosition}, {@code receiveOptions} is
+ * null.
* @throws IllegalArgumentException if {@code partitionId} is an empty string.
*/
public Flux receiveFromPartition(String partitionId, EventPosition startingPosition,
@@ -241,8 +237,9 @@ public Flux receive() {
* given partition or subset of partitions.
*
*
- * @param startReadingAtEarliestEvent {@code true} to begin reading at the first events available in each partition;
- * otherwise, reading will begin at the end of each partition seeing only new events as they are published.
+ * @param startReadingAtEarliestEvent {@code true} to begin reading at the first events available in each
+ * partition; otherwise, reading will begin at the end of each partition seeing only new events as they are
+ * published.
*
* @return A stream of events for every partition in the Event Hub.
*/
@@ -263,8 +260,9 @@ public Flux receive(boolean startReadingAtEarliestEvent) {
* given partition or subset of partitions.
*
*
- * @param startReadingAtEarliestEvent {@code true} to begin reading at the first events available in each partition;
- * otherwise, reading will begin at the end of each partition seeing only new events as they are published.
+ * @param startReadingAtEarliestEvent {@code true} to begin reading at the first events available in each
+ * partition; otherwise, reading will begin at the end of each partition seeing only new events as they are
+ * published.
* @param receiveOptions Options when receiving events from each Event Hub partition.
*
* @return A stream of events for every partition in the Event Hub.
@@ -294,24 +292,19 @@ public Flux receive(boolean startReadingAtEarliestEvent, Receive
*/
@Override
public void close() {
- if (!isDisposed.getAndSet(true)) {
- openPartitionConsumers.forEach((key, value) -> {
- try {
- value.close();
- } catch (IOException e) {
- logger.warning("Exception occurred while closing consumer for partition '{}'", key, e);
- }
- });
- openPartitionConsumers.clear();
+ if (isDisposed.getAndSet(true)) {
+ return;
+ }
+ openPartitionConsumers.forEach((key, value) -> value.close());
+ openPartitionConsumers.clear();
- if (!isSharedConnection) {
- connection.close();
- }
+ if (!isSharedConnection) {
+ connection.close();
}
}
private Flux createConsumer(String linkName, String partitionId, EventPosition startingPosition,
- ReceiveOptions receiveOptions) {
+ ReceiveOptions receiveOptions) {
return openPartitionConsumers
.computeIfAbsent(linkName, name -> {
logger.info("{}: Creating receive consumer for partition '{}'", linkName, partitionId);
@@ -324,11 +317,7 @@ private Flux createConsumer(String linkName, String partitionId,
final EventHubPartitionAsyncConsumer consumer = openPartitionConsumers.remove(linkName);
if (consumer != null) {
- try {
- consumer.close();
- } catch (IOException e) {
- logger.warning("Exception occurred while closing consumer {}", linkName, e);
- }
+ consumer.close();
}
});
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java
index 91b908e2aea9..3366fd861739 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java
@@ -28,7 +28,6 @@
import reactor.core.publisher.Mono;
import java.io.Closeable;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -134,8 +133,8 @@ public class EventHubProducerAsyncClient implements Closeable {
* load balance the messages amongst available partitions.
*/
EventHubProducerAsyncClient(String fullyQualifiedNamespace, String eventHubName, EventHubConnection connection,
- AmqpRetryOptions retryOptions, TracerProvider tracerProvider, MessageSerializer messageSerializer,
- boolean isSharedConnection) {
+ AmqpRetryOptions retryOptions, TracerProvider tracerProvider, MessageSerializer messageSerializer,
+ boolean isSharedConnection) {
this.fullyQualifiedNamespace = fullyQualifiedNamespace;
this.eventHubName = eventHubName;
this.connection = connection;
@@ -188,6 +187,7 @@ public Flux getPartitionIds() {
* events in the partition event stream.
*
* @param partitionId The unique identifier of a partition associated with the Event Hub.
+ *
* @return The set of information for the requested partition under the Event Hub this client is associated with.
*/
@ServiceMethod(returns = ReturnType.SINGLE)
@@ -208,6 +208,7 @@ public Mono createBatch() {
* Creates an {@link EventDataBatch} that can fit as many events as the transport allows.
*
* @param options A set of options used to configure the {@link EventDataBatch}.
+ *
* @return A new {@link EventDataBatch} that can fit as many events as the transport allows.
*/
public Mono createBatch(CreateBatchOptions options) {
@@ -220,7 +221,7 @@ public Mono createBatch(CreateBatchOptions options) {
final int batchMaxSize = options.getMaximumSizeInBytes();
if (!CoreUtils.isNullOrEmpty(partitionKey)
- && !CoreUtils.isNullOrEmpty(partitionId)) {
+ && !CoreUtils.isNullOrEmpty(partitionId)) {
return monoError(logger, new IllegalArgumentException(String.format(Locale.US,
"CreateBatchOptions.getPartitionKey() and CreateBatchOptions.getPartitionId() are both set. "
+ "Only one or the other can be used. partitionKey: '%s'. partitionId: '%s'",
@@ -382,6 +383,7 @@ Mono send(Flux events, SendOptions options) {
* @param batch The batch to send to the service.
*
* @return A {@link Mono} that completes when the batch is pushed to the service.
+ *
* @throws NullPointerException if {@code batch} is {@code null}.
* @see EventHubProducerAsyncClient#createBatch()
* @see EventHubProducerAsyncClient#createBatch(CreateBatchOptions)
@@ -450,7 +452,7 @@ private Mono sendInternal(Flux events, SendOptions options) {
final String partitionId = options.getPartitionId();
if (!CoreUtils.isNullOrEmpty(partitionKey)
- && !CoreUtils.isNullOrEmpty(partitionId)) {
+ && !CoreUtils.isNullOrEmpty(partitionId)) {
return monoError(logger, new IllegalArgumentException(String.format(Locale.US,
"SendOptions.getPartitionKey() and SendOptions.getPartitionId() are both set. Only one or the"
+ " other can be used. partitionKey: '%s'. partitionId: '%s'",
@@ -510,18 +512,14 @@ private Mono getSendLink(String partitionId) {
@Override
public void close() {
if (!isDisposed.getAndSet(true)) {
- openLinks.forEach((key, value) -> {
- try {
- value.close();
- } catch (IOException e) {
- logger.warning("Error closing link for partition: {}", key, e);
- }
- });
- openLinks.clear();
+ return;
+ }
- if (!isSharedConnection) {
- connection.close();
- }
+ openLinks.forEach((key, value) -> value.close());
+ openLinks.clear();
+
+ if (!isSharedConnection) {
+ connection.close();
}
}
From 0bd64d10ac475c6c4a848278d1f7aa39e9d0d4ce Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 14:49:17 -0800
Subject: [PATCH 17/29] Fixing test breaks.
---
.../eventhubs/EventHubConsumerAsyncClientTest.java | 14 --------------
.../messaging/eventhubs/IntegrationTestBase.java | 8 +++++---
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
index b07d38c91159..04acbc4f3358 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
@@ -111,9 +111,7 @@ public void setup() {
MockitoAnnotations.initMocks(this);
when(amqpReceiveLink.receive()).thenReturn(messageProcessor);
- when(amqpReceiveLink.getErrors()).thenReturn(errorProcessor);
when(amqpReceiveLink.getEndpointStates()).thenReturn(endpointProcessor);
- when(amqpReceiveLink.getShutdownSignals()).thenReturn(shutdownProcessor);
connectionOptions = new ConnectionOptions(HOSTNAME, "event-hub-path", tokenCredential,
CbsAuthorizationType.SHARED_ACCESS_SIGNATURE, AmqpTransportType.AMQP_WEB_SOCKETS, new AmqpRetryOptions(),
@@ -223,15 +221,11 @@ public void returnsNewListener() {
EventHubSession session3 = mock(EventHubSession.class);
when(link2.receive()).thenReturn(processor2);
- when(link2.getErrors()).thenReturn(Flux.never());
when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
- when(link2.getShutdownSignals()).thenReturn(Flux.never());
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
- when(link3.getErrors()).thenReturn(Flux.never());
when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
- when(link3.getShutdownSignals()).thenReturn(Flux.never());
when(link3.getCredits()).thenReturn(numberOfEvents);
when(connection1.createSession(any())).thenReturn(Mono.just(session2), Mono.just(session3));
@@ -541,15 +535,11 @@ public void receivesMultiplePartitions() {
EventHubSession session3 = mock(EventHubSession.class);
when(link2.receive()).thenReturn(processor2);
- when(link2.getErrors()).thenReturn(Flux.never());
when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
- when(link2.getShutdownSignals()).thenReturn(Flux.never());
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
- when(link3.getErrors()).thenReturn(Flux.never());
when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
- when(link3.getShutdownSignals()).thenReturn(Flux.never());
when(link3.getCredits()).thenReturn(numberOfEvents);
when(connection1.createSession(any())).thenAnswer(invocation -> {
@@ -619,15 +609,11 @@ public void receivesMultiplePartitionsWhenOneCloses() {
EventHubSession session3 = mock(EventHubSession.class);
when(link2.receive()).thenReturn(processor2);
- when(link2.getErrors()).thenReturn(Flux.never());
when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
- when(link2.getShutdownSignals()).thenReturn(Flux.never());
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
- when(link3.getErrors()).thenReturn(Flux.never());
when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
- when(link3.getShutdownSignals()).thenReturn(Flux.never());
when(link3.getCredits()).thenReturn(numberOfEvents);
when(connection1.createSession(any())).thenAnswer(invocation -> {
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java
index 6745048120af..72d212bf6e4d 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java
@@ -3,10 +3,10 @@
package com.azure.messaging.eventhubs;
+import com.azure.core.amqp.AmqpRetryOptions;
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyAuthenticationType;
import com.azure.core.amqp.ProxyOptions;
-import com.azure.core.amqp.AmqpRetryOptions;
import com.azure.core.amqp.implementation.ConnectionStringProperties;
import com.azure.core.test.TestBase;
import com.azure.core.test.TestMode;
@@ -52,6 +52,7 @@ public abstract class IntegrationTestBase extends TestBase {
private ConnectionStringProperties properties;
private Scheduler scheduler;
+ private String testName;
protected IntegrationTestBase(ClientLogger logger) {
this.logger = logger;
@@ -61,6 +62,7 @@ protected IntegrationTestBase(ClientLogger logger) {
public void setupTest(TestInfo testInfo) {
logger.info("[{}]: Performing integration test set-up.", testInfo.getDisplayName());
+ testName = testInfo.getDisplayName();
skipIfNotRecordMode();
scheduler = Schedulers.single();
@@ -247,8 +249,8 @@ protected void dispose(Closeable... closeables) {
try {
closeable.close();
} catch (IOException error) {
- logger.error(String.format("[%s]: %s didn't close properly.",
- getTestName(), closeable.getClass().getSimpleName()), error);
+ logger.error(String.format("[%s]: %s didn't close properly.", testName,
+ closeable.getClass().getSimpleName()), error);
}
}
}
From 6de70bd06aab5677cb4657e24c0978da849738d3 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 15:01:00 -0800
Subject: [PATCH 18/29] Fix assertions in test.
---
.../implementation/ReactorConnectionTest.java | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
index daa507c317e1..318ea204fbe1 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorConnectionTest.java
@@ -3,12 +3,13 @@
package com.azure.core.amqp.implementation;
-import com.azure.core.amqp.AmqpConnection;
import com.azure.core.amqp.AmqpEndpointState;
import com.azure.core.amqp.AmqpRetryMode;
import com.azure.core.amqp.AmqpRetryOptions;
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyOptions;
+import com.azure.core.amqp.exception.AmqpErrorCondition;
+import com.azure.core.amqp.exception.AmqpException;
import com.azure.core.amqp.implementation.handler.ConnectionHandler;
import com.azure.core.amqp.implementation.handler.SessionHandler;
import com.azure.core.credential.TokenCredential;
@@ -53,7 +54,7 @@ public class ReactorConnectionTest {
private static final String HOSTNAME = CREDENTIAL_INFO.getEndpoint().getHost();
private static final Scheduler SCHEDULER = Schedulers.elastic();
- private AmqpConnection connection;
+ private ReactorConnection connection;
private SessionHandler sessionHandler;
@Mock
@@ -303,7 +304,8 @@ public void cannotCreateResourcesOnFailure() {
// Arrange
final Event event = mock(Event.class);
final Transport transport = mock(Transport.class);
- final ErrorCondition errorCondition = new ErrorCondition(Symbol.getSymbol("amqp:not-found"), "Not found");
+ final AmqpErrorCondition condition = AmqpErrorCondition.NOT_FOUND;
+ final ErrorCondition errorCondition = new ErrorCondition(Symbol.getSymbol(condition.getErrorCondition()), "Not found");
when(event.getTransport()).thenReturn(transport);
when(event.getConnection()).thenReturn(connectionProtonJ);
@@ -314,10 +316,14 @@ public void cannotCreateResourcesOnFailure() {
connectionHandler.onTransportError(event);
+ // Act & Assert
StepVerifier.create(connection.getClaimsBasedSecurityNode())
- .assertNext(node -> {
- Assertions.assertTrue(node instanceof ClaimsBasedSecurityChannel);
- }).verifyComplete();
+ .expectErrorSatisfies(e -> {
+ Assertions.assertTrue(e instanceof AmqpException);
+ AmqpException amqpException = (AmqpException) e;
+ Assertions.assertEquals(condition, amqpException.getErrorCondition());
+ })
+ .verify(Duration.ofSeconds(10));
verify(transport, times(1)).unbind();
}
From 59ebdef97ec58bf6591fd5096fb597ae05c02db1 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 15:05:38 -0800
Subject: [PATCH 19/29] Fixing test issue.
---
.../azure/core/amqp/implementation/ReactorSessionTest.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
index 1b55148e6775..4274613b385f 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorSessionTest.java
@@ -102,9 +102,9 @@ public void verifyEndpointStates() {
.then(() -> handler.onSessionRemoteOpen(event))
.expectNext(AmqpEndpointState.ACTIVE)
.then(() -> handler.close())
- // Expect two close notifications. One for getErrors() subscription and getEndpointStates();
- .expectNext(AmqpEndpointState.CLOSED, AmqpEndpointState.CLOSED)
+ .expectNext(AmqpEndpointState.CLOSED)
.then(() -> reactorSession.close())
- .verifyComplete();
+ .expectComplete()
+ .verify(Duration.ofSeconds(10));
}
}
From 08837ea5da996e3f59f0a519559861a4349460e9 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 15:11:54 -0800
Subject: [PATCH 20/29] Closing ReactorReceiver on errors or closures in link.
---
.../com/azure/core/amqp/implementation/ReactorReceiver.java | 6 ++++--
.../azure/core/amqp/implementation/ReactorReceiverTest.java | 5 ++++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
index 9965cd670ab8..5c2ff19d41c5 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
@@ -60,14 +60,16 @@ public class ReactorReceiver implements AmqpReceiveLink {
}, error -> {
logger.error("Error occurred in connection.", error);
connectionStateSink.error(error);
+ close();
}, () -> {
connectionStateSink.next(AmqpEndpointState.CLOSED);
- connectionStateSink.complete();
+ close();
}),
this.handler.getErrors().subscribe(error -> {
- logger.error("Error occurred in connection.", error);
+ logger.error("Error occurred in link.", error);
connectionStateSink.error(error);
+ close();
}),
this.tokenManager.getAuthorizationResults().subscribe(
diff --git a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java
index 2eef8f7b0783..fe7c25aeb2a0 100644
--- a/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java
+++ b/sdk/core/azure-core-amqp/src/test/java/com/azure/core/amqp/implementation/ReactorReceiverTest.java
@@ -26,6 +26,8 @@
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
+import java.time.Duration;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -149,6 +151,7 @@ public void closesOnNonAmqpException() {
// Act & Assert
StepVerifier.create(reactorReceiver.receive())
.then(() -> receiverHandler.onLinkRemoteClose(event))
- .verifyComplete();
+ .expectComplete()
+ .verify(Duration.ofSeconds(10));
}
}
From 868a2dbc9c93c1a1c85a16055878be947000f2d0 Mon Sep 17 00:00:00 2001
From: Connie
Date: Fri, 22 Nov 2019 15:38:31 -0800
Subject: [PATCH 21/29] Fix test failures.
---
.../EventHubPartitionAsyncConsumer.java | 10 +++++--
.../EventHubConsumerAsyncClientTest.java | 29 +++++++++----------
2 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java
index eb0b8ac77826..1cf12f0b96b0 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubPartitionAsyncConsumer.java
@@ -79,11 +79,18 @@ class EventHubPartitionAsyncConsumer implements AutoCloseable {
});
link.getEndpointStates().subscribe(
- unused -> { },
+ state -> {
+ logger.verbose("Endpoint state: {}", state);
+ },
error -> {
logger.info("Error received in AmqpReceiveLink. {}", error.toString());
//TODO (conniey): Propagate error to emitter and re-resubscribe for a link if it is transient.
+ close();
+ },
+ () -> {
+ logger.info("Amqp receive link shutting down.");
+ close();
});
}
@@ -121,7 +128,6 @@ class EventHubPartitionAsyncConsumer implements AutoCloseable {
/**
* Disposes of the consumer by closing the underlying connection to the service.
- *
*/
@Override
public void close() {
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
index 04acbc4f3358..1864337818a9 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubConsumerAsyncClientTest.java
@@ -5,7 +5,6 @@
import com.azure.core.amqp.AmqpEndpointState;
import com.azure.core.amqp.AmqpRetryOptions;
-import com.azure.core.amqp.AmqpShutdownSignal;
import com.azure.core.amqp.AmqpTransportType;
import com.azure.core.amqp.ProxyOptions;
import com.azure.core.amqp.implementation.AmqpReceiveLink;
@@ -43,7 +42,6 @@
import reactor.core.scheduler.Schedulers;
import reactor.test.StepVerifier;
-import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
@@ -84,10 +82,8 @@ public class EventHubConsumerAsyncClientTest {
private final ClientLogger logger = new ClientLogger(EventHubConsumerAsyncClientTest.class);
private final String messageTrackingUUID = UUID.randomUUID().toString();
- private final Flux errorProcessor = Flux.never();
- private final Flux endpointProcessor = Flux.never();
+ private final DirectProcessor endpointProcessor = DirectProcessor.create();
private final DirectProcessor messageProcessor = DirectProcessor.create();
- private final DirectProcessor shutdownProcessor = DirectProcessor.create();
@Mock
private AmqpReceiveLink amqpReceiveLink;
@@ -221,11 +217,11 @@ public void returnsNewListener() {
EventHubSession session3 = mock(EventHubSession.class);
when(link2.receive()).thenReturn(processor2);
- when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link2.getEndpointStates()).thenReturn(Flux.create(sink -> sink.next(AmqpEndpointState.ACTIVE)));
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
- when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link3.getEndpointStates()).thenReturn(Flux.create(sink -> sink.next(AmqpEndpointState.ACTIVE)));
when(link3.getCredits()).thenReturn(numberOfEvents);
when(connection1.createSession(any())).thenReturn(Mono.just(session2), Mono.just(session3));
@@ -441,12 +437,10 @@ public void suppliesNoCreditsWhenNoSubscribers() {
* Verifies that the consumer closes and completes any listeners on a shutdown signal.
*/
@Test
- public void listensToShutdownSignals() throws InterruptedException, IOException {
+ public void listensToShutdownSignals() throws InterruptedException {
// Arrange
final int numberOfEvents = 7;
final CountDownLatch shutdownReceived = new CountDownLatch(3);
- final AmqpShutdownSignal shutdownSignal = new AmqpShutdownSignal(false, false,
- "Test message");
when(amqpReceiveLink.getCredits()).thenReturn(numberOfEvents);
@@ -478,7 +472,8 @@ public void listensToShutdownSignals() throws InterruptedException, IOException
// Act
sendMessages(messageProcessor.sink(), numberOfEvents, PARTITION_ID);
- shutdownProcessor.onNext(shutdownSignal);
+ endpointProcessor.onNext(AmqpEndpointState.CLOSED);
+ endpointProcessor.onComplete();
// Assert
try {
@@ -535,11 +530,11 @@ public void receivesMultiplePartitions() {
EventHubSession session3 = mock(EventHubSession.class);
when(link2.receive()).thenReturn(processor2);
- when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link2.getEndpointStates()).thenReturn(Flux.create(sink -> sink.next(AmqpEndpointState.ACTIVE)));
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
- when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link3.getEndpointStates()).thenReturn(Flux.create(sink -> sink.next(AmqpEndpointState.ACTIVE)));
when(link3.getCredits()).thenReturn(numberOfEvents);
when(connection1.createSession(any())).thenAnswer(invocation -> {
@@ -609,11 +604,15 @@ public void receivesMultiplePartitionsWhenOneCloses() {
EventHubSession session3 = mock(EventHubSession.class);
when(link2.receive()).thenReturn(processor2);
- when(link2.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link2.getEndpointStates()).thenReturn(Flux.create(sink -> {
+ sink.next(AmqpEndpointState.ACTIVE);
+ }));
when(link2.getCredits()).thenReturn(numberOfEvents);
when(link3.receive()).thenReturn(processor3);
- when(link3.getEndpointStates()).thenReturn(Flux.just(AmqpEndpointState.ACTIVE));
+ when(link3.getEndpointStates()).thenReturn(Flux.create(sink -> {
+ sink.next(AmqpEndpointState.ACTIVE);
+ }));
when(link3.getCredits()).thenReturn(numberOfEvents);
when(connection1.createSession(any())).thenAnswer(invocation -> {
From 7911c724d728fc71fc80401f0bba3598a9a1f663 Mon Sep 17 00:00:00 2001
From: Connie
Date: Sat, 23 Nov 2019 10:13:25 -0800
Subject: [PATCH 22/29] Fixing checkstyle issue.
---
.../java/com/azure/core/amqp/implementation/ReactorSender.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
index e8e3452aeaab..10c39eea20b5 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
@@ -69,7 +69,7 @@ class ReactorSender implements AmqpSendLink {
private final ConcurrentHashMap pendingSendsMap = new ConcurrentHashMap<>();
private final PriorityQueue pendingSendsQueue =
new PriorityQueue<>(1000, new DeliveryTagComparator());
- private final ClientLogger logger = new ClientLogger(ReactorReceiver.class);
+ private final ClientLogger logger = new ClientLogger(ReactorSender.class);
private final ReplayProcessor connectionStates =
ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
From 45fc1000899d56c5ed5e0a1678a373ebfeee94db Mon Sep 17 00:00:00 2001
From: Connie
Date: Sat, 23 Nov 2019 21:04:29 -0800
Subject: [PATCH 23/29] Fixing tests.
---
.../eventhubs/EventHubConnection.java | 38 +++++++++----------
.../EventHubProducerAsyncClient.java | 2 +-
.../EventHubProducerAsyncClientTest.java | 24 +++++++++++-
.../eventhubs/IntegrationTestBase.java | 1 +
4 files changed, 42 insertions(+), 23 deletions(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
index 5a030502f611..30424e04c22e 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
@@ -73,12 +73,13 @@ Mono getManagementNode() {
}
/**
- * Creates or gets a send link. The same link is returned if there is an existing send link with the same
- * {@code linkName}. Otherwise, a new link is created and returned.
+ * Creates or gets a send link. The same link is returned if there is an existing send link with the same {@code
+ * linkName}. Otherwise, a new link is created and returned.
*
* @param linkName The name of the link.
* @param entityPath The remote address to connect to for the message broker.
* @param retryOptions Options to use when creating the link.
+ *
* @return A new or existing send link that is connected to the given {@code entityPath}.
*/
Mono createSendLink(String linkName, String entityPath, AmqpRetryOptions retryOptions) {
@@ -93,17 +94,18 @@ Mono createSendLink(String linkName, String entityPath, AmqpRetryO
}
/**
- * Creates or gets an existing receive link. The same link is returned if there is an existing receive link with
- * the same {@code linkName}. Otherwise, a new link is created and returned.
+ * Creates or gets an existing receive link. The same link is returned if there is an existing receive link with the
+ * same {@code linkName}. Otherwise, a new link is created and returned.
*
* @param linkName The name of the link.
* @param entityPath The remote address to connect to for the message broker.
* @param eventPosition Position to set the receive link to.
* @param options Consumer options to use when creating the link.
+ *
* @return A new or existing receive link that is connected to the given {@code entityPath}.
*/
Mono createReceiveLink(String linkName, String entityPath, EventPosition eventPosition,
- ReceiveOptions options) {
+ ReceiveOptions options) {
return currentConnection.flatMap(connection -> connection.createSession(entityPath).cast(EventHubSession.class))
.flatMap(session -> {
logger.verbose("Creating consumer for path: {}", entityPath);
@@ -121,21 +123,17 @@ Mono createReceiveLink(String linkName, String entityPath, Even
*/
@Override
public void close() {
- if (hasConnection.getAndSet(false)) {
- try {
- final AmqpConnection connection = currentConnection.block(connectionOptions.getRetry().getTryTimeout());
- if (connection != null) {
- connection.close();
- }
-
- if (connectionOptions.getScheduler() != null && !connectionOptions.getScheduler().isDisposed()) {
- connectionOptions.getScheduler().dispose();
- }
- } catch (IOException exception) {
- throw logger.logExceptionAsError(
- new AmqpException(false, "Unable to close connection to service", exception,
- new AmqpErrorContext(connectionOptions.getFullyQualifiedNamespace())));
- }
+ if (!hasConnection.getAndSet(false)) {
+ return;
+ }
+
+ final AmqpConnection connection = currentConnection.block(connectionOptions.getRetry().getTryTimeout());
+ if (connection != null) {
+ connection.close();
+ }
+
+ if (connectionOptions.getScheduler() != null && !connectionOptions.getScheduler().isDisposed()) {
+ connectionOptions.getScheduler().dispose();
}
}
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java
index 3366fd861739..f8559e44c997 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClient.java
@@ -511,7 +511,7 @@ private Mono getSendLink(String partitionId) {
*/
@Override
public void close() {
- if (!isDisposed.getAndSet(true)) {
+ if (isDisposed.getAndSet(true)) {
return;
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java
index 3d018ac84471..bd69306be76d 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventHubProducerAsyncClientTest.java
@@ -731,16 +731,36 @@ public void doesNotCloseSharedConnection() {
public void closesDedicatedConnection() {
// Arrange
EventHubConnection hubConnection = mock(EventHubConnection.class);
- EventHubProducerAsyncClient sharedProducer = new EventHubProducerAsyncClient(HOSTNAME, EVENT_HUB_NAME,
+ EventHubProducerAsyncClient dedicatedProducer = new EventHubProducerAsyncClient(HOSTNAME, EVENT_HUB_NAME,
hubConnection, retryOptions, tracerProvider, messageSerializer, false);
// Act
- sharedProducer.close();
+ dedicatedProducer.close();
// Verify
verify(hubConnection, times(1)).close();
}
+
+ /**
+ * Verifies that when we have a non-shared connection, the producer closes that connection. Only once.
+ */
+ @Test
+ public void closesDedicatedConnectionOnlyOnce() {
+ // Arrange
+ EventHubConnection hubConnection = mock(EventHubConnection.class);
+ EventHubProducerAsyncClient dedicatedProducer = new EventHubProducerAsyncClient(HOSTNAME, EVENT_HUB_NAME,
+ hubConnection, retryOptions, tracerProvider, messageSerializer, false);
+
+ // Act
+ dedicatedProducer.close();
+ dedicatedProducer.close();
+
+ // Verify
+ verify(hubConnection, times(1)).close();
+ }
+
+
static final String TEST_CONTENTS = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \n"
+ "Ut sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \n"
+ "Aenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \n"
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java
index 6e6e8f962c66..63270cb18124 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/IntegrationTestBase.java
@@ -49,6 +49,7 @@ public abstract class IntegrationTestBase extends TestBase {
private static final String AZURE_EVENTHUBS_EVENT_HUB_NAME = "AZURE_EVENTHUBS_EVENT_HUB_NAME";
private ConnectionStringProperties properties;
+ private String testName;
protected IntegrationTestBase(ClientLogger logger) {
this.logger = logger;
From b244790f02f95ecbb991a726bb4c97bb84ecbc9d Mon Sep 17 00:00:00 2001
From: Connie
Date: Sat, 23 Nov 2019 21:11:52 -0800
Subject: [PATCH 24/29] rename connectionStates -> endpointStates
---
.../amqp/implementation/ReactorConnection.java | 18 +++++++++---------
.../amqp/implementation/ReactorReceiver.java | 16 ++++++++--------
.../amqp/implementation/ReactorSender.java | 18 +++++++++---------
.../amqp/implementation/ReactorSession.java | 16 ++++++++--------
4 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
index 5c4c85c5f3b4..6a6393482a9d 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorConnection.java
@@ -42,9 +42,9 @@ public class ReactorConnection implements AmqpConnection {
private final AtomicBoolean hasConnection = new AtomicBoolean();
private final AtomicBoolean isDisposed = new AtomicBoolean();
private final DirectProcessor shutdownSignals = DirectProcessor.create();
- private final ReplayProcessor connectionStates =
+ private final ReplayProcessor endpointStates =
ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
- private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
+ private FluxSink endpointStatesSink = endpointStates.sink(FluxSink.OverflowStrategy.BUFFER);
private final String connectionId;
private final Mono connectionMono;
@@ -96,18 +96,18 @@ public ReactorConnection(String connectionId, ConnectionOptions connectionOption
this.handler.getEndpointStates().subscribe(
state -> {
logger.verbose("Connection state: {}", state);
- connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ endpointStatesSink.next(AmqpEndpointStateUtil.getConnectionState(state));
}, error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStatesSink.error(error);
}, () -> {
- connectionStateSink.next(AmqpEndpointState.CLOSED);
- connectionStateSink.complete();
+ endpointStatesSink.next(AmqpEndpointState.CLOSED);
+ endpointStatesSink.complete();
}),
this.handler.getErrors().subscribe(error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStatesSink.error(error);
}));
}
@@ -116,7 +116,7 @@ public ReactorConnection(String connectionId, ConnectionOptions connectionOption
*/
@Override
public Flux getEndpointStates() {
- return connectionStates;
+ return endpointStates;
}
@Override
@@ -225,7 +225,7 @@ public void close() {
}
subscriptions.dispose();
- connectionStateSink.complete();
+ endpointStatesSink.complete();
final HashMap map = new HashMap<>(sessionMap);
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
index 5c2ff19d41c5..17f829d6d65f 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorReceiver.java
@@ -38,9 +38,9 @@ public class ReactorReceiver implements AmqpReceiveLink {
private final EmitterProcessor messagesProcessor = EmitterProcessor.create();
private FluxSink messageSink = messagesProcessor.sink();
private final ClientLogger logger = new ClientLogger(ReactorReceiver.class);
- private final ReplayProcessor connectionStates =
+ private final ReplayProcessor endpointStates =
ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
- private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
+ private FluxSink endpointStateSink = endpointStates.sink(FluxSink.OverflowStrategy.BUFFER);
private volatile Supplier creditSupplier;
@@ -56,19 +56,19 @@ public class ReactorReceiver implements AmqpReceiveLink {
this.handler.getEndpointStates().subscribe(
state -> {
logger.verbose("Connection state: {}", state);
- connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ endpointStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
}, error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStateSink.error(error);
close();
}, () -> {
- connectionStateSink.next(AmqpEndpointState.CLOSED);
+ endpointStateSink.next(AmqpEndpointState.CLOSED);
close();
}),
this.handler.getErrors().subscribe(error -> {
logger.error("Error occurred in link.", error);
- connectionStateSink.error(error);
+ endpointStateSink.error(error);
close();
}),
@@ -85,7 +85,7 @@ public class ReactorReceiver implements AmqpReceiveLink {
@Override
public Flux getEndpointStates() {
- return connectionStates;
+ return endpointStates;
}
@Override
@@ -131,7 +131,7 @@ public void close() {
}
subscriptions.dispose();
- connectionStateSink.complete();
+ endpointStateSink.complete();
messageSink.complete();
tokenManager.close();
handler.close();
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
index 10c39eea20b5..c0dcb73d94d5 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
@@ -70,9 +70,9 @@ class ReactorSender implements AmqpSendLink {
private final PriorityQueue pendingSendsQueue =
new PriorityQueue<>(1000, new DeliveryTagComparator());
private final ClientLogger logger = new ClientLogger(ReactorSender.class);
- private final ReplayProcessor connectionStates =
+ private final ReplayProcessor endpointStates =
ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
- private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
+ private FluxSink endpointStateSink = endpointStates.sink(FluxSink.OverflowStrategy.BUFFER);
private final TokenManager tokenManager;
@@ -116,18 +116,18 @@ class ReactorSender implements AmqpSendLink {
this.handler.getEndpointStates().subscribe(
state -> {
logger.verbose("Connection state: {}", state);
- connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ endpointStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
}, error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStateSink.error(error);
}, () -> {
- connectionStateSink.next(AmqpEndpointState.CLOSED);
- connectionStateSink.complete();
+ endpointStateSink.next(AmqpEndpointState.CLOSED);
+ endpointStateSink.complete();
}),
this.handler.getErrors().subscribe(error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStateSink.error(error);
}),
this.tokenManager.getAuthorizationResults().subscribe(
@@ -145,7 +145,7 @@ class ReactorSender implements AmqpSendLink {
@Override
public Flux getEndpointStates() {
- return connectionStates;
+ return endpointStates;
}
@Override
@@ -265,7 +265,7 @@ public Mono getLinkSize() {
@Override
public void close() {
subscriptions.dispose();
- connectionStateSink.complete();
+ endpointStateSink.complete();
tokenManager.close();
}
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java
index 803a57e7e22a..f7a82b9523a9 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSession.java
@@ -44,9 +44,9 @@ public class ReactorSession implements AmqpSession {
private final ConcurrentMap openReceiveLinks = new ConcurrentHashMap<>();
private final AtomicBoolean isDisposed = new AtomicBoolean();
private final ClientLogger logger = new ClientLogger(ReactorSession.class);
- private final ReplayProcessor connectionStates =
+ private final ReplayProcessor endpointStates =
ReplayProcessor.cacheLastOrDefault(AmqpEndpointState.UNINITIALIZED);
- private FluxSink connectionStateSink = connectionStates.sink(FluxSink.OverflowStrategy.BUFFER);
+ private FluxSink endpointStateSink = endpointStates.sink(FluxSink.OverflowStrategy.BUFFER);
private final Session session;
private final SessionHandler sessionHandler;
@@ -90,18 +90,18 @@ public ReactorSession(Session session, SessionHandler sessionHandler, String ses
this.sessionHandler.getEndpointStates().subscribe(
state -> {
logger.verbose("Connection state: {}", state);
- connectionStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
+ endpointStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
}, error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStateSink.error(error);
}, () -> {
- connectionStateSink.next(AmqpEndpointState.CLOSED);
- connectionStateSink.complete();
+ endpointStateSink.next(AmqpEndpointState.CLOSED);
+ endpointStateSink.complete();
}),
this.sessionHandler.getErrors().subscribe(error -> {
logger.error("Error occurred in connection.", error);
- connectionStateSink.error(error);
+ endpointStateSink.error(error);
}));
session.open();
@@ -113,7 +113,7 @@ Session session() {
@Override
public Flux getEndpointStates() {
- return connectionStates;
+ return endpointStates;
}
/**
From 7b54ace2252a73b44ad14eabe24bdf3a4594b6f8 Mon Sep 17 00:00:00 2001
From: Connie
Date: Sat, 23 Nov 2019 22:12:50 -0800
Subject: [PATCH 25/29] Fix problem with sends.
---
.../com/azure/core/amqp/implementation/ReactorSender.java | 1 +
.../java/com/azure/messaging/eventhubs/BackCompatTest.java | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
index c0dcb73d94d5..18561d7adb8b 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
@@ -116,6 +116,7 @@ class ReactorSender implements AmqpSendLink {
this.handler.getEndpointStates().subscribe(
state -> {
logger.verbose("Connection state: {}", state);
+ this.hasConnected.set(state == EndpointState.ACTIVE);
endpointStateSink.next(AmqpEndpointStateUtil.getConnectionState(state));
}, error -> {
logger.error("Error occurred in connection.", error);
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/BackCompatTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/BackCompatTest.java
index 93483adeeedc..dbb62f6a9db9 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/BackCompatTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/BackCompatTest.java
@@ -19,6 +19,7 @@
import reactor.test.StepVerifier;
import java.nio.ByteBuffer;
+import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
@@ -99,7 +100,8 @@ public void backCompatWithJavaSDKOlderThan0110() {
.filter(received -> isMatchingEvent(received, messageTrackingValue)).take(1))
.then(() -> producer.send(eventData, sendOptions).block(TIMEOUT))
.assertNext(event -> validateAmqpProperties(applicationProperties, event.getData()))
- .verifyComplete();
+ .expectComplete()
+ .verify(Duration.ofSeconds(45));
}
private void validateAmqpProperties(Map expected, EventData event) {
From 66c5736041adebdee406ad94d833f155814b9c9a Mon Sep 17 00:00:00 2001
From: Connie
Date: Sun, 24 Nov 2019 00:00:18 -0800
Subject: [PATCH 26/29] Add timeouts to test.
---
.../amqp/implementation/ReactorSender.java | 1 +
.../eventhubs/InteropAmqpPropertiesTest.java | 26 +++++++++++++------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
index 18561d7adb8b..e15164a9e02d 100644
--- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
+++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java
@@ -124,6 +124,7 @@ class ReactorSender implements AmqpSendLink {
}, () -> {
endpointStateSink.next(AmqpEndpointState.CLOSED);
endpointStateSink.complete();
+ hasConnected.set(false);
}),
this.handler.getErrors().subscribe(error -> {
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
index a6643bba39e1..3bd26ce1be4e 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
@@ -7,6 +7,7 @@
import com.azure.core.amqp.implementation.MessageSerializer;
import com.azure.core.util.logging.ClientLogger;
import com.azure.messaging.eventhubs.models.EventPosition;
+import com.azure.messaging.eventhubs.models.PartitionEvent;
import com.azure.messaging.eventhubs.models.SendOptions;
import org.apache.qpid.proton.Proton;
import org.apache.qpid.proton.amqp.Binary;
@@ -20,6 +21,7 @@
import reactor.test.StepVerifier;
import java.nio.ByteBuffer;
+import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
@@ -107,25 +109,33 @@ public void interoperableWithDirectProtonAmqpMessage() {
message.setBody(new Data(Binary.create(ByteBuffer.wrap(PAYLOAD.getBytes()))));
final EventData msgEvent = serializer.deserialize(message, EventData.class);
+ final EventPosition enqueuedTime = EventPosition.fromEnqueuedTime(Instant.now());
+ producer.send(msgEvent, sendOptions).block(TIMEOUT);
+
// Act & Assert
// We're setting a tracking identifier because we don't want to receive some random operations. We want to
// receive the event we sent.
- StepVerifier.create(consumer.receiveFromPartition(PARTITION_ID, EventPosition.latest())
- .filter(event -> isMatchingEvent(event, messageTrackingValue)).take(1).map(x -> x.getData()))
- .then(() -> producer.send(msgEvent, sendOptions).block(TIMEOUT))
+ StepVerifier.create(consumer.receiveFromPartition(PARTITION_ID, enqueuedTime)
+ .filter(event -> isMatchingEvent(event, messageTrackingValue)).take(1).map(PartitionEvent::getData))
.assertNext(event -> {
validateAmqpProperties(message, expectedAnnotations, applicationProperties, event);
receivedEventData.set(event);
})
- .verifyComplete();
+ .expectComplete()
+ .verify(TIMEOUT);
Assertions.assertNotNull(receivedEventData.get());
- StepVerifier.create(consumer.receiveFromPartition(PARTITION_ID, EventPosition.latest())
- .filter(event -> isMatchingEvent(event, messageTrackingValue)).take(1).map(x -> x.getData()))
- .then(() -> producer.send(receivedEventData.get(), sendOptions).block(TIMEOUT))
+ System.out.println("Sending another event we received.");
+ final EventPosition enqueuedTime2 = EventPosition.fromEnqueuedTime(Instant.now());
+ producer.send(receivedEventData.get(), sendOptions).block(TIMEOUT);
+
+// .filter(event -> isMatchingEvent(event, messageTrackingValue))
+ StepVerifier.create(consumer.receiveFromPartition(PARTITION_ID, enqueuedTime2)
+ .take(1).map(PartitionEvent::getData))
.assertNext(event -> validateAmqpProperties(message, expectedAnnotations, applicationProperties, event))
- .verifyComplete();
+ .expectComplete()
+ .verify(TIMEOUT);
}
private void validateAmqpProperties(Message message, Map messageAnnotations,
From 00c51a7571121e01b379a4f28f5b8d204fbfa970 Mon Sep 17 00:00:00 2001
From: Connie
Date: Sun, 24 Nov 2019 10:42:11 -0800
Subject: [PATCH 27/29] Fix event position test.
---
.../messaging/eventhubs/EventPositionIntegrationTest.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventPositionIntegrationTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventPositionIntegrationTest.java
index 377f77bca46c..2d0ab37cf2eb 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventPositionIntegrationTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/EventPositionIntegrationTest.java
@@ -238,7 +238,6 @@ public void receiveMessageFromEnqueuedTimeReceivedMessage() {
}
}
-
/**
* Tests that we can get an event using the inclusive offset.
*/
@@ -275,7 +274,7 @@ public void receiveMessageFromOffsetNonInclusive() {
final EventData expectedEvent = events[4];
// Choose the offset before it, so we get that event back.
- final EventPosition position = EventPosition.fromOffset(events[3].getOffset() - 1);
+ final EventPosition position = EventPosition.fromOffset(expectedEvent.getOffset() - 1);
final EventHubConsumerAsyncClient consumer = client.createConsumer(DEFAULT_CONSUMER_GROUP_NAME, DEFAULT_PREFETCH_COUNT);
// Act & Assert
From 52976882b97c0c5ed37677df2238f25a283b4406 Mon Sep 17 00:00:00 2001
From: Connie
Date: Sun, 24 Nov 2019 17:16:12 -0800
Subject: [PATCH 28/29] Fix tests.
---
.../azure/messaging/eventhubs/InteropAmqpPropertiesTest.java | 3 ++-
.../java/com/azure/messaging/eventhubs/ProxyReceiveTest.java | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
index 3bd26ce1be4e..4a9545e72f5f 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
@@ -56,7 +56,8 @@ public InteropAmqpPropertiesTest() {
protected void beforeTest() {
sendOptions = new SendOptions().setPartitionId(PARTITION_ID);
- client = createBuilder().buildAsyncClient();
+ client = createBuilder().shareConnection()
+ .buildAsyncClient();
producer = client.createProducer();
consumer = client.createConsumer(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME, DEFAULT_PREFETCH_COUNT);
}
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/ProxyReceiveTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/ProxyReceiveTest.java
index 4515484a95a4..f6cc19fb49ba 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/ProxyReceiveTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/ProxyReceiveTest.java
@@ -76,6 +76,7 @@ public static void cleanup() throws Exception {
protected void beforeTest() {
EventHubClientBuilder builder = new EventHubClientBuilder()
.transportType(AmqpTransportType.AMQP_WEB_SOCKETS)
+ .shareConnection()
.connectionString(getConnectionString());
if (HAS_PUSHED_EVENTS.getAndSet(true)) {
From d797d21b3b2cf9ea9a6b5faf2dd34b933cbbee8b Mon Sep 17 00:00:00 2001
From: Connie
Date: Sun, 24 Nov 2019 17:41:50 -0800
Subject: [PATCH 29/29] Fixing checkstyle issues.
---
.../com/azure/messaging/eventhubs/EventHubConnection.java | 4 ++--
.../azure/messaging/eventhubs/InteropAmqpPropertiesTest.java | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
index 30424e04c22e..4b4c41c76797 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/EventHubConnection.java
@@ -73,8 +73,8 @@ Mono getManagementNode() {
}
/**
- * Creates or gets a send link. The same link is returned if there is an existing send link with the same {@code
- * linkName}. Otherwise, a new link is created and returned.
+ * Creates or gets a send link. The same link is returned if there is an existing send link with the same
+ * {@code linkName}. Otherwise, a new link is created and returned.
*
* @param linkName The name of the link.
* @param entityPath The remote address to connect to for the message broker.
diff --git a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
index 4a9545e72f5f..19ab8b864657 100644
--- a/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
+++ b/sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/InteropAmqpPropertiesTest.java
@@ -21,7 +21,6 @@
import reactor.test.StepVerifier;
import java.nio.ByteBuffer;
-import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;