ggershinsky commented on code in PR #3785:
URL: https://github.com/apache/parquet-java/pull/3785#discussion_r3979169697


##########
parquet-hadoop/src/main/java/org/apache/parquet/crypto/keytools/KmsClientFactory.java:
##########
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.parquet.crypto.keytools;
+
+/** Factory for creating {@link KmsClient} instances with programmatically 
supplied dependencies. */
+@FunctionalInterface
+public interface KmsClientFactory {
+
+  /**
+   * Creates a KMS client. {@link KeyToolkit} initializes the returned client 
before using it.
+   *
+   * @return a new or pre-built KMS client
+   */
+  KmsClient createKmsClient();

Review Comment:
   should we pass the current Configuration object here? It might have a useful 
input for creation of custom KMS clients.



##########
parquet-hadoop/src/main/java/org/apache/parquet/crypto/keytools/KeyToolkit.java:
##########
@@ -281,15 +343,64 @@ public static void rotateMasterKeys(String folderPath, 
Configuration hadoopConfi
    * @param accessToken access token
    */
   public static void removeCacheEntriesForToken(String accessToken) {
-    KMS_CLIENT_CACHE_PER_TOKEN.removeCacheEntriesForToken(accessToken);
-    KEK_WRITE_CACHE_PER_TOKEN.removeCacheEntriesForToken(accessToken);
-    KEK_READ_CACHE_PER_TOKEN.removeCacheEntriesForToken(accessToken);
+    DEFAULT_KMS_CLIENT_CACHE_CONTEXT.removeCacheEntriesForToken(accessToken);
+    synchronized (KMS_CLIENT_FACTORY_REGISTRATIONS) {
+      for (KmsClientCacheContext cacheContext : 
KMS_CLIENT_FACTORY_REGISTRATIONS.values()) {
+        cacheContext.removeCacheEntriesForToken(accessToken);
+      }
+    }
   }
 
   public static void removeCacheEntriesForAllTokens() {
-    KMS_CLIENT_CACHE_PER_TOKEN.clear();
-    KEK_WRITE_CACHE_PER_TOKEN.clear();
-    KEK_READ_CACHE_PER_TOKEN.clear();
+    DEFAULT_KMS_CLIENT_CACHE_CONTEXT.clear();
+    synchronized (KMS_CLIENT_FACTORY_REGISTRATIONS) {
+      for (KmsClientCacheContext cacheContext : 
KMS_CLIENT_FACTORY_REGISTRATIONS.values()) {
+        cacheContext.clear();
+      }
+    }
+  }
+
+  /**
+   * Sets the factory used to create KMS clients for the supplied 
configuration.
+   *
+   * <p>The factory is local to this JVM and must be set before constructing a 
reader or writer.
+   * Reflection through {@link #KMS_CLIENT_CLASS_PROPERTY_NAME} remains the 
default for other
+   * configurations. Clients returned by the factory are initialized and 
cached by {@link
+   * KeyToolkit} in the same way as reflectively constructed clients. The KMS 
client and key
+   * encryption key caches are isolated from registrations for other 
configurations.
+   *
+   * <p>The association is not serialized, and configuration copies must 
register their own
+   * factory. The caller must invoke {@link 
#removeKmsClientFactory(Configuration)} after all
+   * readers and writers using the configuration have closed. Replacing a 
factory clears the
+   * previous registration and its caches.
+   *
+   * @param configuration Hadoop configuration associated with the factory
+   * @param kmsClientFactory factory used to create KMS clients
+   */
+  public static void setKmsClientFactory(Configuration configuration, 
KmsClientFactory kmsClientFactory) {
+    Objects.requireNonNull(configuration, "configuration");
+    Objects.requireNonNull(kmsClientFactory, "kmsClientFactory");
+    KmsClientCacheContext previous =
+        KMS_CLIENT_FACTORY_REGISTRATIONS.put(configuration, new 
KmsClientCacheContext(kmsClientFactory));

Review Comment:
   What if a shell/notebook user adds some parameter to the config during a 
session?
   They'll need to call `removeKmsClientFactory` and then `setKmsClientFactory` 
each time?
   Are there usecases where config changes are hard to trace?
   Maybe there is an alternative approach? (eg using something similar to the 
kms instance, say "parquet.encryption.kms.factory.instance")



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to