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]

Reply via email to