Lehel44 commented on a change in pull request #5110:
URL: https://github.com/apache/nifi/pull/5110#discussion_r644337507



##########
File path: 
nifi-commons/nifi-security-kms/src/main/java/org/apache/nifi/security/kms/KeyProviderFactory.java
##########
@@ -0,0 +1,85 @@
+/*
+ * 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.nifi.security.kms;
+
+import org.apache.commons.codec.DecoderException;
+import 
org.apache.nifi.security.kms.configuration.FileBasedKeyProviderConfiguration;
+import org.apache.nifi.security.kms.configuration.KeyProviderConfiguration;
+import 
org.apache.nifi.security.kms.configuration.KeyStoreKeyProviderConfiguration;
+import 
org.apache.nifi.security.kms.configuration.StaticKeyProviderConfiguration;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.nifi.security.kms.reader.KeyReaderException;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.KeyStore;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Key Provider Factory
+ */
+public class KeyProviderFactory {
+    private static final String SECRET_KEY_ALGORITHM = "AES";
+
+    /**
+     * Get Key Provider based on Configuration
+     *
+     * @param configuration Key Provider Configuration
+     * @return Key Provider
+     */
+    public static KeyProvider getKeyProvider(final KeyProviderConfiguration<?> 
configuration) {

Review comment:
       I've got an idea to avoid downcasting and branching here. The 
_KeyProviderConfiguration_ interface could contain a new method:
   `KeyProvider getKeyProvider(final KeyProviderCreator keyProviderCreator);`
   
   A key provider creator class could handle creating the different providers 
based on different configurations:
   
   `   public class KeyProviderCreator {
   
       private static final String SECRET_KEY_ALGORITHM = "AES";
   
       public KeyProvider getKeyProvider(final StaticKeyProviderConfiguration 
configuration) {
           final Map<String, SecretKey> secretKeys;
           try {
               secretKeys = getSecretKeys(configuration.getKeys());
               return new StaticKeyProvider(secretKeys);
           } catch (final DecoderException e) {
               throw new KeyReaderException("Decoding Hexadecimal Secret Keys 
failed", e);
           }
       }
   
       public KeyProvider getKeyProvider(final 
FileBasedKeyProviderConfiguration configuration) {
           final Path keyProviderPath = Paths.get(configuration.getLocation());
           return new FileBasedKeyProvider(keyProviderPath, 
configuration.getRootKey());
       }
   
       public KeyProvider getKeyProvider(final KeyStoreKeyProviderConfiguration 
configuration) {
           final KeyStore keyStore = configuration.getKeyStore();
           return new KeyStoreKeyProvider(keyStore, 
configuration.getKeyPassword());
       }
   
       private Map<String, SecretKey> getSecretKeys(final Map<String, String> 
keys) throws DecoderException {
           final Map<String, SecretKey> secretKeys = new HashMap<>();
   
           for (final Map.Entry<String, String> keyEntry : keys.entrySet()) {
               final byte[] encodedSecretKey = 
Hex.decodeHex(keyEntry.getValue());
               final SecretKey secretKey = new SecretKeySpec(encodedSecretKey, 
SECRET_KEY_ALGORITHM);
               secretKeys.put(keyEntry.getKey(), secretKey);
           }
   
           return secretKeys;
       }
   }`
   
   The configuration classes can utilize the creator class to make providers:
   
   `@Override
       public KeyProvider getKeyProvider(KeyProviderCreator keyProviderCreator) 
{
           return keyProviderCreator.getKeyProvider(this);
       }`
   
   And then in the factory, there's no branching remaining:
   
   `public class KeyProviderFactory {
   
       private static final KeyProviderCreator creator = new 
KeyProviderCreator();
   
       public static KeyProvider getKeyProvider(final 
KeyProviderConfiguration<?> configuration) {
           return configuration.getKeyProvider(creator);
       }
   }`
   
   What do you think of this approach? It adds a bit of extra complexity to 
other classes but withdraws some from the factory. Also this way when somebody 
adds a new configuration, they're obliged to implement the provider method.




-- 
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.

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


Reply via email to