You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@accumulo.apache.org by GitBox <gi...@apache.org> on 2022/02/16 15:22:39 UTC

[GitHub] [accumulo] ctubbsii commented on a change in pull request #2500: Make build work on Java 17

ctubbsii commented on a change in pull request #2500:
URL: https://github.com/apache/accumulo/pull/2500#discussion_r808111822



##########
File path: core/src/main/java/org/apache/accumulo/core/client/security/tokens/PasswordToken.java
##########
@@ -83,12 +86,46 @@ public PasswordToken(ByteBuffer password) {
 
   @Override
   public void readFields(DataInput arg0) throws IOException {
-    password = WritableUtils.readCompressedByteArray(arg0);
+    int version = arg0.readInt();
+    // -1 is null, consistent with legacy format; legacy format length must be >= -1
+    // so, use -2 as a magic number to indicate the new format
+    if (version == -1) {
+      password = null;
+    } else if (version == -2) {
+      byte[] passwordTmp = new byte[arg0.readInt()];
+      arg0.readFully(passwordTmp);
+      password = passwordTmp;
+    } else {
+      // legacy format; should avoid reading/writing compressed byte arrays using WritableUtils,
+      // because GZip is expensive and it doesn't actually compress passwords very well
+      AtomicBoolean calledFirstReadInt = new AtomicBoolean(false);
+      DataInput wrapped = (DataInput) Proxy.newProxyInstance(DataInput.class.getClassLoader(),
+          arg0.getClass().getInterfaces(), (obj, method, args) -> {
+            // wrap the original DataInput in order to return the integer that was read
+            // and then not used, because it didn't match -2
+            if (!calledFirstReadInt.get() && method.getName().equals("readInt")) {
+              calledFirstReadInt.set(true);
+              return version;
+            }
+            try {
+              return method.invoke(arg0, args);
+            } catch (InvocationTargetException e) {
+              throw e.getCause();
+            }
+          });
+      password = WritableUtils.readCompressedByteArray(wrapped);
+    }

Review comment:
       The original version just passed the full DataInput content to `WritableUtils.readCompressedByteArray()`. However, since I've already read the first integer from the front of the byte array, I need to inject it back into the front of the DataInput. I did that using Java's reflection Proxy to wrap the original DataInput. The first time `readInt` is called on the proxy, it provides the integer that was already previously pulled out of the original DataInput. After that, the proxy just passes through to the original DataInput.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@accumulo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org