This is an automated email from the ASF dual-hosted git repository.
tabish pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-protonj2.git
The following commit(s) were added to refs/heads/main by this push:
new 32eb611c PROTON-2686 Expand API docs and clean up some APIs for buffers
32eb611c is described below
commit 32eb611c3f09a58ca8f9e73dbfd81eaeaa95b029
Author: Timothy Bish <[email protected]>
AuthorDate: Wed Feb 22 18:56:16 2023 -0500
PROTON-2686 Expand API docs and clean up some APIs for buffers
Minor API cleanup for buffer cleaners and adds additional docs for some
SASL layer calls.
---
.../apache/qpid/protonj2/buffer/ProtonBuffer.java | 6 ++-
.../qpid/protonj2/buffer/ProtonBufferUtils.java | 47 +++++++++++++++++++---
.../protonj2/buffer/ProtonCompositeBuffer.java | 40 +++++++++++++++++-
.../protonj2/engine/sasl/SaslClientContext.java | 9 ++++-
.../protonj2/engine/sasl/SaslServerContext.java | 14 ++++++-
.../protonj2/engine/sasl/SaslServerListener.java | 4 +-
6 files changed, 106 insertions(+), 14 deletions(-)
diff --git
a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBuffer.java
b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBuffer.java
index 46996128..d9051672 100644
--- a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBuffer.java
+++ b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBuffer.java
@@ -597,7 +597,8 @@ public interface ProtonBuffer extends
ProtonBufferAccessors, Resource<ProtonBuff
/**
* Writes into this buffer, the given number of bytes from the byte array.
This updates the
- * {@linkplain #getWriteOffset()} of this buffer by the length argument.
+ * {@linkplain #getWriteOffset()} of this buffer by the length argument.
Implementations are
+ * recommended to specialize this method and provide a more efficient
version.
*
* @param source The byte array to read from.
* @param offset The position in the {@code source} from where bytes
should be written to this buffer.
@@ -621,7 +622,8 @@ public interface ProtonBuffer extends
ProtonBufferAccessors, Resource<ProtonBuff
/**
* Writes into this buffer from the source {@link ByteBuffer}. This
updates the
* {@link #getWriteOffset()} of this buffer and also the position of the
source
- * {@link ByteBuffer}.
+ * {@link ByteBuffer}. Implementations are recommended to specialize this
method
+ * and provide a more efficient version.
* <p>
* Note: the behavior is undefined if the given {@link ByteBuffer} is an
alias for the memory in this buffer.
*
diff --git
a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBufferUtils.java
b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBufferUtils.java
index 6c4cc847..d92bdc63 100644
---
a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBufferUtils.java
+++
b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonBufferUtils.java
@@ -34,12 +34,42 @@ public abstract class ProtonBufferUtils {
*/
public static final int MAX_BUFFER_CAPACITY = Integer.MAX_VALUE - 8;
- /**
+ /*
* Cleaner used by buffer implementations to close out wrapped or otherwise
* managed buffer resources when the buffer is no longer reachable and can
be
* garbage collected.
*/
- public static final Cleaner CLEANER = Cleaner.create();
+ private static Cleaner CLEANER;
+
+ /**
+ * Create and / or return a Cleaner instance on demand and then serve out
only that
+ * instance from then on.
+ * <p>
+ * Care should be taken when using Cleaners as the instance will be tired
to a thread that
+ * will run to perform the cleanups, an application is advised to assign a
single global
+ * value for the whole application,
+ *
+ * @return a {@link Cleaner} instance which is created on demand or was
already assigned.
+ */
+ public static synchronized Cleaner getCleaner() {
+ if (CLEANER == null) {
+ CLEANER = Cleaner.create();
+ }
+
+ return CLEANER;
+ }
+
+ /**
+ * Allows an external application {@link Cleaner} instance to be assigned
to the
+ * buffer utilities Cleaner instance which will then be used if a cleaner
for a
+ * {@link ProtonBuffer} is registered.
+ *
+ * @param cleaner
+ * The cleaner to assign as the global {@link Cleaner} for
buffer instances.
+ */
+ public static synchronized void setCleaner(Cleaner cleaner) {
+ CLEANER = cleaner;
+ }
/**
* Register a cleanup watch on the given object which is related to the
{@link ProtonBuffer}
@@ -57,7 +87,7 @@ public abstract class ProtonBufferUtils {
Objects.requireNonNull(observed, "The observed resource holder cannot
be null");
Objects.requireNonNull(buffer, "The buffer resource to be cleaned
cannot be null");
- return CLEANER.register(observed, () -> {
+ return getCleaner().register(observed, () -> {
buffer.close();
});
}
@@ -80,8 +110,8 @@ public abstract class ProtonBufferUtils {
}
/**
- * Given a {@link ProtonBuffer} returns an array containing a copy of the
readable bytes
- * from the provided buffer.
+ * Given a {@link ProtonBuffer} returns an array containing a deep copy of
the readable
+ * bytes from the provided buffer.
*
* @param buffer
* The buffer whose readable bytes are to be copied.
@@ -669,7 +699,7 @@ public abstract class ProtonBufferUtils {
if (newCapacity > MAX_BUFFER_CAPACITY) {
throw new IllegalArgumentException(
"Requested new buffer capacity {" + newCapacity +
- "}is greater than the max allowed size: " +
MAX_BUFFER_CAPACITY);
+ "} is greater than the max allowed size: " +
MAX_BUFFER_CAPACITY);
}
}
@@ -872,6 +902,10 @@ public abstract class ProtonBufferUtils {
/**
* Creates a wrapper around the given allocator that prevents the close
call
* from having any effect.
+ * <p>
+ * Care should be taken to ensure that the allocator being wrapper is safe
to leave
+ * unclosed or that the code closes it purposefully in some other context
as certain
+ * wrapped allocators might require a close to free native resources.
*
* @param allocator
* the {@link ProtonBufferAllocator} to wrap.
@@ -882,6 +916,7 @@ public abstract class ProtonBufferUtils {
return new UnclosableBufferAllocator(allocator);
}
+ // This wrapper relies on the default implementation of the close method
being a no-op
private static class UnclosableBufferAllocator implements
ProtonBufferAllocator {
private final ProtonBufferAllocator allocator;
diff --git
a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonCompositeBuffer.java
b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonCompositeBuffer.java
index b9dd4195..e3f038b2 100644
---
a/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonCompositeBuffer.java
+++
b/protonj2/src/main/java/org/apache/qpid/protonj2/buffer/ProtonCompositeBuffer.java
@@ -27,14 +27,50 @@ import
org.apache.qpid.protonj2.buffer.impl.ProtonCompositeBufferImpl;
*/
public interface ProtonCompositeBuffer extends ProtonBuffer {
+ /**
+ * Create an empty composite buffer that will use the provided allocator to
+ * create new buffer capacity if writes are performed and insufficient
space
+ * remains (unless the capacity limit is reached).
+ *
+ * @param allocator
+ * The allocator to use when adding new buffer capacity
automatically.
+ *
+ * @return a new empty composite buffer instance.
+ */
static ProtonCompositeBuffer create(ProtonBufferAllocator allocator) {
return ProtonCompositeBufferImpl.create(allocator);
}
+ /**
+ * Create an composite buffer with the given buffer instance as the
initial buffer
+ * payload. The provided buffer allocator will use the provided allocator
to create
+ * new buffer capacity if writes are performed and insufficient space
remains (unless
+ * the capacity limit is reached).
+ *
+ * @param allocator
+ * The allocator to use when adding new buffer capacity
automatically.
+ * @param buffer
+ * The initial buffer to append as the body of the
returned composite buffer.
+ *
+ * @return a new composite buffer instance that wraps the given buffer.
+ */
static ProtonCompositeBuffer create(ProtonBufferAllocator allocator,
ProtonBuffer buffer) {
return ProtonCompositeBufferImpl.create(allocator, buffer);
}
+ /**
+ * Create an composite buffer with the given array of buffers as the
initial buffer
+ * payload. The provided buffer allocator will use the provided allocator
to create
+ * new buffer capacity if writes are performed and insufficient space
remains (unless
+ * the capacity limit is reached).
+ *
+ * @param allocator
+ * The allocator to use when adding new buffer capacity
automatically.
+ * @param buffers
+ * The initial buffers to append as the body of the
returned composite buffer.
+ *
+ * @return a new composite buffer instance that wraps the given buffers.
+ */
static ProtonCompositeBuffer create(ProtonBufferAllocator allocator,
ProtonBuffer[] buffers) {
return ProtonCompositeBufferImpl.create(allocator, buffers);
}
@@ -64,8 +100,8 @@ public interface ProtonCompositeBuffer extends ProtonBuffer {
/**
* Splits the composite buffer up into a collection of buffers that
comprise it and
- * leaves this buffer in an empty state. The returned buffers are now the
property
- * of the caller.
+ * leaves this buffer in what is effectively a closed state. The returned
buffers are
+ * now the property of the caller who must ensure they are closed when no
longer in use..
*
* @return the collection of buffers that comprised this composite buffer.
*/
diff --git
a/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslClientContext.java
b/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslClientContext.java
index c23c031b..7e5e4007 100644
---
a/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslClientContext.java
+++
b/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslClientContext.java
@@ -101,7 +101,8 @@ public interface SaslClientContext extends SaslContext {
/**
* Sends a response to a server side challenge that comprises the
challenge / response
- * exchange for the chosen SASL mechanism.
+ * exchange for the chosen SASL mechanism. The server may response with
another challenge
+ * or complete the SASL exchange by sending an outcome.
*
* @param response
* The response bytes to be sent to the server for this cycle.
@@ -117,6 +118,12 @@ public interface SaslClientContext extends SaslContext {
* unrecoverable error. Failing the process will signal the engine that
the SASL process
* has failed and place the engine in a failed state as well as notify the
registered error
* handler for the {@link Engine}.
+ * <p>
+ * Once the SASL negotiation completes after an outcome has arrived
calling this method
+ * will not produce any effect as the SASL layer will be shutdown at this
point, this
+ * method is for failing negotiations that are ongoing. If a failed SASL
outcome arrives
+ * the client should take action by shutting down the engine or failing it
to trigger
+ * an event that is handled or by closing the I/O channel in use.
*
* @param failure
* The exception to report to the {@link Engine} that describes the
failure.
diff --git
a/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerContext.java
b/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerContext.java
index c2ac1a72..4d156378 100644
---
a/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerContext.java
+++
b/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerContext.java
@@ -84,7 +84,8 @@ public interface SaslServerContext extends SaslContext {
/**
* Sends the SASL challenge defined by the SASL mechanism that is in use
during
* this SASL negotiation. The challenge is an opaque binary that is
provided to
- * the server by the security mechanism.
+ * the server by the security mechanism. Upon sending a challenge the
SASL server
+ * should expect a response from the SASL client.
*
* @param challenge
* The buffer containing the server challenge.
@@ -98,6 +99,13 @@ public interface SaslServerContext extends SaslContext {
/**
* Sends a response to a server side challenge that comprises the
challenge / response
* exchange for the chosen SASL mechanism.
+ * <p>
+ * Sending an outcome that indicates SASL does not trigger a failure of
the engine or
+ * cause a shutdown, the caller must ensure that after failing the SASL
exchange the
+ * engine is shutdown or failed so that event handlers are triggered or
should pro-actively
+ * close any I/O channel that was opened. The {@link
#saslFailure(SaslException)} method
+ * has no effect once this method has been called as SASL negotiations are
considered done
+ * once an outcome is sent.
*
* @param outcome
* The outcome of the SASL negotiation to be sent to the client.
@@ -115,6 +123,10 @@ public interface SaslServerContext extends SaslContext {
* unrecoverable error. Failing the process will signal the {@link
Engine} that the SASL process
* has failed and place the engine in a failed state as well as notify the
registered error
* handler for the {@link Engine}.
+ * <p>
+ * This method will not perform any action if called after the {@link
#sendOutcome(SaslOutcome, ProtonBuffer)}
+ * method has been called as the SASL negotiation process was marked as
completed and the implementation
+ * is free to tear down SASL resources following that call.
*
* @param failure
* The exception to report to the {@link Engine} that describes the
failure.
diff --git
a/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerListener.java
b/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerListener.java
index f17d90da..2e2b29a5 100644
---
a/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerListener.java
+++
b/protonj2/src/main/java/org/apache/qpid/protonj2/engine/sasl/SaslServerListener.java
@@ -95,8 +95,8 @@ public interface SaslServerListener {
* same thread that the response handler was invoked from.
* <p>
* In the event that the server implementation cannot proceed with SASL
authentication it should call the
- * {@link
SaslServerContext#saslFailure(javax.security.sasl.SaslException)} to fail
- * the SASL negotiation and signal the {@link Engine} that it should
transition to a failed state.
+ * {@link
SaslServerContext#saslFailure(javax.security.sasl.SaslException)} to fail the
SASL negotiation
+ * and signal the {@link Engine} that it should transition to a failed
state.
*
* @param context
* the {@link SaslServerContext} object that is to process the
incoming response.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]