diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java index de64a36ea883..fbd9d79869cb 100644 --- a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java +++ b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/main/java/org/apache/nifi/dbcp/DBCPConnectionPool.java @@ -53,6 +53,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * Implementation of for Database Connection Pooling Service. Apache DBCP is used for connection pooling functionality. @@ -65,6 +66,8 @@ + "If Expression Language is used, evaluation will be performed upon the controller service being enabled. " + "Note that no flow file input (attributes, e.g.) is available for use in Expression Language constructs for these properties.") public class DBCPConnectionPool extends AbstractControllerService implements DBCPService { + /** Property Name Prefix for Sensitive Dynamic Properties */ + protected static final String SENSITIVE_PROPERTY_PREFIX = "SENSITIVE."; /** * Copied from {@link GenericObjectPoolConfig.DEFAULT_MIN_IDLE} in Commons-DBCP 2.7.0 @@ -305,14 +308,20 @@ protected List getSupportedPropertyDescriptors() { @Override protected PropertyDescriptor getSupportedDynamicPropertyDescriptor(final String propertyDescriptorName) { - return new PropertyDescriptor.Builder() + final PropertyDescriptor.Builder builder = new PropertyDescriptor.Builder() .name(propertyDescriptorName) .required(false) - .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING, true)) - .addValidator(StandardValidators.ATTRIBUTE_KEY_PROPERTY_NAME_VALIDATOR) - .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY) .dynamic(true) - .build(); + .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING, true)) + .addValidator(StandardValidators.ATTRIBUTE_KEY_PROPERTY_NAME_VALIDATOR); + + if (propertyDescriptorName.startsWith(SENSITIVE_PROPERTY_PREFIX)) { + builder.sensitive(true).expressionLanguageSupported(ExpressionLanguageScope.NONE); + } else { + builder.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY); + } + + return builder.build(); } @Override @@ -425,10 +434,21 @@ public void onConfigured(final ConfigurationContext context) throws Initializati dataSource.setUsername(user); dataSource.setPassword(passw); - context.getProperties().keySet().stream().filter(PropertyDescriptor::isDynamic) - .forEach((dynamicPropDescriptor) -> dataSource.addConnectionProperty(dynamicPropDescriptor.getName(), - context.getProperty(dynamicPropDescriptor).evaluateAttributeExpressions().getValue())); - + final List dynamicProperties = 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()); + } + }); } private Long extractMillisWithInfinite(PropertyValue prop) { diff --git a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java index 373d13e34537..58f38892466d 100644 --- a/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java +++ b/nifi-nar-bundles/nifi-standard-services/nifi-dbcp-service-bundle/nifi-dbcp-service/src/test/java/org/apache/nifi/dbcp/DBCPServiceTest.java @@ -83,6 +83,40 @@ public void testMissingPropertyValues() throws InitializationException { runner.assertNotValid(service); } + @Test + public void testDynamicProperties() throws InitializationException, SQLException { + assertConnectionNotNullDynamicProperty("create", "true"); + } + + @Test + public void testExpressionLanguageDynamicProperties() throws InitializationException, SQLException { + assertConnectionNotNullDynamicProperty("create", "${literal(1):gt(0)}"); + } + + @Test + public void testSensitiveDynamicProperties() throws InitializationException, SQLException { + assertConnectionNotNullDynamicProperty("SENSITIVE.create", "true"); + } + + private void assertConnectionNotNullDynamicProperty(final String propertyName, final String propertyValue) throws InitializationException, SQLException { + final TestRunner runner = TestRunners.newTestRunner(TestProcessor.class); + final DBCPConnectionPool service = new DBCPConnectionPool(); + runner.addControllerService(DBCPConnectionPool.class.getSimpleName(), service); + + runner.setProperty(service, DBCPConnectionPool.DATABASE_URL, "jdbc:derby:" + dbLocation); + runner.setProperty(service, DBCPConnectionPool.DB_USER, "tester"); + runner.setProperty(service, DBCPConnectionPool.DB_PASSWORD, "testerp"); + runner.setProperty(service, DBCPConnectionPool.DB_DRIVERNAME, "org.apache.derby.jdbc.EmbeddedDriver"); + runner.setProperty(service, propertyName, propertyValue); + + runner.enableControllerService(service); + runner.assertValid(service); + + try (final Connection connection = service.getConnection()) { + assertNotNull(connection); + } + } + /** * Max wait set to -1 */