turcsanyip commented on code in PR #6935:
URL: https://github.com/apache/nifi/pull/6935#discussion_r1112089266


##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/AbstractDBCPConnectionPool.java:
##########
@@ -365,168 +121,151 @@ public List<ConfigVerificationResult> verify(final 
ConfigurationContext context,
                 verificationLogger.error("Failed to shut down data source", e);
             }
         }
-
         return results;
     }
 
     /**
      * Configures connection pool by creating an instance of the
      * {@link BasicDataSource} based on configuration provided with
      * {@link ConfigurationContext}.
-     *
+     * <p>
      * This operation makes no guarantees that the actual connection could be
      * made since the underlying system may still go off-line during normal
      * operation of the connection pool.
      *
-     * @param context
-     *            the configuration context
-     * @throws InitializationException
-     *             if unable to create a database connection
+     * @param context the configuration context
+     * @throws InitializationException if unable to create a database 
connection
      */
     @OnEnabled
     public void onConfigured(final ConfigurationContext context) throws 
InitializationException {
-        kerberosUser = getKerberosUser(context);
         dataSource = new BasicDataSource();
-        configureDataSource(dataSource, kerberosUser, context);
+        kerberosUser = getKerberosUser(context);
+        loginKerberos(kerberosUser);
+        final DataSourceConfiguration configuration = 
createDataSourceConfiguraton(context);
+        configureDataSource(context, configuration);
     }
 
-    private void configureDataSource(final BasicDataSource dataSource, final 
KerberosUser kerberosUser,
-                                     final ConfigurationContext context) 
throws InitializationException {
-        final String dburl = getUrl(context);
-
-        final String driverName = 
context.getProperty(DB_DRIVERNAME).evaluateAttributeExpressions().getValue();
-        final String user = 
context.getProperty(DB_USER).evaluateAttributeExpressions().getValue();
-        final String passw = 
context.getProperty(DB_PASSWORD).evaluateAttributeExpressions().getValue();
-        final Integer maxTotal = 
context.getProperty(MAX_TOTAL_CONNECTIONS).evaluateAttributeExpressions().asInteger();
-        final String validationQuery = 
context.getProperty(VALIDATION_QUERY).evaluateAttributeExpressions().getValue();
-        final Long maxWaitMillis = 
extractMillisWithInfinite(context.getProperty(MAX_WAIT_TIME).evaluateAttributeExpressions());
-        final Integer minIdle = 
context.getProperty(MIN_IDLE).evaluateAttributeExpressions().asInteger();
-        final Integer maxIdle = 
context.getProperty(MAX_IDLE).evaluateAttributeExpressions().asInteger();
-        final Long maxConnLifetimeMillis = 
extractMillisWithInfinite(context.getProperty(MAX_CONN_LIFETIME).evaluateAttributeExpressions());
-        final Long timeBetweenEvictionRunsMillis = 
extractMillisWithInfinite(context.getProperty(EVICTION_RUN_PERIOD).evaluateAttributeExpressions());
-        final Long minEvictableIdleTimeMillis = 
extractMillisWithInfinite(context.getProperty(MIN_EVICTABLE_IDLE_TIME).evaluateAttributeExpressions());
-        final Long softMinEvictableIdleTimeMillis = 
extractMillisWithInfinite(context.getProperty(SOFT_MIN_EVICTABLE_IDLE_TIME).evaluateAttributeExpressions());
-
+    private void loginKerberos(KerberosUser kerberosUser) throws 
InitializationException {
         if (kerberosUser != null) {
             try {
                 kerberosUser.login();
             } catch (KerberosLoginException e) {
                 throw new InitializationException("Unable to authenticate 
Kerberos principal", e);
             }
         }
+    }
 
-        dataSource.setDriver(getDriver(driverName, dburl));
-        dataSource.setMaxWaitMillis(maxWaitMillis);
-        dataSource.setMaxTotal(maxTotal);
-        dataSource.setMinIdle(minIdle);
-        dataSource.setMaxIdle(maxIdle);
-        dataSource.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
-        
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        
dataSource.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
+    protected abstract Driver getDriver(final String driverName, final String 
url);
 
-        if (validationQuery != null && !validationQuery.isEmpty()) {
+    protected DataSourceConfiguration createDataSourceConfiguraton(final 
ConfigurationContext context) {

Review Comment:
   Typo:
   ```suggestion
       protected DataSourceConfiguration createDataSourceConfiguration(final 
ConfigurationContext context) {
   ```



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/AbstractDBCPConnectionPool.java:
##########
@@ -365,168 +121,151 @@ public List<ConfigVerificationResult> verify(final 
ConfigurationContext context,
                 verificationLogger.error("Failed to shut down data source", e);
             }
         }
-
         return results;
     }
 
     /**
      * Configures connection pool by creating an instance of the
      * {@link BasicDataSource} based on configuration provided with
      * {@link ConfigurationContext}.
-     *
+     * <p>
      * This operation makes no guarantees that the actual connection could be
      * made since the underlying system may still go off-line during normal
      * operation of the connection pool.
      *
-     * @param context
-     *            the configuration context
-     * @throws InitializationException
-     *             if unable to create a database connection
+     * @param context the configuration context
+     * @throws InitializationException if unable to create a database 
connection
      */
     @OnEnabled
     public void onConfigured(final ConfigurationContext context) throws 
InitializationException {
-        kerberosUser = getKerberosUser(context);
         dataSource = new BasicDataSource();
-        configureDataSource(dataSource, kerberosUser, context);
+        kerberosUser = getKerberosUser(context);
+        loginKerberos(kerberosUser);
+        final DataSourceConfiguration configuration = 
createDataSourceConfiguraton(context);
+        configureDataSource(context, configuration);
     }
 
-    private void configureDataSource(final BasicDataSource dataSource, final 
KerberosUser kerberosUser,
-                                     final ConfigurationContext context) 
throws InitializationException {
-        final String dburl = getUrl(context);
-
-        final String driverName = 
context.getProperty(DB_DRIVERNAME).evaluateAttributeExpressions().getValue();
-        final String user = 
context.getProperty(DB_USER).evaluateAttributeExpressions().getValue();
-        final String passw = 
context.getProperty(DB_PASSWORD).evaluateAttributeExpressions().getValue();
-        final Integer maxTotal = 
context.getProperty(MAX_TOTAL_CONNECTIONS).evaluateAttributeExpressions().asInteger();
-        final String validationQuery = 
context.getProperty(VALIDATION_QUERY).evaluateAttributeExpressions().getValue();
-        final Long maxWaitMillis = 
extractMillisWithInfinite(context.getProperty(MAX_WAIT_TIME).evaluateAttributeExpressions());
-        final Integer minIdle = 
context.getProperty(MIN_IDLE).evaluateAttributeExpressions().asInteger();
-        final Integer maxIdle = 
context.getProperty(MAX_IDLE).evaluateAttributeExpressions().asInteger();
-        final Long maxConnLifetimeMillis = 
extractMillisWithInfinite(context.getProperty(MAX_CONN_LIFETIME).evaluateAttributeExpressions());
-        final Long timeBetweenEvictionRunsMillis = 
extractMillisWithInfinite(context.getProperty(EVICTION_RUN_PERIOD).evaluateAttributeExpressions());
-        final Long minEvictableIdleTimeMillis = 
extractMillisWithInfinite(context.getProperty(MIN_EVICTABLE_IDLE_TIME).evaluateAttributeExpressions());
-        final Long softMinEvictableIdleTimeMillis = 
extractMillisWithInfinite(context.getProperty(SOFT_MIN_EVICTABLE_IDLE_TIME).evaluateAttributeExpressions());
-
+    private void loginKerberos(KerberosUser kerberosUser) throws 
InitializationException {
         if (kerberosUser != null) {
             try {
                 kerberosUser.login();
             } catch (KerberosLoginException e) {
                 throw new InitializationException("Unable to authenticate 
Kerberos principal", e);
             }
         }
+    }
 
-        dataSource.setDriver(getDriver(driverName, dburl));
-        dataSource.setMaxWaitMillis(maxWaitMillis);
-        dataSource.setMaxTotal(maxTotal);
-        dataSource.setMinIdle(minIdle);
-        dataSource.setMaxIdle(maxIdle);
-        dataSource.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
-        
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        
dataSource.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
+    protected abstract Driver getDriver(final String driverName, final String 
url);
 
-        if (validationQuery != null && !validationQuery.isEmpty()) {
+    protected DataSourceConfiguration createDataSourceConfiguraton(final 
ConfigurationContext context) {
+        final String url = 
context.getProperty(DBCPProperties.DATABASE_URL).getValue();
+        final String user = 
context.getProperty(DBCPProperties.DB_USER).getValue();
+        final String password = 
context.getProperty(DBCPProperties.DB_PASSWORD).getValue();
+        final String driverName = 
context.getProperty(DB_DRIVERNAME).evaluateAttributeExpressions().getValue();
+
+        return new DataSourceConfiguration.Builder(url, driverName, user, 
password)
+                .build();
+    }
+
+    protected void configureDataSource(final ConfigurationContext context, 
final DataSourceConfiguration configuration) {
+        final Driver driver = getDriver(configuration.getDriverName(), 
configuration.getUrl());
+
+        dataSource.setDriver(driver);
+        dataSource.setMaxWaitMillis(configuration.getMaxWaitMillis());
+        dataSource.setMaxTotal(configuration.getMaxTotal());
+        dataSource.setMinIdle(configuration.getMinIdle());
+        dataSource.setMaxIdle(configuration.getMaxIdle());
+        
dataSource.setMaxConnLifetimeMillis(configuration.getMaxConnLifetimeMillis());
+        
dataSource.setTimeBetweenEvictionRunsMillis(configuration.getTimeBetweenEvictionRunsMillis());
+        
dataSource.setMinEvictableIdleTimeMillis(configuration.getMinEvictableIdleTimeMillis());
+        
dataSource.setSoftMinEvictableIdleTimeMillis(configuration.getSoftMinEvictableIdleTimeMillis());
+
+        final String validationQuery = configuration.getValidationQuery();
+        if (StringUtils.isNotBlank(validationQuery)) {
             dataSource.setValidationQuery(validationQuery);
             dataSource.setTestOnBorrow(true);
         }
 
-        dataSource.setUrl(dburl);
-        dataSource.setUsername(user);
-        dataSource.setPassword(passw);
+        dataSource.setUrl(configuration.getUrl());
+        dataSource.setUsername(configuration.getUserName());
+        dataSource.setPassword(configuration.getPassword());
+
+        
getConnectionProperties(context).forEach(dataSource::addConnectionProperty);
+    }
+
+    protected Map<String, String> getConnectionProperties(final 
ConfigurationContext context) {
+        return getDynamicProperties(context)
+                .stream()
+                .collect(Collectors.toMap(PropertyDescriptor::getName, s -> {
+                    final PropertyValue propertyValue = context.getProperty(s);
+                    return 
propertyValue.evaluateAttributeExpressions().getValue();
+                }));
+    }
 
-        final List<PropertyDescriptor> dynamicProperties = 
context.getProperties()
+    protected List<PropertyDescriptor> getDynamicProperties(final 
ConfigurationContext context) {
+        return context.getProperties()
                 .keySet()
                 .stream()
                 .filter(PropertyDescriptor::isDynamic)
                 .collect(Collectors.toList());
-
-        dynamicProperties.forEach((descriptor) -> {
-            final PropertyValue propertyValue = 
context.getProperty(descriptor);
-            if (descriptor.isSensitive()) {
-                final String propertyName = 
StringUtils.substringAfter(descriptor.getName(), SENSITIVE_PROPERTY_PREFIX);
-                dataSource.addConnectionProperty(propertyName, 
propertyValue.getValue());
-            } else {
-                dataSource.addConnectionProperty(descriptor.getName(), 
propertyValue.evaluateAttributeExpressions().getValue());
-            }
-        });
-
-        
getConnectionProperties(context).forEach(dataSource::addConnectionProperty);
     }
 
-    private KerberosUser getKerberosUser(final ConfigurationContext context) {
-        KerberosUser kerberosUser = null;
-        final KerberosCredentialsService kerberosCredentialsService = 
context.getProperty(KERBEROS_CREDENTIALS_SERVICE).asControllerService(KerberosCredentialsService.class);
+    protected KerberosUser getKerberosUser(final ConfigurationContext context) 
{
+        KerberosUser kerberosUser;

Review Comment:
   ```suggestion
           final KerberosUser kerberosUser;
   ```



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DBCPProperties.java:
##########
@@ -0,0 +1,228 @@
+/*
+ * 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.dbcp.utils;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.components.resource.ResourceCardinality;
+import org.apache.nifi.components.resource.ResourceType;
+import org.apache.nifi.dbcp.DBCPValidator;
+import org.apache.nifi.expression.AttributeExpression;
+import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.kerberos.KerberosCredentialsService;
+import org.apache.nifi.kerberos.KerberosUserService;
+import org.apache.nifi.processor.util.StandardValidators;
+
+import java.util.concurrent.TimeUnit;
+
+public final class DBCPProperties {
+
+    private DBCPProperties() {
+    }
+
+    public static final PropertyDescriptor DATABASE_URL = new 
PropertyDescriptor.Builder()
+            .name("Database Connection URL")
+            .description("A database connection URL used to connect to a 
database. May contain database system name, host, port, database name and some 
parameters."
+                    + " The exact syntax of a database connection URL is 
specified by your DBMS.")
+            .defaultValue(null)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .required(true)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor DB_USER = new 
PropertyDescriptor.Builder()
+            .name("Database User")
+            .description("Database user name")
+            .defaultValue(null)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor DB_PASSWORD = new 
PropertyDescriptor.Builder()
+            .name("Password")
+            .description("The password for the database user")
+            .defaultValue(null)
+            .required(false)
+            .sensitive(true)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+
+    public static final PropertyDescriptor DB_DRIVERNAME = new 
PropertyDescriptor.Builder()
+            .name("Database Driver Class Name")
+            .description("Database driver class name")
+            .defaultValue(null)
+            .required(true)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor DB_DRIVER_LOCATION = new 
PropertyDescriptor.Builder()
+            .name("database-driver-locations")
+            .displayName("Database Driver Location(s)")
+            .description("Comma-separated list of files/folders and/or URLs 
containing the driver JAR and its dependencies (if any). For example 
'/var/tmp/mariadb-java-client-1.1.7.jar'")
+            .defaultValue(null)
+            .required(false)
+            .identifiesExternalResource(ResourceCardinality.MULTIPLE, 
ResourceType.FILE, ResourceType.DIRECTORY, ResourceType.URL)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .dynamicallyModifiesClasspath(true)
+            .build();
+
+    public static final PropertyDescriptor MAX_WAIT_TIME = new 
PropertyDescriptor.Builder()
+            .name("Max Wait Time")
+            .description("The maximum amount of time that the pool will wait 
(when there are no available connections) "
+                    + " for a connection to be returned before failing, or -1 
to wait indefinitely. ")
+            
.defaultValue(DefaultDataSourceValues.MAX_WAIT_MILLIS.getPropertyValue())
+            .required(true)
+            .addValidator(DBCPValidator.CUSTOM_TIME_PERIOD_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .sensitive(false)
+            .build();
+
+    public static final PropertyDescriptor MAX_TOTAL_CONNECTIONS = new 
PropertyDescriptor.Builder()
+            .name("Max Total Connections")
+            .description("The maximum number of active connections that can be 
allocated from this pool at the same time, "
+                    + " or negative for no limit.")
+            
.defaultValue(DefaultDataSourceValues.MAX_TOTAL_CONNECTIONS.getPropertyValue())
+            .required(true)
+            .addValidator(StandardValidators.INTEGER_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .sensitive(false)
+            .build();
+
+    public static final PropertyDescriptor VALIDATION_QUERY = new 
PropertyDescriptor.Builder()
+            .name("Validation-query")
+            .displayName("Validation query")
+            .description("Validation query used to validate connections before 
returning them. "
+                    + "When connection is invalid, it gets dropped and new 
valid connection will be returned. "
+                    + "Note!! Using validation might have some performance 
penalty.")
+            .required(false)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor MIN_IDLE = new 
PropertyDescriptor.Builder()
+            .displayName("Minimum Idle Connections")
+            .name("dbcp-min-idle-conns")
+            .description("The minimum number of connections that can remain 
idle in the pool without extra ones being " +
+                    "created. Set to or zero to allow no idle connections.")
+            .defaultValue(DefaultDataSourceValues.MIN_IDLE.getPropertyValue())
+            .required(false)
+            .addValidator(StandardValidators.NON_NEGATIVE_INTEGER_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor MAX_IDLE = new 
PropertyDescriptor.Builder()
+            .displayName("Max Idle Connections")
+            .name("dbcp-max-idle-conns")
+            .description("The maximum number of connections that can remain 
idle in the pool without extra ones being " +
+                    "released. Set to any negative value to allow unlimited 
idle connections.")
+            .defaultValue(DefaultDataSourceValues.MAX_IDLE.getPropertyValue())
+            .required(false)
+            .addValidator(StandardValidators.INTEGER_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor MAX_CONN_LIFETIME = new 
PropertyDescriptor.Builder()
+            .displayName("Max Connection Lifetime")
+            .name("dbcp-max-conn-lifetime")
+            .description("The maximum lifetime in milliseconds of a 
connection. After this time is exceeded the " +
+                    "connection will fail the next activation, passivation or 
validation test. A value of zero or less " +
+                    "means the connection has an infinite lifetime.")
+            
.defaultValue(DefaultDataSourceValues.MAX_CONN_LIFETIME.getPropertyValue())
+            .required(false)
+            .addValidator(DBCPValidator.CUSTOM_TIME_PERIOD_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor EVICTION_RUN_PERIOD = new 
PropertyDescriptor.Builder()
+            .displayName("Time Between Eviction Runs")
+            .name("dbcp-time-between-eviction-runs")
+            .description("The number of milliseconds to sleep between runs of 
the idle connection evictor thread. When " +
+                    "non-positive, no idle connection evictor thread will be 
run.")
+            
.defaultValue(DefaultDataSourceValues.EVICTION_RUN_PERIOD.getPropertyValue())
+            .required(false)
+            .addValidator(DBCPValidator.CUSTOM_TIME_PERIOD_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor MIN_EVICTABLE_IDLE_TIME = new 
PropertyDescriptor.Builder()
+            .displayName("Minimum Evictable Idle Time")
+            .name("dbcp-min-evictable-idle-time")
+            .description("The minimum amount of time a connection may sit idle 
in the pool before it is eligible for eviction.")
+            
.defaultValue(DefaultDataSourceValues.MIN_EVICTABLE_IDLE_TIME_MILLIS.getPropertyValue())
+            .required(false)
+            .addValidator(DBCPValidator.CUSTOM_TIME_PERIOD_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor SOFT_MIN_EVICTABLE_IDLE_TIME = new 
PropertyDescriptor.Builder()
+            .displayName("Soft Minimum Evictable Idle Time")
+            .name("dbcp-soft-min-evictable-idle-time")
+            .description("The minimum amount of time a connection may sit idle 
in the pool before it is eligible for " +
+                    "eviction by the idle connection evictor, with the extra 
condition that at least a minimum number of" +
+                    " idle connections remain in the pool. When the not-soft 
version of this option is set to a positive" +
+                    " value, it is examined first by the idle connection 
evictor: when idle connections are visited by " +
+                    "the evictor, idle time is first compared against it 
(without considering the number of idle " +
+                    "connections in the pool) and then against this soft 
option, including the minimum idle connections " +
+                    "constraint.")
+            
.defaultValue(DefaultDataSourceValues.SOFT_MIN_EVICTABLE_IDLE_TIME.getPropertyValue())
+            .required(false)
+            .addValidator(DBCPValidator.CUSTOM_TIME_PERIOD_VALIDATOR)
+            
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .build();
+
+    public static final PropertyDescriptor KERBEROS_CREDENTIALS_SERVICE = new 
PropertyDescriptor.Builder()

Review Comment:
   The legacy kerberos properties (`KERBEROS_CREDENTIALS_SERVICE`, 
`KERBEROS_PRINCIPAL`, `KERBEROS_PASSWORD`) should be moved to the existing 
processor(s) where they are in still use. This common code should only contain 
the current kerberos property / code.



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DefaultDataSourceValues.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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.dbcp.utils;
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+public enum DefaultDataSourceValues {
+
+
+    MAX_WAIT_MILLIS("500", "500 millis"),

Review Comment:
   I think it is not necessary to define the same value in 2 formats because 
the millisec value could be calculated from the property value using 
`FormatUtils.getTimeDuration()` (the -1 special value needs to be handled too).



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DefaultDataSourceValues.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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.dbcp.utils;
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+public enum DefaultDataSourceValues {
+
+
+    MAX_WAIT_MILLIS("500", "500 millis"),

Review Comment:
   ```suggestion
       MAX_WAIT_TIME("500", "500 millis"),
   ```
   Other constants (`MAX_CONN_LIFETIME`, `EVICTION_RUN_PERIOD`) do not have 
`_MILLIS` suffix which I think is correct because the time period can be 
defined in different time units.



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DefaultDataSourceValues.java:
##########
@@ -0,0 +1,74 @@
+/*
+ * 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.dbcp.utils;
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+public enum DefaultDataSourceValues {
+
+
+    MAX_WAIT_MILLIS("500", "500 millis"),
+
+    MAX_TOTAL_CONNECTIONS("8", "8"),
+    /**
+     * Copied from {@link GenericObjectPoolConfig#DEFAULT_MIN_IDLE} in 
Commons-DBCP 2.7.0
+     */
+    MIN_IDLE("0", "0"),
+    /**
+     * Copied from {@link GenericObjectPoolConfig#DEFAULT_MAX_IDLE} in 
Commons-DBCP 2.7.0
+     */
+    MAX_IDLE("8", "8"),
+    /**
+     * Copied from private variable {@link 
BasicDataSource#maxConnLifetimeMillis} in Commons-DBCP 2.7.0
+     */
+    MAX_CONN_LIFETIME("-1", "-1"),
+    /**
+     * Copied from {@link 
GenericObjectPoolConfig#DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS} in 
Commons-DBCP 2.7.0
+     */
+    EVICTION_RUN_PERIOD("-1", "-1"),
+    /**
+     * Copied from {@link 
GenericObjectPoolConfig#DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS} in Commons-DBCP 
2.7.0
+     * and converted from 1800000L to "1800000 millis" to "30 mins"
+     */
+    MIN_EVICTABLE_IDLE_TIME_MILLIS("1800000", "30 mins"),

Review Comment:
   ```suggestion
       MIN_EVICTABLE_IDLE_TIME("1800000", "30 mins"),
   ```
   Other constants (`MAX_CONN_LIFETIME`, `EVICTION_RUN_PERIOD`) do not have 
`_MILLIS` suffix which I think is correct because the time period can be 
defined in different time units.



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/utils/DataSourceConfiguration.java:
##########
@@ -0,0 +1,174 @@
+/*
+ * 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.dbcp.utils;
+
+public class DataSourceConfiguration {
+
+    private final long maxWaitMillis;
+    private final int maxTotal;
+    private final int minIdle;
+    private final int maxIdle;
+    private final long maxConnLifetimeMillis;
+    private final long timeBetweenEvictionRunsMillis;
+    private final long minEvictableIdleTimeMillis;
+    private final long softMinEvictableIdleTimeMillis;
+    private final String validationQuery;
+    private final String url;
+    private final String driverName;
+    private final String userName;
+    private final String password;
+
+    public long getMaxWaitMillis() {
+        return maxWaitMillis;
+    }
+
+    public int getMaxTotal() {
+        return maxTotal;
+    }
+
+    public int getMinIdle() {
+        return minIdle;
+    }
+
+    public int getMaxIdle() {
+        return maxIdle;
+    }
+
+    public long getMaxConnLifetimeMillis() {
+        return maxConnLifetimeMillis;
+    }
+
+    public long getTimeBetweenEvictionRunsMillis() {
+        return timeBetweenEvictionRunsMillis;
+    }
+
+    public long getMinEvictableIdleTimeMillis() {
+        return minEvictableIdleTimeMillis;
+    }
+
+    public long getSoftMinEvictableIdleTimeMillis() {
+        return softMinEvictableIdleTimeMillis;
+    }
+
+    public String getValidationQuery() {
+        return validationQuery;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public String getDriverName() {
+        return driverName;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public DataSourceConfiguration(final Builder builder) {
+        this.maxWaitMillis = builder.maxWaitMillis;
+        this.maxTotal = builder.maxTotal;
+        this.minIdle = builder.minIdle;
+        this.maxIdle = builder.maxIdle;
+        this.maxConnLifetimeMillis = builder.maxConnLifetimeMillis;
+        this.timeBetweenEvictionRunsMillis = 
builder.timeBetweenEvictionRunsMillis;
+        this.minEvictableIdleTimeMillis = builder.minEvictableIdleTimeMillis;
+        this.softMinEvictableIdleTimeMillis = 
builder.softMinEvictableIdleTimeMillis;
+        this.validationQuery = builder.validationQuery;
+        this.url = builder.url;
+        this.driverName = builder.driverName;
+        this.userName = builder.userName;
+        this.password = builder.password;
+    }
+
+    public static class Builder {
+        private long maxWaitMillis = 
DefaultDataSourceValues.MAX_WAIT_MILLIS.getLongValue();
+        private int maxTotal = 
DefaultDataSourceValues.MAX_TOTAL_CONNECTIONS.getIntValue();
+        private int minIdle = DefaultDataSourceValues.MIN_IDLE.getIntValue();
+        private int maxIdle = DefaultDataSourceValues.MAX_IDLE.getIntValue();
+        private long maxConnLifetimeMillis = 
DefaultDataSourceValues.MAX_CONN_LIFETIME.getLongValue();
+        private long timeBetweenEvictionRunsMillis = 
DefaultDataSourceValues.EVICTION_RUN_PERIOD.getLongValue();
+        private long minEvictableIdleTimeMillis = 
DefaultDataSourceValues.MIN_EVICTABLE_IDLE_TIME_MILLIS.getLongValue();
+        private long softMinEvictableIdleTimeMillis = 
DefaultDataSourceValues.SOFT_MIN_EVICTABLE_IDLE_TIME.getLongValue();
+        private String validationQuery;
+        private final String url;
+        private final String driverName;
+        private final String userName;
+        private final String password;

Review Comment:
   Minor, but I would move the more important and mandatory fields to the top 
(all over the class: fields, getters, etc.). Something like:
   ```
           private final String url;
           private final String driverName;
           private final String userName;
           private final String password;
           private String validationQuery;
           // other
   ```



##########
nifi-nar-bundles/nifi-extension-utils/nifi-dbcp-base/src/main/java/org/apache/nifi/dbcp/AbstractDBCPConnectionPool.java:
##########
@@ -365,168 +121,151 @@ public List<ConfigVerificationResult> verify(final 
ConfigurationContext context,
                 verificationLogger.error("Failed to shut down data source", e);
             }
         }
-
         return results;
     }
 
     /**
      * Configures connection pool by creating an instance of the
      * {@link BasicDataSource} based on configuration provided with
      * {@link ConfigurationContext}.
-     *
+     * <p>
      * This operation makes no guarantees that the actual connection could be
      * made since the underlying system may still go off-line during normal
      * operation of the connection pool.
      *
-     * @param context
-     *            the configuration context
-     * @throws InitializationException
-     *             if unable to create a database connection
+     * @param context the configuration context
+     * @throws InitializationException if unable to create a database 
connection
      */
     @OnEnabled
     public void onConfigured(final ConfigurationContext context) throws 
InitializationException {
-        kerberosUser = getKerberosUser(context);
         dataSource = new BasicDataSource();
-        configureDataSource(dataSource, kerberosUser, context);
+        kerberosUser = getKerberosUser(context);
+        loginKerberos(kerberosUser);
+        final DataSourceConfiguration configuration = 
createDataSourceConfiguraton(context);
+        configureDataSource(context, configuration);
     }
 
-    private void configureDataSource(final BasicDataSource dataSource, final 
KerberosUser kerberosUser,
-                                     final ConfigurationContext context) 
throws InitializationException {
-        final String dburl = getUrl(context);
-
-        final String driverName = 
context.getProperty(DB_DRIVERNAME).evaluateAttributeExpressions().getValue();
-        final String user = 
context.getProperty(DB_USER).evaluateAttributeExpressions().getValue();
-        final String passw = 
context.getProperty(DB_PASSWORD).evaluateAttributeExpressions().getValue();
-        final Integer maxTotal = 
context.getProperty(MAX_TOTAL_CONNECTIONS).evaluateAttributeExpressions().asInteger();
-        final String validationQuery = 
context.getProperty(VALIDATION_QUERY).evaluateAttributeExpressions().getValue();
-        final Long maxWaitMillis = 
extractMillisWithInfinite(context.getProperty(MAX_WAIT_TIME).evaluateAttributeExpressions());
-        final Integer minIdle = 
context.getProperty(MIN_IDLE).evaluateAttributeExpressions().asInteger();
-        final Integer maxIdle = 
context.getProperty(MAX_IDLE).evaluateAttributeExpressions().asInteger();
-        final Long maxConnLifetimeMillis = 
extractMillisWithInfinite(context.getProperty(MAX_CONN_LIFETIME).evaluateAttributeExpressions());
-        final Long timeBetweenEvictionRunsMillis = 
extractMillisWithInfinite(context.getProperty(EVICTION_RUN_PERIOD).evaluateAttributeExpressions());
-        final Long minEvictableIdleTimeMillis = 
extractMillisWithInfinite(context.getProperty(MIN_EVICTABLE_IDLE_TIME).evaluateAttributeExpressions());
-        final Long softMinEvictableIdleTimeMillis = 
extractMillisWithInfinite(context.getProperty(SOFT_MIN_EVICTABLE_IDLE_TIME).evaluateAttributeExpressions());
-
+    private void loginKerberos(KerberosUser kerberosUser) throws 
InitializationException {
         if (kerberosUser != null) {
             try {
                 kerberosUser.login();
             } catch (KerberosLoginException e) {
                 throw new InitializationException("Unable to authenticate 
Kerberos principal", e);
             }
         }
+    }
 
-        dataSource.setDriver(getDriver(driverName, dburl));
-        dataSource.setMaxWaitMillis(maxWaitMillis);
-        dataSource.setMaxTotal(maxTotal);
-        dataSource.setMinIdle(minIdle);
-        dataSource.setMaxIdle(maxIdle);
-        dataSource.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
-        
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        
dataSource.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
+    protected abstract Driver getDriver(final String driverName, final String 
url);
 
-        if (validationQuery != null && !validationQuery.isEmpty()) {
+    protected DataSourceConfiguration createDataSourceConfiguraton(final 
ConfigurationContext context) {
+        final String url = 
context.getProperty(DBCPProperties.DATABASE_URL).getValue();
+        final String user = 
context.getProperty(DBCPProperties.DB_USER).getValue();
+        final String password = 
context.getProperty(DBCPProperties.DB_PASSWORD).getValue();
+        final String driverName = 
context.getProperty(DB_DRIVERNAME).evaluateAttributeExpressions().getValue();
+
+        return new DataSourceConfiguration.Builder(url, driverName, user, 
password)
+                .build();
+    }

Review Comment:
   This method it not really reusable unless the child processor has this 4 
properties and no more because the configuration object is built right here and 
now.
   I think the Builder should be returned instead in order to make the building 
of the configuration object extendable.



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


Reply via email to