NIFI-9883 Refactor Property Protection using Isolated ClassLoader (#5972)

* NIFI-9883 Refactored property protection to isolated ClassLoader

- Added nifi-property-protection-loader for abstracting access to implementation classes using ServiceLoader
- Updated Authorizer and Login Identity Provider configuration using isolated ClassLoader
- Updated NiFi Properties Loader using isolated ClassLoader
- Updated nifi-assembly to place property protection dependencies in lib/properties directory
- Updated and refactored unit tests
- Corrected LoginIdentityProviderFactoryBean getObject() Type
This commit is contained in:
exceptionfactory 2022-04-19 10:08:04 -05:00 committed by GitHub
parent 876e16f6a8
commit 18a4182cb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 1263 additions and 5403 deletions

View File

@ -167,6 +167,21 @@ language governing permissions and limitations under the License. -->
<artifactId>nifi-bootstrap-utils</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-utils</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-api</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-resources</artifactId>

View File

@ -29,6 +29,7 @@
<include>slf4j-api</include>
<include>logback-classic</include>
<include>nifi-api</include>
<include>nifi-property-protection-api</include>
</includes>
</dependencySet>
@ -62,6 +63,19 @@
</includes>
</dependencySet>
<!-- Write Property Protection implementation libraries to isolated directory-->
<dependencySet>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib/properties</outputDirectory>
<directoryMode>0770</directoryMode>
<fileMode>0664</fileMode>
<useTransitiveFiltering>true</useTransitiveFiltering>
<includes>
<include>nifi-property-protection-factory</include>
</includes>
</dependencySet>
<!-- Write out the conf directory contents -->
<dependencySet>
<scope>runtime</scope>

View File

@ -34,6 +34,8 @@
<excludes>
<exclude>nifi-bootstrap-utils</exclude>
<exclude>nifi-bootstrap</exclude>
<exclude>nifi-property-protection-api</exclude>
<exclude>nifi-property-protection-factory</exclude>
<exclude>nifi-resources</exclude>
<exclude>nifi-docs</exclude>

View File

@ -1,55 +0,0 @@
/*
* 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.properties;
import org.apache.nifi.properties.scheme.StandardProtectionScheme;
import java.util.function.Supplier;
/**
* Provides a default SensitivePropertyProviderFactory to subclasses.
*/
public class SensitivePropertyProviderFactoryAware {
private SensitivePropertyProviderFactory sensitivePropertyProviderFactory;
protected SensitivePropertyProviderFactory getSensitivePropertyProviderFactory() throws SensitivePropertyProtectionException {
if (sensitivePropertyProviderFactory == null) {
sensitivePropertyProviderFactory = StandardSensitivePropertyProviderFactory.withDefaults();
}
return sensitivePropertyProviderFactory;
}
protected String decryptValue(final String cipherText, final String protectionScheme, final String propertyName, final String groupIdentifier) throws SensitivePropertyProtectionException {
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory = getSensitivePropertyProviderFactory();
final ProtectedPropertyContext protectedPropertyContext = sensitivePropertyProviderFactory.getPropertyContext(groupIdentifier, propertyName);
return sensitivePropertyProviderFactory.getProvider(new StandardProtectionScheme(protectionScheme))
.unprotect(cipherText, protectedPropertyContext);
}
/**
* Configures and sets the SensitivePropertyProviderFactory.
* @param keyHex An key in hex format, which some providers may use for encryption
* @param bootstrapPropertiesSupplier The bootstrap.conf properties supplier
* @return The configured SensitivePropertyProviderFactory
*/
public SensitivePropertyProviderFactory configureSensitivePropertyProviderFactory(final String keyHex,
final Supplier<BootstrapProperties> bootstrapPropertiesSupplier) {
sensitivePropertyProviderFactory = StandardSensitivePropertyProviderFactory.withKeyAndBootstrapSupplier(keyHex, bootstrapPropertiesSupplier);
return sensitivePropertyProviderFactory;
}
}

View File

@ -66,11 +66,22 @@ public class StandardSensitivePropertyProviderFactory implements SensitiveProper
HashiCorpVaultTransitSensitivePropertyProvider.class
);
private final Optional<String> keyHex;
private Optional<String> keyHex;
private final Supplier<BootstrapProperties> bootstrapPropertiesSupplier;
private final Map<Class<? extends SensitivePropertyProvider>, SensitivePropertyProvider> providers;
private Map<String, Pattern> customPropertyContextMap;
/**
* Factory default constructor to support java.util.ServiceLoader
*/
public StandardSensitivePropertyProviderFactory() {
this(null, null);
}
public void setKeyHex(final String hexadecimalKey) {
this.keyHex = Optional.ofNullable(hexadecimalKey);
}
/**
* Creates a StandardSensitivePropertyProviderFactory using the default bootstrap.conf location and
* the keyHex extracted from this bootstrap.conf.

View File

@ -12,3 +12,4 @@
# 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.
org.apache.nifi.properties.StandardSensitivePropertyProviderFactory

View File

@ -12,3 +12,4 @@
# 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.
org.apache.nifi.properties.scheme.StandardProtectionSchemeResolver

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-commons</artifactId>
<version>1.17.0-SNAPSHOT</version>
</parent>
<artifactId>nifi-property-protection-loader</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-api</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -16,7 +16,6 @@
*/
package org.apache.nifi.properties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -158,7 +157,7 @@ public class ApplicationPropertiesProtector<T extends ProtectedProperties<U>, U
@Override
public List<String> getPopulatedSensitivePropertyKeys() {
List<String> allSensitiveKeys = getSensitivePropertyKeys();
return allSensitiveKeys.stream().filter(k -> StringUtils.isNotBlank(getProperty(k))).collect(Collectors.toList());
return allSensitiveKeys.stream().filter(k -> isNotBlank(getProperty(k))).collect(Collectors.toList());
}
@Override
@ -179,7 +178,7 @@ public class ApplicationPropertiesProtector<T extends ProtectedProperties<U>, U
final Map<String, String> traditionalProtectedProperties = new HashMap<>();
for (final String key : sensitiveKeys) {
final String protection = getProperty(getProtectionKey(key));
if (StringUtils.isNotBlank(protection) && StringUtils.isNotBlank(getProperty(key))) {
if (isNotBlank(protection) && isNotBlank(getProperty(key))) {
traditionalProtectedProperties.put(key, protection);
}
}
@ -203,7 +202,7 @@ public class ApplicationPropertiesProtector<T extends ProtectedProperties<U>, U
*/
@Override
public boolean isPropertyProtected(final String key) {
return key != null && isPropertySensitive(key) && !StringUtils.isBlank(getProperty(getProtectionKey(key)));
return key != null && isPropertySensitive(key) && isNotBlank(getProperty(getProtectionKey(key)));
}
@Override
@ -238,7 +237,7 @@ public class ApplicationPropertiesProtector<T extends ProtectedProperties<U>, U
}
if (!failedKeys.isEmpty()) {
final String failed = failedKeys.size() == 1 ? failedKeys.iterator().next() : StringUtils.join(failedKeys, ", ");
final String failed = failedKeys.size() == 1 ? failedKeys.iterator().next() : String.join(", ", failedKeys);
throw new SensitivePropertyProtectionException(String.format("Failed unprotected properties: %s", failed));
}
@ -297,4 +296,8 @@ public class ApplicationPropertiesProtector<T extends ProtectedProperties<U>, U
.map(Map.Entry::getValue)
.orElseThrow(() -> new UnsupportedOperationException(String.format("Protection Scheme Path [%s] Provider not found", protectionSchemePath)));
}
private boolean isNotBlank(final String string) {
return string != null && string.length() > 0;
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.property.protection.loader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* Property Protection URL Class Loader uses the Current Thread Class Loader as the parent and loads libraries from a standard directory
*/
public class PropertyProtectionURLClassLoader extends URLClassLoader {
private static final String STANDARD_DIRECTORY = "lib/properties";
private static final Logger logger = LoggerFactory.getLogger(PropertyProtectionURLClassLoader.class);
public PropertyProtectionURLClassLoader(final ClassLoader parentClassLoader) {
super(getPropertyProtectionUrls(), parentClassLoader);
}
private static URL[] getPropertyProtectionUrls() {
final Path standardDirectory = Paths.get(STANDARD_DIRECTORY);
if (Files.exists(standardDirectory)) {
try (final Stream<Path> files = Files.list(standardDirectory)) {
return files.map(Path::toUri)
.map(uri -> {
try {
return uri.toURL();
} catch (final MalformedURLException e) {
throw new UncheckedIOException(String.format("Processing Property Protection libraries failed [%s]", standardDirectory), e);
}
})
.toArray(URL[]::new);
} catch (final IOException e) {
throw new UncheckedIOException(String.format("Loading Property Protection libraries failed [%s]", standardDirectory), e);
}
} else {
logger.warn("Property Protection libraries directory [{}] not found", standardDirectory);
return new URL[0];
}
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.property.protection.loader;
import org.apache.nifi.properties.SensitivePropertyProtectionException;
import org.apache.nifi.properties.SensitivePropertyProviderFactory;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Loader for Sensitive Property Provider Factory
*/
public class PropertyProviderFactoryLoader {
/**
* Get Sensitive Property Provider Factory using ServiceLoader to find available implementations from META-INF directories
*
* @return Sensitive Property Provider Factory
* @throws SensitivePropertyProtectionException Thrown when no implementations found
*/
public SensitivePropertyProviderFactory getPropertyProviderFactory() {
final ServiceLoader<SensitivePropertyProviderFactory> serviceLoader = ServiceLoader.load(SensitivePropertyProviderFactory.class);
final Iterator<SensitivePropertyProviderFactory> factories = serviceLoader.iterator();
if (factories.hasNext()) {
return factories.next();
} else {
throw new SensitivePropertyProtectionException(String.format("No implementations found [%s]", SensitivePropertyProviderFactory.class.getName()));
}
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.property.protection.loader;
import org.apache.nifi.properties.SensitivePropertyProtectionException;
import org.apache.nifi.properties.scheme.ProtectionSchemeResolver;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Loader for Protection Scheme Resolver
*/
public class ProtectionSchemeResolverLoader {
/**
* Get Protection Scheme Resolver using ServiceLoader to find available implementations from META-INF directories
*
* @return Protection Scheme Resolver
* @throws SensitivePropertyProtectionException Thrown when no implementations found
*/
public ProtectionSchemeResolver getProtectionSchemeResolver() {
final ServiceLoader<ProtectionSchemeResolver> serviceLoader = ServiceLoader.load(ProtectionSchemeResolver.class);
final Iterator<ProtectionSchemeResolver> factories = serviceLoader.iterator();
if (factories.hasNext()) {
return factories.next();
} else {
throw new SensitivePropertyProtectionException(String.format("No implementations found [%s]", ProtectionSchemeResolver.class.getName()));
}
}
}

View File

@ -44,6 +44,7 @@
<module>nifi-property-protection-factory</module>
<module>nifi-property-protection-gcp</module>
<module>nifi-property-protection-hashicorp</module>
<module>nifi-property-protection-loader</module>
<module>nifi-property-protection-shared</module>
<module>nifi-record</module>
<module>nifi-record-path</module>

View File

@ -148,6 +148,14 @@
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-properties-loader</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
</dependency>
<!-- Test dependencies -->
<dependency>
@ -156,6 +164,11 @@
<version>1.17.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>
<scope>test</scope>
</dependency>
<!-- Spock testing dependencies-->
<dependency>

View File

@ -25,7 +25,14 @@ import org.apache.nifi.authorization.generated.Authorizers;
import org.apache.nifi.authorization.generated.Property;
import org.apache.nifi.bundle.Bundle;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.properties.SensitivePropertyProviderFactoryAware;
import org.apache.nifi.properties.ProtectedPropertyContext;
import org.apache.nifi.properties.SensitivePropertyProvider;
import org.apache.nifi.properties.SensitivePropertyProviderFactory;
import org.apache.nifi.properties.scheme.ProtectionScheme;
import org.apache.nifi.properties.scheme.ProtectionSchemeResolver;
import org.apache.nifi.property.protection.loader.PropertyProtectionURLClassLoader;
import org.apache.nifi.property.protection.loader.PropertyProviderFactoryLoader;
import org.apache.nifi.property.protection.loader.ProtectionSchemeResolverLoader;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.util.file.classloader.ClassLoaderUtils;
import org.apache.nifi.xml.processing.ProcessingException;
@ -62,8 +69,7 @@ import java.util.stream.Collectors;
/**
* Factory bean for loading the configured authorizer.
*/
public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
implements FactoryBean, DisposableBean, UserGroupProviderLookup, AccessPolicyProviderLookup, AuthorizerLookup {
public class AuthorizerFactoryBean implements FactoryBean<Authorizer>, DisposableBean, UserGroupProviderLookup, AccessPolicyProviderLookup, AuthorizerLookup {
private static final Logger logger = LoggerFactory.getLogger(AuthorizerFactoryBean.class);
private static final String AUTHORIZERS_XSD = "/authorizers.xsd";
@ -109,7 +115,7 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
}
@Override
public Object getObject() throws Exception {
public Authorizer getObject() throws Exception {
if (authorizer == null) {
if (properties.getSslPort() == null) {
// use a default authorizer... only allowable when running not securely
@ -132,12 +138,6 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
userGroupProviders.put(userGroupProvider.getIdentifier(), createUserGroupProvider(userGroupProvider.getIdentifier(), userGroupProvider.getClazz()));
}
// configure each user group provider
for (final org.apache.nifi.authorization.generated.UserGroupProvider provider : authorizerConfiguration.getUserGroupProvider()) {
final UserGroupProvider instance = userGroupProviders.get(provider.getIdentifier());
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty()));
}
// create each access policy provider
for (final org.apache.nifi.authorization.generated.AccessPolicyProvider accessPolicyProvider : authorizerConfiguration.getAccessPolicyProvider()) {
if (accessPolicyProviders.containsKey(accessPolicyProvider.getIdentifier())) {
@ -146,12 +146,6 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
accessPolicyProviders.put(accessPolicyProvider.getIdentifier(), createAccessPolicyProvider(accessPolicyProvider.getIdentifier(), accessPolicyProvider.getClazz()));
}
// configure each access policy provider
for (final org.apache.nifi.authorization.generated.AccessPolicyProvider provider : authorizerConfiguration.getAccessPolicyProvider()) {
final AccessPolicyProvider instance = accessPolicyProviders.get(provider.getIdentifier());
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty()));
}
// create each authorizer
for (final org.apache.nifi.authorization.generated.Authorizer authorizer : authorizerConfiguration.getAuthorizer()) {
if (authorizers.containsKey(authorizer.getIdentifier())) {
@ -160,15 +154,6 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
authorizers.put(authorizer.getIdentifier(), createAuthorizer(authorizer.getIdentifier(), authorizer.getClazz(), authorizer.getClasspath()));
}
// configure each authorizer, except the authorizer that is selected in nifi.properties
for (final org.apache.nifi.authorization.generated.Authorizer provider : authorizerConfiguration.getAuthorizer()) {
if (provider.getIdentifier().equals(authorizerIdentifier)) {
continue;
}
final Authorizer instance = authorizers.get(provider.getIdentifier());
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty()));
}
// get the authorizer instance
authorizer = getAuthorizer(authorizerIdentifier);
@ -180,19 +165,7 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
authorizer = AuthorizerFactory.installIntegrityChecks(authorizer);
// configure authorizer after integrity checks are installed
AuthorizerConfigurationContext authorizerConfigurationContext = null;
for (final org.apache.nifi.authorization.generated.Authorizer provider : authorizerConfiguration.getAuthorizer()) {
if (provider.getIdentifier().equals(authorizerIdentifier)) {
authorizerConfigurationContext = loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty());
break;
}
}
if (authorizerConfigurationContext == null) {
throw new IllegalStateException("Unable to load configuration for authorizer with id: " + authorizerIdentifier);
}
authorizer.onConfigured(authorizerConfigurationContext);
loadProviderProperties(authorizerConfiguration, authorizerIdentifier);
}
}
}
@ -201,6 +174,75 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
return authorizer;
}
private void loadProviderProperties(final Authorizers authorizerConfiguration, final String authorizerIdentifier) {
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
final PropertyProtectionURLClassLoader protectionClassLoader = new PropertyProtectionURLClassLoader(contextClassLoader);
Thread.currentThread().setContextClassLoader(protectionClassLoader);
final ProtectionSchemeResolverLoader resolverLoader = new ProtectionSchemeResolverLoader();
final ProtectionSchemeResolver protectionSchemeResolver = resolverLoader.getProtectionSchemeResolver();
final PropertyProviderFactoryLoader factoryLoader = new PropertyProviderFactoryLoader();
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory = factoryLoader.getPropertyProviderFactory();
// configure each user group provider
for (final org.apache.nifi.authorization.generated.UserGroupProvider provider : authorizerConfiguration.getUserGroupProvider()) {
final UserGroupProvider instance = userGroupProviders.get(provider.getIdentifier());
final AuthorizerConfigurationContext configurationContext = getConfigurationContext(
provider.getIdentifier(),
provider.getProperty(),
sensitivePropertyProviderFactory,
protectionSchemeResolver
);
instance.onConfigured(configurationContext);
}
// configure each access policy provider
for (final org.apache.nifi.authorization.generated.AccessPolicyProvider provider : authorizerConfiguration.getAccessPolicyProvider()) {
final AccessPolicyProvider instance = accessPolicyProviders.get(provider.getIdentifier());
final AuthorizerConfigurationContext configurationContext = getConfigurationContext(
provider.getIdentifier(),
provider.getProperty(),
sensitivePropertyProviderFactory,
protectionSchemeResolver
);
instance.onConfigured(configurationContext);
}
// configure each authorizer, except the authorizer that is selected in nifi.properties
AuthorizerConfigurationContext authorizerConfigurationContext = null;
for (final org.apache.nifi.authorization.generated.Authorizer provider : authorizerConfiguration.getAuthorizer()) {
if (provider.getIdentifier().equals(authorizerIdentifier)) {
authorizerConfigurationContext = getConfigurationContext(
provider.getIdentifier(),
provider.getProperty(),
sensitivePropertyProviderFactory,
protectionSchemeResolver
);
continue;
}
final Authorizer instance = authorizers.get(provider.getIdentifier());
final AuthorizerConfigurationContext configurationContext = getConfigurationContext(
provider.getIdentifier(),
provider.getProperty(),
sensitivePropertyProviderFactory,
protectionSchemeResolver
);
instance.onConfigured(configurationContext);
}
if (authorizerConfigurationContext == null) {
throw new IllegalStateException("Unable to load configuration for authorizer with id: " + authorizerIdentifier);
}
authorizer.onConfigured(authorizerConfigurationContext);
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}
private Authorizers loadAuthorizersConfiguration() throws Exception {
final File authorizersConfigurationFile = properties.getAuthorizerConfigurationFile();
@ -252,15 +294,10 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
// attempt to load the class
Class<?> rawUserGroupProviderClass = Class.forName(userGroupProviderClassName, true, userGroupProviderClassLoader);
Class<? extends UserGroupProvider> userGroupProviderClass = rawUserGroupProviderClass.asSubclass(UserGroupProvider.class);
Constructor<? extends UserGroupProvider> constructor = userGroupProviderClass.getConstructor();
instance = constructor.newInstance();
// otherwise create a new instance
Constructor constructor = userGroupProviderClass.getConstructor();
instance = (UserGroupProvider) constructor.newInstance();
// method injection
performMethodInjection(instance, userGroupProviderClass);
// field injection
performFieldInjection(instance, userGroupProviderClass);
// call post construction lifecycle event
@ -300,15 +337,10 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
// attempt to load the class
Class<?> rawAccessPolicyProviderClass = Class.forName(accessPolicyProviderClassName, true, accessPolicyProviderClassLoader);
Class<? extends AccessPolicyProvider> accessPolicyClass = rawAccessPolicyProviderClass.asSubclass(AccessPolicyProvider.class);
Constructor<? extends AccessPolicyProvider> constructor = accessPolicyClass.getConstructor();
instance = constructor.newInstance();
// otherwise create a new instance
Constructor constructor = accessPolicyClass.getConstructor();
instance = (AccessPolicyProvider) constructor.newInstance();
// method injection
performMethodInjection(instance, accessPolicyClass);
// field injection
performFieldInjection(instance, accessPolicyClass);
// call post construction lifecycle event
@ -356,15 +388,10 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
// attempt to load the class
Class<?> rawAuthorizerClass = Class.forName(authorizerClassName, true, authorizerClassLoader);
Class<? extends Authorizer> authorizerClass = rawAuthorizerClass.asSubclass(Authorizer.class);
Constructor<? extends Authorizer> constructor = authorizerClass.getConstructor();
instance = constructor.newInstance();
// otherwise create a new instance
Constructor constructor = authorizerClass.getConstructor();
instance = (Authorizer) constructor.newInstance();
// method injection
performMethodInjection(instance, authorizerClass);
// field injection
performFieldInjection(instance, authorizerClass);
// call post construction lifecycle event
@ -378,22 +405,43 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
return AuthorizerFactory.withNarLoader(instance, authorizerClassLoader);
}
private AuthorizerConfigurationContext loadAuthorizerConfiguration(final String identifier, final List<Property> properties) {
private AuthorizerConfigurationContext getConfigurationContext(
final String identifier,
final List<Property> properties,
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory,
final ProtectionSchemeResolver protectionSchemeResolver
) {
final Map<String, String> authorizerProperties = new HashMap<>();
for (final Property property : properties) {
if (!StringUtils.isBlank(property.getEncryption())) {
String decryptedValue = decryptValue(property.getValue(), property.getEncryption(), property.getName(), identifier);
authorizerProperties.put(property.getName(), decryptedValue);
} else {
final String encryption = property.getEncryption();
if (StringUtils.isBlank(encryption)) {
authorizerProperties.put(property.getName(), property.getValue());
} else {
final String propertyDecrypted = getPropertyDecrypted(identifier, property, sensitivePropertyProviderFactory, protectionSchemeResolver);
authorizerProperties.put(property.getName(), propertyDecrypted);
}
}
return new StandardAuthorizerConfigurationContext(identifier, authorizerProperties);
}
private void performMethodInjection(final Object instance, final Class authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
private String getPropertyDecrypted(
final String providerIdentifier,
final Property property,
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory,
final ProtectionSchemeResolver protectionSchemeResolver
) {
final String scheme = property.getEncryption();
final ProtectionScheme protectionScheme = protectionSchemeResolver.getProtectionScheme(scheme);
final SensitivePropertyProvider propertyProvider = sensitivePropertyProviderFactory.getProvider(protectionScheme);
final ProtectedPropertyContext protectedPropertyContext = sensitivePropertyProviderFactory.getPropertyContext(providerIdentifier, property.getName());
final String protectedProperty = property.getValue();
return propertyProvider.unprotect(protectedProperty, protectedPropertyContext);
}
private void performMethodInjection(final Object instance, final Class<?> authorizerClass) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (final Method method : authorizerClass.getMethods()) {
if (method.isAnnotationPresent(AuthorizerContext.class)) {
// make the method accessible
@ -419,13 +467,13 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
}
}
final Class parentClass = authorizerClass.getSuperclass();
final Class<?> parentClass = authorizerClass.getSuperclass();
if (parentClass != null && Authorizer.class.isAssignableFrom(parentClass)) {
performMethodInjection(instance, parentClass);
}
}
private void performFieldInjection(final Object instance, final Class authorizerClass) throws IllegalArgumentException, IllegalAccessException {
private void performFieldInjection(final Object instance, final Class<?> authorizerClass) throws IllegalArgumentException, IllegalAccessException {
for (final Field field : authorizerClass.getDeclaredFields()) {
if (field.isAnnotationPresent(AuthorizerContext.class)) {
// make the method accessible
@ -451,7 +499,7 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
}
}
final Class parentClass = authorizerClass.getSuperclass();
final Class<?> parentClass = authorizerClass.getSuperclass();
if (parentClass != null && Authorizer.class.isAssignableFrom(parentClass)) {
performFieldInjection(instance, parentClass);
}
@ -482,7 +530,7 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
}
@Override
public Class getObjectType() {
public Class<Authorizer> getObjectType() {
return Authorizer.class;
}
@ -495,38 +543,32 @@ public class AuthorizerFactoryBean extends SensitivePropertyProviderFactoryAware
public void destroy() throws Exception {
List<Exception> errors = new ArrayList<>();
if (authorizers != null) {
authorizers.forEach((identifier, object) -> {
try {
object.preDestruction();
} catch (Exception e) {
errors.add(e);
logger.error("Error pre-destructing {}: {}", identifier, e);
}
});
}
authorizers.forEach((identifier, object) -> {
try {
object.preDestruction();
} catch (Exception e) {
errors.add(e);
logger.error("Authorizer [{}] destruction failed", identifier, e);
}
});
if (accessPolicyProviders != null) {
accessPolicyProviders.forEach((identifier, object) -> {
try {
object.preDestruction();
} catch (Exception e) {
errors.add(e);
logger.error("Error pre-destructing {}: {}", identifier, e);
}
});
}
accessPolicyProviders.forEach((identifier, object) -> {
try {
object.preDestruction();
} catch (Exception e) {
errors.add(e);
logger.error("Access Policy Provider [{}] destruction failed", identifier, e);
}
});
if (userGroupProviders != null) {
userGroupProviders.forEach((identifier, object) -> {
try {
object.preDestruction();
} catch (Exception e) {
errors.add(e);
logger.error("Error pre-destructing {}: {}", identifier, e);
}
});
}
userGroupProviders.forEach((identifier, object) -> {
try {
object.preDestruction();
} catch (Exception e) {
errors.add(e);
logger.error("User Group Provider [{}] destruction failed", identifier, e);
}
});
if (!errors.isEmpty()) {
List<String> errorMessages = errors.stream().map(Throwable::toString).collect(Collectors.toList());

View File

@ -1,72 +0,0 @@
/*
* 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.authorization
import org.apache.nifi.authorization.resource.ResourceFactory
import org.apache.nifi.util.NiFiProperties
import spock.lang.Specification
class AuthorizerFactoryBeanSpec extends Specification {
def mockProperties = Mock(NiFiProperties)
AuthorizerFactoryBean authorizerFactoryBean
// runs before every feature method
def setup() {
authorizerFactoryBean = new AuthorizerFactoryBean()
authorizerFactoryBean.setProperties(mockProperties)
}
// runs after every feature method
def cleanup() {}
// runs before the first feature method
def setupSpec() {}
// runs after the last feature method
def cleanupSpec() {}
def "create default authorizer"() {
setup: "properties indicate nifi-registry is unsecured"
mockProperties.getProperty(NiFiProperties.WEB_HTTPS_PORT) >> ""
when: "getAuthorizer() is first called"
def authorizer = (Authorizer) authorizerFactoryBean.getObject()
then: "the default authorizer is returned"
authorizer != null
and: "any authorization request made to that authorizer is approved"
def authorizationResult = authorizer.authorize(getTestAuthorizationRequest())
authorizationResult.result == AuthorizationResult.Result.Approved
}
// Helper methods
private static AuthorizationRequest getTestAuthorizationRequest() {
return new AuthorizationRequest.Builder()
.resource(ResourceFactory.getFlowResource())
.action(RequestAction.WRITE)
.accessAttempt(false)
.anonymous(true)
.build()
}
}

View File

@ -1,105 +0,0 @@
/*
* 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.authorization
import org.apache.nifi.authorization.generated.Property
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.crypto.Cipher
import java.security.Security
@RunWith(JUnit4.class)
class AuthorizerFactoryBeanTest extends GroovyTestCase {
private static final Logger logger = LoggerFactory.getLogger(AuthorizerFactoryBeanTest.class)
// These blocks configure the constant values depending on JCE policies of the machine running the tests
private static final String KEY_HEX_128 = "0123456789ABCDEFFEDCBA9876543210"
private static final String KEY_HEX_256 = KEY_HEX_128 * 2
public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
private static final String CIPHER_TEXT_128 = "6pqdM1urBEPHtj+L||ds0Z7RpqOA2321c/+7iPMfxDrqmH5Qx6UwQG0eIYB//3Ng"
private static final String CIPHER_TEXT_256 = "TepMCD7v3LAMF0KX||ydSRWPRl1/JXgTsZtfzCnDXu7a0lTLysjPL2I06EPUCHzw"
public static final String CIPHER_TEXT = isUnlimitedStrengthCryptoAvailable() ? CIPHER_TEXT_256 : CIPHER_TEXT_128
private static final String ENCRYPTION_SCHEME_128 = "aes/gcm/128"
private static final String ENCRYPTION_SCHEME_256 = "aes/gcm/256"
public static
final String ENCRYPTION_SCHEME = isUnlimitedStrengthCryptoAvailable() ? ENCRYPTION_SCHEME_256 : ENCRYPTION_SCHEME_128
private static final String PASSWORD = "thisIsABadPassword"
private AuthorizerFactoryBean bean
@BeforeClass
static void setUpOnce() throws Exception {
Security.addProvider(new BouncyCastleProvider())
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
}
@Before
void setUp() throws Exception {
bean = new AuthorizerFactoryBean()
bean.configureSensitivePropertyProviderFactory(KEY_HEX, null)
}
private static boolean isUnlimitedStrengthCryptoAvailable() {
Cipher.getMaxAllowedKeyLength("AES") > 128
}
@Test
void testShouldDecryptValue() {
// Arrange
logger.info("Encryption scheme: ${ENCRYPTION_SCHEME}")
logger.info("Cipher text: ${CIPHER_TEXT}")
// Act
String decrypted = bean.decryptValue(CIPHER_TEXT, ENCRYPTION_SCHEME, "propertyName", "ldap-user-group-provider")
logger.info("Decrypted ${CIPHER_TEXT} -> ${decrypted}")
// Assert
assert decrypted == PASSWORD
}
@Test
void testShouldLoadEncryptedAuthorizersConfiguration() {
// Arrange
def identifier = "ldap-user-group-provider"
def managerPasswordName = "Manager Password"
Property managerPasswordProperty = new Property(name: managerPasswordName, value: CIPHER_TEXT, encryption: ENCRYPTION_SCHEME)
List<Property> properties = [managerPasswordProperty]
logger.info("Manager Password property: ${managerPasswordProperty.dump()}")
// Act
def context = bean.loadAuthorizerConfiguration(identifier, properties)
logger.info("Loaded context: ${context.dump()}")
// Assert
String decryptedPropertyValue = context.getProperty(managerPasswordName)
assert decryptedPropertyValue == PASSWORD
}
}

View File

@ -0,0 +1,107 @@
/*
* 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.authorization;
import org.apache.nifi.authorization.mock.MockAccessPolicyProvider;
import org.apache.nifi.authorization.mock.MockAuthorizer;
import org.apache.nifi.authorization.mock.MockUserGroupProvider;
import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.bundle.Bundle;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.util.NiFiProperties;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class AuthorizerFactoryBeanTest {
private static final String AUTHORIZER_ID = "authorizer";
private static final String AUTHORIZERS_PATH = "/authorizers.xml";
private static final AuthorizationRequest REQUEST = new AuthorizationRequest.Builder()
.resource(ResourceFactory.getFlowResource())
.action(RequestAction.READ)
.accessAttempt(true)
.anonymous(true)
.build();
@Mock
NiFiProperties properties;
@Mock
ExtensionManager extensionManager;
@Mock
Bundle bundle;
@Test
void testGetObjectDefaultAuthorizerRequestApproved() throws Exception {
when(properties.getSslPort()).thenReturn(null);
final AuthorizerFactoryBean bean = new AuthorizerFactoryBean();
bean.setProperties(properties);
final Authorizer authorizer = bean.getObject();
assertNotNull(authorizer);
final AuthorizationResult authorizationResult = authorizer.authorize(REQUEST);
assertEquals(AuthorizationResult.approved(), authorizationResult);
}
@Test
void testGetObject() throws Exception {
when(properties.getSslPort()).thenReturn(8443);
when(properties.getProperty(eq(NiFiProperties.SECURITY_USER_AUTHORIZER))).thenReturn(AUTHORIZER_ID);
when(properties.getAuthorizerConfigurationFile()).thenReturn(getAuthorizersConfigurationFile());
when(bundle.getClassLoader()).thenReturn(getClass().getClassLoader());
final List<Bundle> bundles = Collections.singletonList(bundle);
when(extensionManager.getBundles(eq(MockUserGroupProvider.class.getName()))).thenReturn(bundles);
when(extensionManager.getBundles(eq(MockAccessPolicyProvider.class.getName()))).thenReturn(bundles);
when(extensionManager.getBundles(eq(MockAuthorizer.class.getName()))).thenReturn(bundles);
final AuthorizerFactoryBean bean = new AuthorizerFactoryBean();
bean.setProperties(properties);
bean.setExtensionManager(extensionManager);
final Authorizer authorizer = bean.getObject();
assertNotNull(authorizer);
}
private File getAuthorizersConfigurationFile() {
final URL url = AuthorizerFactoryBeanTest.class.getResource(AUTHORIZERS_PATH);
if (url == null) {
throw new IllegalStateException(String.format("Authorizers [%s] not found", AUTHORIZERS_PATH));
}
return new File(url.getPath());
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.authorization.mock;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.AccessPolicyProvider;
import org.apache.nifi.authorization.AccessPolicyProviderInitializationContext;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.UserGroupProvider;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import java.util.Set;
public class MockAccessPolicyProvider implements AccessPolicyProvider {
@Override
public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
return null;
}
@Override
public AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
return null;
}
@Override
public AccessPolicy getAccessPolicy(String resourceIdentifier, RequestAction action) throws AuthorizationAccessException {
return null;
}
@Override
public UserGroupProvider getUserGroupProvider() {
return null;
}
@Override
public void initialize(AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException {
}
@Override
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
}
@Override
public void preDestruction() throws AuthorizerDestructionException {
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.authorization.mock;
import org.apache.nifi.authorization.AuthorizationRequest;
import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.AuthorizerInitializationContext;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
public class MockAuthorizer implements Authorizer {
@Override
public AuthorizationResult authorize(final AuthorizationRequest request) throws AuthorizationAccessException {
return AuthorizationResult.resourceNotFound();
}
@Override
public void initialize(final AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
}
@Override
public void onConfigured(final AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
}
@Override
public void preDestruction() throws AuthorizerDestructionException {
}
}

View File

@ -0,0 +1,76 @@
/*
* 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.authorization.mock;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.Group;
import org.apache.nifi.authorization.User;
import org.apache.nifi.authorization.UserAndGroups;
import org.apache.nifi.authorization.UserGroupProvider;
import org.apache.nifi.authorization.UserGroupProviderInitializationContext;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import java.util.Set;
public class MockUserGroupProvider implements UserGroupProvider {
@Override
public Set<User> getUsers() throws AuthorizationAccessException {
return null;
}
@Override
public User getUser(String identifier) throws AuthorizationAccessException {
return null;
}
@Override
public User getUserByIdentity(String identity) throws AuthorizationAccessException {
return null;
}
@Override
public Set<Group> getGroups() throws AuthorizationAccessException {
return null;
}
@Override
public Group getGroup(String identifier) throws AuthorizationAccessException {
return null;
}
@Override
public UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException {
return null;
}
@Override
public void initialize(UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException {
}
@Override
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
}
@Override
public void preDestruction() throws AuthorizerDestructionException {
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
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.
-->
<authorizers>
<userGroupProvider>
<identifier>user-group-provider</identifier>
<class>org.apache.nifi.authorization.mock.MockUserGroupProvider</class>
</userGroupProvider>
<accessPolicyProvider>
<identifier>access-policy-provider</identifier>
<class>org.apache.nifi.authorization.mock.MockAccessPolicyProvider</class>
</accessPolicyProvider>
<authorizer>
<identifier>authorizer</identifier>
<class>org.apache.nifi.authorization.mock.MockAuthorizer</class>
</authorizer>
</authorizers>

View File

@ -57,7 +57,6 @@ import org.apache.nifi.registry.flow.diff.StandardFlowComparator;
import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedProcessGroup;
import org.apache.nifi.registry.flow.mapping.NiFiRegistryFlowMapper;
import org.apache.nifi.util.FlowDifferenceFilters;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.io.IOException;
@ -747,7 +746,6 @@ public class ImportFlowIT extends FrameworkIntegrationTest {
return flow;
}
@NotNull
private VersionedProcessGroup createFlowContents() {
final VersionedProcessGroup flowContents = new VersionedProcessGroup();
flowContents.setIdentifier("unit-test-flow-contents");
@ -763,7 +761,6 @@ public class ImportFlowIT extends FrameworkIntegrationTest {
bundle.setVersion(coordinate.getVersion());
}
@NotNull
private VersionedFlow createVersionedFlow() {
final VersionedFlow flow = new VersionedFlow();
flow.setBucketIdentifier("unit-test-bucket");
@ -774,7 +771,6 @@ public class ImportFlowIT extends FrameworkIntegrationTest {
return flow;
}
@NotNull
private Bucket createBucket() {
final Bucket bucket = new Bucket();
bucket.setCreatedTimestamp(System.currentTimeMillis());

View File

@ -21,62 +21,25 @@
</parent>
<artifactId>nifi-properties-loader</artifactId>
<name>nifi-properties-loader</name>
<description>Handles the loading of the nifi.properties file to an instance of NiFiProperties, and transparently
performs any decryption/retrieval of sensitive configuration properties.
</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-properties</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-security-utils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>
<scope>provided</scope>
<!-- Provided through isolated ClassLoader to avoid unnecessary runtime dependencies -->
</dependency>
</dependencies>
<build>
<!-- Required to run Groovy tests without any Java tests -->
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/groovy</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -16,9 +16,10 @@
*/
package org.apache.nifi.properties;
import org.apache.nifi.property.protection.loader.PropertyProtectionURLClassLoader;
import org.apache.nifi.property.protection.loader.PropertyProviderFactoryLoader;
import org.apache.nifi.util.NiFiBootstrapUtils;
import org.apache.nifi.util.NiFiProperties;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -28,11 +29,12 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64;
import java.util.List;
import java.util.Properties;
@ -48,13 +50,12 @@ public class NiFiPropertiesLoader {
private static final String MIGRATION_INSTRUCTIONS = "See Admin Guide section [Updating the Sensitive Properties Key]";
private static final String PROPERTIES_KEY_MESSAGE = String.format("Sensitive Properties Key [%s] not found: %s", NiFiProperties.SENSITIVE_PROPS_KEY, MIGRATION_INSTRUCTIONS);
private static final String SET_KEY_METHOD = "setKeyHex";
private final String defaultPropertiesFilePath = NiFiBootstrapUtils.getDefaultApplicationPropertiesFilePath();
private NiFiProperties instance;
private String keyHex;
// Future enhancement: allow for external registration of new providers
private SensitivePropertyProviderFactory sensitivePropertyProviderFactory;
public NiFiPropertiesLoader() {
}
@ -96,13 +97,9 @@ public class NiFiPropertiesLoader {
* startup.
*
* @return the populated and decrypted NiFiProperties instance
* @throws IOException if there is a problem reading from the bootstrap.conf
* or nifi.properties files
*/
public static NiFiProperties loadDefaultWithKeyFromBootstrap() throws IOException {
public static NiFiProperties loadDefaultWithKeyFromBootstrap() {
try {
// The default behavior of StandardSensitivePropertiesFactory is to use the key
// from bootstrap.conf if no key is provided
return new NiFiPropertiesLoader().loadDefault();
} catch (Exception e) {
logger.warn("Encountered an error naively loading the nifi.properties file because one or more properties are protected: {}", e.getLocalizedMessage());
@ -110,17 +107,6 @@ public class NiFiPropertiesLoader {
}
}
private NiFiProperties loadDefault() {
return load(defaultPropertiesFilePath);
}
private SensitivePropertyProviderFactory getSensitivePropertyProviderFactory() {
if (sensitivePropertyProviderFactory == null) {
sensitivePropertyProviderFactory = StandardSensitivePropertyProviderFactory.withKey(keyHex);
}
return sensitivePropertyProviderFactory;
}
/**
* Returns a {@link ProtectedNiFiProperties} instance loaded from the
* serialized form in the file. Responsible for actually reading from disk
@ -130,29 +116,25 @@ public class NiFiPropertiesLoader {
* @param file the file containing serialized properties
* @return the ProtectedNiFiProperties instance
*/
ProtectedNiFiProperties readProtectedPropertiesFromDisk(File file) {
ProtectedNiFiProperties loadProtectedProperties(final File file) {
if (file == null || !file.exists() || !file.canRead()) {
String path = (file == null ? "missing file" : file.getAbsolutePath());
logger.error("Cannot read from '{}' -- file is missing or not readable", path);
throw new IllegalArgumentException("NiFi properties file missing or unreadable");
throw new IllegalArgumentException(String.format("Application Properties [%s] not found", file));
}
final Properties rawProperties = new Properties();
logger.info("Loading Application Properties [{}]", file);
final Properties properties = new Properties();
try (final InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
rawProperties.load(inputStream);
logger.info("Loaded {} properties from {}", rawProperties.size(), file.getAbsolutePath());
properties.load(inputStream);
final Set<String> keys = rawProperties.stringPropertyNames();
final Set<String> keys = properties.stringPropertyNames();
for (final String key : keys) {
final String property = rawProperties.getProperty(key);
rawProperties.setProperty(key, property.trim());
final String property = properties.getProperty(key);
properties.setProperty(key, property.trim());
}
return new ProtectedNiFiProperties(rawProperties);
} catch (final Exception ex) {
logger.error("Cannot load properties file due to {}", ex.getLocalizedMessage());
throw new RuntimeException("Cannot load properties file due to "
+ ex.getLocalizedMessage(), ex);
return new ProtectedNiFiProperties(properties);
} catch (final Exception e) {
throw new RuntimeException(String.format("Loading Application Properties [%s] failed", file), e);
}
}
@ -166,20 +148,32 @@ public class NiFiPropertiesLoader {
* @return the NiFiProperties instance
*/
public NiFiProperties load(final File file) {
final ProtectedNiFiProperties protectedNiFiProperties = readProtectedPropertiesFromDisk(file);
if (protectedNiFiProperties.hasProtectedKeys()) {
Security.addProvider(new BouncyCastleProvider());
getSensitivePropertyProviderFactory()
.getSupportedProviders()
.forEach(protectedNiFiProperties::addSensitivePropertyProvider);
final ProtectedNiFiProperties protectedProperties = loadProtectedProperties(file);
final NiFiProperties properties;
if (protectedProperties.hasProtectedKeys()) {
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
final PropertyProtectionURLClassLoader protectionClassLoader = new PropertyProtectionURLClassLoader(contextClassLoader);
Thread.currentThread().setContextClassLoader(protectionClassLoader);
final PropertyProviderFactoryLoader factoryLoader = new PropertyProviderFactoryLoader();
final SensitivePropertyProviderFactory providerFactory = factoryLoader.getPropertyProviderFactory();
setBootstrapKey(providerFactory);
providerFactory.getSupportedProviders().forEach(protectedProperties::addSensitivePropertyProvider);
properties = protectedProperties.getUnprotectedProperties();
providerFactory.getSupportedProviders().forEach(SensitivePropertyProvider::cleanUp);
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
} else {
properties = protectedProperties.getUnprotectedProperties();
}
NiFiProperties props = protectedNiFiProperties.getUnprotectedProperties();
if (protectedNiFiProperties.hasProtectedKeys()) {
getSensitivePropertyProviderFactory()
.getSupportedProviders()
.forEach(SensitivePropertyProvider::cleanUp);
}
return props;
return properties;
}
/**
@ -217,6 +211,10 @@ public class NiFiPropertiesLoader {
return instance;
}
private NiFiProperties loadDefault() {
return load(defaultPropertiesFilePath);
}
private NiFiProperties getDefaultProperties() {
NiFiProperties defaultProperties = loadDefault();
if (isKeyGenerationRequired(defaultProperties)) {
@ -272,4 +270,23 @@ public class NiFiPropertiesLoader {
final String configuredSensitivePropertiesKey = properties.getProperty(NiFiProperties.SENSITIVE_PROPS_KEY);
return (configuredSensitivePropertiesKey == null || configuredSensitivePropertiesKey.length() == 0);
}
private void setBootstrapKey(final SensitivePropertyProviderFactory providerFactory) {
if (keyHex == null) {
logger.debug("Bootstrap Sensitive Key not configured");
} else {
final Class<? extends SensitivePropertyProviderFactory> factoryClass = providerFactory.getClass();
try {
// Set Bootstrap Key using reflection to preserve ClassLoader isolation
final Method setMethod = factoryClass.getMethod(SET_KEY_METHOD, String.class);
setMethod.invoke(providerFactory, keyHex);
} catch (final NoSuchMethodException e) {
logger.warn("Method [{}] on Class [{}] not found", SET_KEY_METHOD, factoryClass.getName());
} catch (final IllegalAccessException e) {
logger.warn("Method [{}] on Class [{}] access not allowed", SET_KEY_METHOD, factoryClass.getName());
} catch (final InvocationTargetException e) {
throw new SensitivePropertyProtectionException("Set Bootstrap Key on Provider Factory failed", e);
}
}
}
}

View File

@ -1,491 +0,0 @@
/*
* 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.properties
import org.apache.commons.lang3.SystemUtils
import org.apache.nifi.util.NiFiBootstrapUtils
import org.apache.nifi.util.NiFiProperties
import org.apache.nifi.util.file.FileUtils
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
import org.junit.AfterClass
import org.junit.Assume
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.crypto.Cipher
import java.nio.file.Files
import java.nio.file.attribute.PosixFilePermission
import java.security.Security
@RunWith(JUnit4.class)
class NiFiPropertiesLoaderGroovyTest extends GroovyTestCase {
private static final Logger logger = LoggerFactory.getLogger(NiFiPropertiesLoaderGroovyTest.class)
final def DEFAULT_SENSITIVE_PROPERTIES = [
"nifi.sensitive.props.key",
"nifi.security.keystorePasswd",
"nifi.security.keyPasswd",
"nifi.security.truststorePasswd"
]
final def COMMON_ADDITIONAL_SENSITIVE_PROPERTIES = [
"nifi.sensitive.props.algorithm",
"nifi.kerberos.service.principal",
"nifi.kerberos.krb5.file",
"nifi.kerberos.keytab.location"
]
private static final String KEY_HEX_128 = "0123456789ABCDEFFEDCBA9876543210"
private static final String KEY_HEX_256 = KEY_HEX_128 * 2
public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
private static final String PASSWORD_KEY_HEX_128 = "2C576A9585DB862F5ECBEE5B4FFFCCA1"
private static String originalPropertiesPath = System.getProperty(NiFiProperties.PROPERTIES_FILE_PATH)
private
final Set<PosixFilePermission> ownerReadWrite = [PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_READ]
private static boolean isUnlimitedStrengthCryptoAvailable() {
Cipher.getMaxAllowedKeyLength("AES") > 128
}
@BeforeClass
static void setUpOnce() throws Exception {
Assume.assumeTrue("Test only runs on *nix", !SystemUtils.IS_OS_WINDOWS)
Security.addProvider(new BouncyCastleProvider())
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
}
@Before
void setUp() throws Exception {
}
@After
void tearDown() throws Exception {
// Clear the sensitive property providers between runs
// if (ProtectedNiFiProperties.@localProviderCache) {
// ProtectedNiFiProperties.@localProviderCache = [:]
// }
}
@AfterClass
static void tearDownOnce() {
if (originalPropertiesPath) {
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, originalPropertiesPath)
}
}
@Test
void testConstructorShouldCreateNewInstance() throws Exception {
// Arrange
// Act
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Assert
assert !niFiPropertiesLoader.@instance
assert !niFiPropertiesLoader.@keyHex
}
@Test
void testShouldCreateInstanceWithKey() throws Exception {
// Arrange
// Act
NiFiPropertiesLoader niFiPropertiesLoader = NiFiPropertiesLoader.withKey(KEY_HEX)
// Assert
assert !niFiPropertiesLoader.@instance
assert niFiPropertiesLoader.@keyHex == KEY_HEX
}
@Test
void testShouldLoadUnprotectedPropertiesFromFile() throws Exception {
// Arrange
File unprotectedFile = new File("src/test/resources/conf/nifi.properties")
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
NiFiProperties niFiProperties = niFiPropertiesLoader.load(unprotectedFile)
// Assert
assert niFiProperties.size() > 0
// Ensure it is not a ProtectedNiFiProperties
assert !(niFiProperties instanceof ProtectedNiFiProperties)
}
@Test
void testShouldLoadUnprotectedPropertiesFromFileWithoutBootstrap() throws Exception {
// Arrange
File unprotectedFile = new File("src/test/resources/conf/nifi.properties")
// Set the system property to the test file
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, unprotectedFile.absolutePath)
logger.info("Set ${NiFiProperties.PROPERTIES_FILE_PATH} to ${unprotectedFile.absolutePath}")
// Act
NiFiProperties niFiProperties = NiFiPropertiesLoader.loadDefaultWithKeyFromBootstrap()
// Assert
assert niFiProperties.size() > 0
// Ensure it is not a ProtectedNiFiProperties
assert !(niFiProperties instanceof ProtectedNiFiProperties)
}
@Test
void testShouldNotLoadProtectedPropertiesFromFileWithoutBootstrap() throws Exception {
// Arrange
File protectedFile = new File("src/test/resources/conf/nifi_with_sensitive_properties_protected_aes.properties")
// Set the system property to the test file
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, protectedFile.absolutePath)
logger.info("Set ${NiFiProperties.PROPERTIES_FILE_PATH} to ${protectedFile.absolutePath}")
// Act
def msg = shouldFail(SensitivePropertyProtectionException) {
NiFiProperties niFiProperties = NiFiPropertiesLoader.loadDefaultWithKeyFromBootstrap()
}
logger.expected(msg)
// Assert
assert msg =~ "Could not read root key from bootstrap.conf"
}
@Test
void testShouldLoadUnprotectedPropertiesFromPathWithGeneratedSensitivePropertiesKey() throws Exception {
// Arrange
final File propertiesFile = File.createTempFile("nifi.without.key", ".properties")
propertiesFile.deleteOnExit()
final OutputStream outputStream = new FileOutputStream(propertiesFile)
final InputStream inputStream = getClass().getResourceAsStream("/conf/nifi.without.key.properties")
FileUtils.copy(inputStream, outputStream)
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, propertiesFile.absolutePath);
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
NiFiProperties niFiProperties = niFiPropertiesLoader.get()
// Assert
final String sensitivePropertiesKey = niFiProperties.getProperty(NiFiProperties.SENSITIVE_PROPS_KEY)
assert sensitivePropertiesKey.length() == 32
}
@Test
void testShouldNotLoadUnprotectedPropertiesFromPathWithBlankKeyForClusterNode() throws Exception {
// Arrange
final File propertiesFile = File.createTempFile("nifi.without.key", ".properties")
propertiesFile.deleteOnExit()
final OutputStream outputStream = new FileOutputStream(propertiesFile)
final InputStream inputStream = getClass().getResourceAsStream("/conf/nifi.cluster.without.key.properties")
FileUtils.copy(inputStream, outputStream)
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, propertiesFile.absolutePath);
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
shouldFail(SensitivePropertyProtectionException) {
niFiPropertiesLoader.get()
}
}
@Test
void testShouldNotLoadUnprotectedPropertiesFromNullFile() throws Exception {
// Arrange
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
def msg = shouldFail(IllegalArgumentException) {
NiFiProperties niFiProperties = niFiPropertiesLoader.load(null as File)
}
logger.expected(msg)
// Assert
assert msg == "NiFi properties file missing or unreadable"
}
@Test
void testShouldNotLoadUnprotectedPropertiesFromMissingFile() throws Exception {
// Arrange
File missingFile = new File("src/test/resources/conf/nifi_missing.properties")
assert !missingFile.exists()
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
def msg = shouldFail(IllegalArgumentException) {
NiFiProperties niFiProperties = niFiPropertiesLoader.load(missingFile)
}
logger.expected(msg)
// Assert
assert msg == "NiFi properties file missing or unreadable"
}
@Test
void testShouldNotLoadUnprotectedPropertiesFromUnreadableFile() throws Exception {
// Arrange
File unreadableFile = new File("src/test/resources/conf/nifi_no_permissions.properties")
Files.setPosixFilePermissions(unreadableFile.toPath(), [] as Set)
assert !unreadableFile.canRead()
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
def msg = shouldFail(IllegalArgumentException) {
NiFiProperties niFiProperties = niFiPropertiesLoader.load(unreadableFile)
}
logger.expected(msg)
// Assert
assert msg == "NiFi properties file missing or unreadable"
// Clean up to allow for indexing, etc.
Files.setPosixFilePermissions(unreadableFile.toPath(), ownerReadWrite)
}
@Test
void testShouldLoadUnprotectedPropertiesFromPath() throws Exception {
// Arrange
File unprotectedFile = new File("src/test/resources/conf/nifi.properties")
NiFiPropertiesLoader niFiPropertiesLoader = new NiFiPropertiesLoader()
// Act
NiFiProperties niFiProperties = niFiPropertiesLoader.load(unprotectedFile.path)
// Assert
assert niFiProperties.size() > 0
// Ensure it is not a ProtectedNiFiProperties
assert !(niFiProperties instanceof ProtectedNiFiProperties)
}
@Test
void testShouldLoadUnprotectedPropertiesFromProtectedFile() throws Exception {
// Arrange
File protectedFile = new File("src/test/resources/conf/nifi_with_sensitive_properties_protected_aes.properties")
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, protectedFile.path)
NiFiPropertiesLoader niFiPropertiesLoader = NiFiPropertiesLoader.withKey(KEY_HEX)
final def EXPECTED_PLAIN_VALUES = [
(NiFiProperties.SENSITIVE_PROPS_KEY): "thisIsABadSensitiveKeyPassword",
(NiFiProperties.SECURITY_KEYSTORE_PASSWD): "thisIsABadKeystorePassword",
(NiFiProperties.SECURITY_KEY_PASSWD): "thisIsABadKeyPassword",
]
// This method is covered in tests above, so safe to use here to retrieve protected properties
ProtectedNiFiProperties protectedNiFiProperties = niFiPropertiesLoader.readProtectedPropertiesFromDisk(protectedFile)
int totalKeysCount = protectedNiFiProperties.getPropertyKeysIncludingProtectionSchemes().size()
int protectedKeysCount = protectedNiFiProperties.getProtectedPropertyKeys().size()
logger.info("Read ${totalKeysCount} total properties (${protectedKeysCount} protected) from ${protectedFile.canonicalPath}")
// Act
NiFiProperties niFiProperties = niFiPropertiesLoader.load(protectedFile)
// Assert
assert niFiProperties.size() == totalKeysCount - protectedKeysCount
// Ensure that any key marked as protected above is different in this instance
protectedNiFiProperties.getProtectedPropertyKeys().keySet().each { String key ->
String plainValue = niFiProperties.getProperty(key)
String protectedValue = protectedNiFiProperties.getProperty(key)
logger.info("Checking that [${protectedValue}] -> [${plainValue}] == [${EXPECTED_PLAIN_VALUES[key]}]")
assert plainValue == EXPECTED_PLAIN_VALUES[key]
assert plainValue != protectedValue
assert plainValue.length() <= protectedValue.length()
}
// Ensure it is not a ProtectedNiFiProperties
assert !(niFiProperties instanceof ProtectedNiFiProperties)
}
@Test
void testShouldExtractKeyFromBootstrapFile() throws Exception {
// Arrange
def defaultNiFiPropertiesFilePath = "src/test/resources/bootstrap_tests/conf/nifi.properties"
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, defaultNiFiPropertiesFilePath)
// Act
String key = NiFiBootstrapUtils.extractKeyFromBootstrapFile()
// Assert
assert key == KEY_HEX
}
@Test
void testShouldNotExtractKeyFromBootstrapFileWithoutKeyLine() throws Exception {
// Arrange
def defaultNiFiPropertiesFilePath = "src/test/resources/bootstrap_tests/missing_key_line/nifi.properties"
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, defaultNiFiPropertiesFilePath)
// Act
String key = NiFiBootstrapUtils.extractKeyFromBootstrapFile()
// Assert
assert key == ""
}
@Test
void testShouldNotExtractKeyFromBootstrapFileWithoutKey() throws Exception {
// Arrange
def defaultNiFiPropertiesFilePath = "src/test/resources/bootstrap_tests/missing_key_line/nifi.properties"
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, defaultNiFiPropertiesFilePath)
// Act
String key = NiFiBootstrapUtils.extractKeyFromBootstrapFile()
// Assert
assert key == ""
}
@Test
void testShouldNotExtractKeyFromMissingBootstrapFile() throws Exception {
// Arrange
def defaultNiFiPropertiesFilePath = "src/test/resources/bootstrap_tests/missing_bootstrap/nifi.properties"
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, defaultNiFiPropertiesFilePath)
// Act
def msg = shouldFail(IOException) {
String key = NiFiBootstrapUtils.extractKeyFromBootstrapFile()
}
logger.expected(msg)
// Assert
assert msg =~ "Cannot read from .*bootstrap.conf"
}
@Test
void testShouldNotExtractKeyFromUnreadableBootstrapFile() throws Exception {
// Arrange
File unreadableFile = new File("src/test/resources/bootstrap_tests/unreadable_bootstrap/bootstrap.conf")
Set<PosixFilePermission> originalPermissions = Files.getPosixFilePermissions(unreadableFile.toPath())
Files.setPosixFilePermissions(unreadableFile.toPath(), [] as Set)
assert !unreadableFile.canRead()
def defaultNiFiPropertiesFilePath = "src/test/resources/bootstrap_tests/unreadable_bootstrap/nifi.properties"
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, defaultNiFiPropertiesFilePath)
// Act
def msg = shouldFail(IOException) {
String key = NiFiBootstrapUtils.extractKeyFromBootstrapFile()
}
logger.expected(msg)
// Assert
assert msg =~ "Cannot read from .*bootstrap.conf"
// Clean up to allow for indexing, etc.
Files.setPosixFilePermissions(unreadableFile.toPath(), originalPermissions)
}
@Ignore("Unreadable conf directory breaks build")
@Test
void testShouldNotExtractKeyFromUnreadableConfDir() throws Exception {
// Arrange
File unreadableDir = new File("src/test/resources/bootstrap_tests/unreadable_conf")
Set<PosixFilePermission> originalPermissions = Files.getPosixFilePermissions(unreadableDir.toPath())
Files.setPosixFilePermissions(unreadableDir.toPath(), [] as Set)
assert !unreadableDir.canRead()
def defaultNiFiPropertiesFilePath = "src/test/resources/bootstrap_tests/unreadable_conf/nifi.properties"
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, defaultNiFiPropertiesFilePath)
// Act
def msg = shouldFail(IOException) {
String key = NiFiBootstrapUtils.extractKeyFromBootstrapFile()
}
logger.expected(msg)
// Assert
assert msg == "Cannot read from bootstrap.conf"
// Clean up to allow for indexing, etc.
Files.setPosixFilePermissions(unreadableDir.toPath(), originalPermissions)
}
@Test
void testShouldLoadUnprotectedPropertiesFromProtectedDefaultFileAndUseBootstrapKey() throws Exception {
// Arrange
File protectedFile = new File("src/test/resources/bootstrap_tests/conf/nifi_with_sensitive_properties_protected_aes.properties")
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, protectedFile.path)
NiFiPropertiesLoader niFiPropertiesLoader = NiFiPropertiesLoader.withKey(KEY_HEX)
NiFiProperties normalReadProperties = niFiPropertiesLoader.load(protectedFile)
logger.info("Read ${normalReadProperties.size()} total properties from ${protectedFile.canonicalPath}")
// Act
NiFiProperties niFiProperties = NiFiPropertiesLoader.loadDefaultWithKeyFromBootstrap()
// Assert
assert niFiProperties.size() == normalReadProperties.size()
def readPropertiesAndValues = niFiProperties.getPropertyKeys().collectEntries {
[(it): niFiProperties.getProperty(it)]
}
def expectedPropertiesAndValues = normalReadProperties.getPropertyKeys().collectEntries {
[(it): normalReadProperties.getProperty(it)]
}
assert readPropertiesAndValues == expectedPropertiesAndValues
}
@Test
void testShouldUpdateKeyInFactory() throws Exception {
// Arrange
File originalKeyFile = new File("src/test/resources/conf/nifi_with_sensitive_properties_protected_aes_128.properties")
File passwordKeyFile = new File("src/test/resources/conf/nifi_with_sensitive_properties_protected_aes_128_password.properties")
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, originalKeyFile.path)
NiFiPropertiesLoader niFiPropertiesLoader = NiFiPropertiesLoader.withKey(KEY_HEX_128)
NiFiProperties niFiProperties = niFiPropertiesLoader.load(originalKeyFile)
logger.info("Read ${niFiProperties.size()} total properties from ${originalKeyFile.canonicalPath}")
// Act
NiFiPropertiesLoader passwordNiFiPropertiesLoader = NiFiPropertiesLoader.withKey(PASSWORD_KEY_HEX_128)
NiFiProperties passwordProperties = passwordNiFiPropertiesLoader.load(passwordKeyFile)
logger.info("Read ${passwordProperties.size()} total properties from ${passwordKeyFile.canonicalPath}")
// Assert
assert niFiProperties.size() == passwordProperties.size()
def readPropertiesAndValues = niFiProperties.getPropertyKeys().collectEntries {
[(it): niFiProperties.getProperty(it)]
}
def readPasswordPropertiesAndValues = passwordProperties.getPropertyKeys().collectEntries {
[(it): passwordProperties.getProperty(it)]
}
assert readPropertiesAndValues == readPasswordPropertiesAndValues
}
}

View File

@ -0,0 +1,138 @@
/*
* 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.properties;
import org.apache.nifi.util.NiFiProperties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import java.net.URL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
class NiFiPropertiesLoaderTest {
private static final String NULL_PATH = null;
private static final String EMPTY_PATH = "/properties/conf/empty.nifi.properties";
private static final String FLOW_PATH = "/properties/conf/flow.nifi.properties";
private static final String PROTECTED_PATH = "/properties/conf/protected.nifi.properties";
private static final String HEXADECIMAL_KEY = "12345678123456788765432187654321";
private static final String EXPECTED_PASSWORD = "propertyValue";
@AfterEach
void clearSystemProperty() {
System.clearProperty(NiFiProperties.PROPERTIES_FILE_PATH);
}
@Test
void testGetPropertiesNotFound() {
final NiFiPropertiesLoader loader = new NiFiPropertiesLoader();
assertThrows(IllegalArgumentException.class, loader::get);
}
@Test
void testGetProperties() {
final URL resource = NiFiPropertiesLoaderTest.class.getResource(FLOW_PATH);
assertNotNull(resource);
final String path = resource.getPath();
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, path);
final NiFiPropertiesLoader loader = new NiFiPropertiesLoader();
final NiFiProperties properties = loader.get();
assertNotNull(properties);
assertNotNull(properties.getFlowConfigurationFile());
}
@Test
void testGetPropertiesWithKeyNoEncryptedProperties() {
final URL resource = NiFiPropertiesLoaderTest.class.getResource(FLOW_PATH);
assertNotNull(resource);
final String path = resource.getPath();
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, path);
final NiFiPropertiesLoader loader = NiFiPropertiesLoader.withKey(String.class.getSimpleName());
final NiFiProperties properties = loader.get();
assertNotNull(properties);
assertNotNull(properties.getFlowConfigurationFile());
}
@Test
void testLoadWithKey() {
final NiFiPropertiesLoader loader = NiFiPropertiesLoader.withKey(HEXADECIMAL_KEY);
final URL resource = NiFiPropertiesLoaderTest.class.getResource(PROTECTED_PATH);
assertNotNull(resource);
final String path = resource.getPath();
final NiFiProperties properties = loader.load(path);
assertNotNull(properties);
assertNotNull(properties.getFlowConfigurationFile());
assertEquals(EXPECTED_PASSWORD, properties.getProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD));
}
@Test
void testLoadWithDefaultKeyFromBootstrap() {
final URL resource = NiFiPropertiesLoaderTest.class.getResource(FLOW_PATH);
assertNotNull(resource);
final String path = resource.getPath();
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, path);
final NiFiProperties properties = NiFiPropertiesLoader.loadDefaultWithKeyFromBootstrap();
assertNotNull(properties);
}
@Test
void testLoadDefaultNotFound() {
final NiFiPropertiesLoader loader = new NiFiPropertiesLoader();
assertThrows(IllegalArgumentException.class, () -> loader.load(NULL_PATH));
}
@Test
void testLoadPath() {
final NiFiPropertiesLoader loader = new NiFiPropertiesLoader();
final URL resource = NiFiPropertiesLoaderTest.class.getResource(EMPTY_PATH);
assertNotNull(resource);
final String path = resource.getPath();
final NiFiProperties properties = loader.load(path);
assertNotNull(properties);
}
}

View File

@ -1,74 +0,0 @@
#
# 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.
#
# Java command to use when running NiFi
java=java
# Username to use when running NiFi. This value will be ignored on Windows.
run.as=
# Configure where NiFi's lib and conf directories live
lib.dir=./lib
conf.dir=./conf
# How long to wait after telling NiFi to shutdown before explicitly killing the Process
graceful.shutdown.seconds=20
# Disable JSR 199 so that we can use JSP's without running a JDK
java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
# JVM memory settings
java.arg.2=-Xms512m
java.arg.3=-Xmx512m
# Enable Remote Debugging
#java.arg.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
java.arg.4=-Djava.net.preferIPv4Stack=true
# allowRestrictedHeaders is required for Cluster/Node communications to work properly
java.arg.5=-Dsun.net.http.allowRestrictedHeaders=true
java.arg.6=-Djava.protocol.handler.pkgs=sun.net.www.protocol
# The G1GC is still considered experimental but has proven to be very advantageous in providing great
# performance without significant "stop-the-world" delays.
java.arg.13=-XX:+UseG1GC
#Set headless mode by default
java.arg.14=-Djava.awt.headless=true
# Root key in hexadecimal format for encrypted sensitive configuration values
nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
###
# Notification Services for notifying interested parties when NiFi is stopped, started, dies
###
# XML File that contains the definitions of the notification services
notification.services.file=./conf/bootstrap-notification-services.xml
# In the case that we are unable to send a notification for an event, how many times should we retry?
notification.max.attempts=5
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is started?
#nifi.start.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is stopped?
#nifi.stop.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi dies?
#nifi.dead.notification.services=email-notification

View File

@ -1,126 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=aes/gcm/256
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03vcbo
nifi.security.keystorePasswd.protected=aes/gcm/256
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
nifi.security.keyPasswd.protected=aes/gcm/256
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=/X/RSlNr2QCJ1Kwe||dENJevX5P61ix+97airrtoBQoyasMFS6DG6fHbX+SZtw2VAMllSSnDeT97Q=
nifi.security.truststorePasswd.protected=aes/gcm/256
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,74 +0,0 @@
#
# 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.
#
# Java command to use when running NiFi
java=java
# Username to use when running NiFi. This value will be ignored on Windows.
run.as=
# Configure where NiFi's lib and conf directories live
lib.dir=./lib
conf.dir=./conf
# How long to wait after telling NiFi to shutdown before explicitly killing the Process
graceful.shutdown.seconds=20
# Disable JSR 199 so that we can use JSP's without running a JDK
java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
# JVM memory settings
java.arg.2=-Xms512m
java.arg.3=-Xmx512m
# Enable Remote Debugging
#java.arg.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
java.arg.4=-Djava.net.preferIPv4Stack=true
# allowRestrictedHeaders is required for Cluster/Node communications to work properly
java.arg.5=-Dsun.net.http.allowRestrictedHeaders=true
java.arg.6=-Djava.protocol.handler.pkgs=sun.net.www.protocol
# The G1GC is still considered experimental but has proven to be very advantageous in providing great
# performance without significant "stop-the-world" delays.
java.arg.13=-XX:+UseG1GC
#Set headless mode by default
java.arg.14=-Djava.awt.headless=true
# Root key in hexadecimal format for encrypted sensitive configuration values
nifi.bootstrap.sensitive.key=
###
# Notification Services for notifying interested parties when NiFi is stopped, started, dies
###
# XML File that contains the definitions of the notification services
notification.services.file=./conf/bootstrap-notification-services.xml
# In the case that we are unable to send a notification for an event, how many times should we retry?
notification.max.attempts=5
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is started?
#nifi.start.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is stopped?
#nifi.stop.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi dies?
#nifi.dead.notification.services=email-notification

View File

@ -1,71 +0,0 @@
#
# 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.
#
# Java command to use when running NiFi
java=java
# Username to use when running NiFi. This value will be ignored on Windows.
run.as=
# Configure where NiFi's lib and conf directories live
lib.dir=./lib
conf.dir=./conf
# How long to wait after telling NiFi to shutdown before explicitly killing the Process
graceful.shutdown.seconds=20
# Disable JSR 199 so that we can use JSP's without running a JDK
java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
# JVM memory settings
java.arg.2=-Xms512m
java.arg.3=-Xmx512m
# Enable Remote Debugging
#java.arg.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
java.arg.4=-Djava.net.preferIPv4Stack=true
# allowRestrictedHeaders is required for Cluster/Node communications to work properly
java.arg.5=-Dsun.net.http.allowRestrictedHeaders=true
java.arg.6=-Djava.protocol.handler.pkgs=sun.net.www.protocol
# The G1GC is still considered experimental but has proven to be very advantageous in providing great
# performance without significant "stop-the-world" delays.
java.arg.13=-XX:+UseG1GC
#Set headless mode by default
java.arg.14=-Djava.awt.headless=true
###
# Notification Services for notifying interested parties when NiFi is stopped, started, dies
###
# XML File that contains the definitions of the notification services
notification.services.file=./conf/bootstrap-notification-services.xml
# In the case that we are unable to send a notification for an event, how many times should we retry?
notification.max.attempts=5
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is started?
#nifi.start.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is stopped?
#nifi.stop.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi dies?
#nifi.dead.notification.services=email-notification

View File

@ -1,74 +0,0 @@
#
# 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.
#
# Java command to use when running NiFi
java=java
# Username to use when running NiFi. This value will be ignored on Windows.
run.as=
# Configure where NiFi's lib and conf directories live
lib.dir=./lib
conf.dir=./conf
# How long to wait after telling NiFi to shutdown before explicitly killing the Process
graceful.shutdown.seconds=20
# Disable JSR 199 so that we can use JSP's without running a JDK
java.arg.1=-Dorg.apache.jasper.compiler.disablejsr199=true
# JVM memory settings
java.arg.2=-Xms512m
java.arg.3=-Xmx512m
# Enable Remote Debugging
#java.arg.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
java.arg.4=-Djava.net.preferIPv4Stack=true
# allowRestrictedHeaders is required for Cluster/Node communications to work properly
java.arg.5=-Dsun.net.http.allowRestrictedHeaders=true
java.arg.6=-Djava.protocol.handler.pkgs=sun.net.www.protocol
# The G1GC is still considered experimental but has proven to be very advantageous in providing great
# performance without significant "stop-the-world" delays.
java.arg.13=-XX:+UseG1GC
#Set headless mode by default
java.arg.14=-Djava.awt.headless=true
# Root key in hexadecimal format for encrypted sensitive configuration values
nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
###
# Notification Services for notifying interested parties when NiFi is stopped, started, dies
###
# XML File that contains the definitions of the notification services
notification.services.file=./conf/bootstrap-notification-services.xml
# In the case that we are unable to send a notification for an event, how many times should we retry?
notification.max.attempts=5
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is started?
#nifi.start.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi is stopped?
#nifi.stop.notification.services=email-notification
# Comma-separated list of identifiers that are present in the notification.services.file; which services should be used to notify when NiFi dies?
#nifi.dead.notification.services=email-notification

View File

@ -1,121 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=
nifi.custom.nar.library.directory.alt=
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=key
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,94 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=true
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2

View File

@ -1,119 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=key
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,121 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=key
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,94 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2

View File

@ -1,122 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=key
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version, nifi.sensitive.props.additional.keys
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,126 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=aes/gcm/256
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03vcbo
nifi.security.keystorePasswd.protected=aes/gcm/256
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
nifi.security.keyPasswd.protected=aes/gcm/256
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=/X/RSlNr2QCJ1Kwe||dENJevX5P61ix+97airrtoBQoyasMFS6DG6fHbX+SZtw2VAMllSSnDeT97Q=
nifi.security.truststorePasswd.protected=aes/gcm/256
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,122 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=8080
nifi.web.https.host=
nifi.web.https.port=
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=key
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version, nifi.sensitive.props.additional.keys
nifi.security.keystore=
nifi.security.keystoreType=
nifi.security.keystorePasswd=
nifi.security.keyPasswd=
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=aes/gcm/256
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03vcbo
nifi.security.keystorePasswd.protected=aes/gcm/256
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
nifi.security.keyPasswd.protected=aes/gcm/256
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=6WUpex+VZiN05LXu||joWJMuoSzYniEC7IAoingTimlG7+RGk8I2irl/WTlIuMcg
nifi.sensitive.props.key.protected=aes/gcm/128
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=6WUpex+VZiN05LXu||joWJMuoSzYniEC7IAoingTimlG7+RGk8I2irl/WTlIuMcg
nifi.security.keystorePasswd.protected=aes/gcm/128
nifi.security.keyPasswd=6WUpex+VZiN05LXu||joWJMuoSzYniEC7IAoingTimlG7+RGk8I2irl/WTlIuMcg
nifi.security.keyPasswd.protected=aes/gcm/128
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=oa6Aaz5tlFprPuKt||IlVgftF2VqvBIambkP5HVDbRoyKzZl8wwKSw4O9tjHTALA
nifi.sensitive.props.key.protected=aes/gcm/128
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oa6Aaz5tlFprPuKt||IlVgftF2VqvBIambkP5HVDbRoyKzZl8wwKSw4O9tjHTALA
nifi.security.keystorePasswd.protected=aes/gcm/128
nifi.security.keyPasswd=oa6Aaz5tlFprPuKt||IlVgftF2VqvBIambkP5HVDbRoyKzZl8wwKSw4O9tjHTALA
nifi.security.keyPasswd.protected=aes/gcm/128
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=aes/gcm/256
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03
nifi.security.keystorePasswd.protected=aes/gcm/256
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
nifi.security.keyPasswd.protected=aes/gcm/256
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=aes/gcm/256
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytaC/w/KFe0HOkrJR03vcbo
nifi.security.keystorePasswd.protected=aes/gcm/256
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBK/hGebDKlVg==
nifi.security.keyPasswd.protected=aes/gcm/256
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=aes/gcm/256
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03
nifi.security.keystorePasswd.protected=aes/gcm/256
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
nifi.security.keyPasswd.protected=aes/gcm/256
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,125 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
nifi.sensitive.props.key.protected=unknown
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03vcbo
nifi.security.keystorePasswd.protected=unknown
nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
nifi.security.keyPasswd.protected=unknown
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,122 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=thisIsABadSensitiveKeyPassword
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=thisIsABadKeystorePassword
nifi.security.keyPasswd=thisIsABadKeyPassword
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,123 +0,0 @@
# 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.
# Core Properties #
nifi.flow.configuration.file=./target/flow.xml.gz
nifi.flow.configuration.archive.dir=./target/archive/
nifi.flowcontroller.autoResumeState=true
nifi.flowcontroller.graceful.shutdown.period=10 sec
nifi.flowservice.writedelay.interval=2 sec
nifi.administrative.yield.duration=30 sec
nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
nifi.controller.service.configuration.file=./target/controller-services.xml
nifi.templates.directory=./target/templates
nifi.ui.banner.text=UI Banner Text
nifi.ui.autorefresh.interval=30 sec
nifi.nar.library.directory=./target/resources/NiFiProperties/lib/
nifi.nar.library.directory.alt=./target/resources/NiFiProperties/lib2/
nifi.nar.working.directory=./target/work/nar/
# H2 Settings
nifi.database.directory=./target/database_repository
nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
# FlowFile Repository
nifi.flowfile.repository.directory=./target/test-repo
nifi.flowfile.repository.partitions=1
nifi.flowfile.repository.checkpoint.interval=2 mins
nifi.queue.swap.threshold=20000
nifi.swap.storage.directory=./target/test-repo/swap
nifi.swap.in.period=5 sec
nifi.swap.in.threads=1
nifi.swap.out.period=5 sec
nifi.swap.out.threads=4
# Content Repository
nifi.content.claim.max.appendable.size=10 MB
nifi.content.claim.max.flow.files=100
nifi.content.repository.directory.default=./target/content_repository
# Provenance Repository Properties
nifi.provenance.repository.storage.directory=./target/provenance_repository
nifi.provenance.repository.max.storage.time=24 hours
nifi.provenance.repository.max.storage.size=1 GB
nifi.provenance.repository.rollover.time=30 secs
nifi.provenance.repository.rollover.size=100 MB
# Site to Site properties
nifi.remote.input.socket.port=9990
nifi.remote.input.secure=true
# web properties #
nifi.web.war.directory=./target/lib
nifi.web.http.host=
nifi.web.http.port=
nifi.web.https.host=nifi.nifi.apache.org
nifi.web.https.port=8443
nifi.web.jetty.working.directory=./target/work/jetty
# security properties #
nifi.sensitive.props.key=thisIsABadSensitiveKeyPassword
nifi.sensitive.props.key.protected=
nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
nifi.sensitive.props.additional.keys=nifi.ui.banner.text, nifi.version
nifi.security.keystore=/path/to/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=thisIsABadKeystorePassword
nifi.security.keyPasswd=thisIsABadKeyPassword
nifi.security.truststore=
nifi.security.truststoreType=
nifi.security.truststorePasswd=
nifi.security.user.authorizer=
# cluster common properties (cluster manager and nodes must have same values) #
nifi.cluster.protocol.heartbeat.interval=5 sec
nifi.cluster.protocol.is.secure=false
nifi.cluster.protocol.socket.timeout=30 sec
nifi.cluster.protocol.connection.handshake.timeout=45 sec
# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
nifi.cluster.protocol.use.multicast=false
nifi.cluster.protocol.multicast.address=
nifi.cluster.protocol.multicast.port=
nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
nifi.cluster.protocol.multicast.service.locator.attempts=3
nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
# cluster node properties (only configure for cluster nodes) #
nifi.cluster.is.node=false
nifi.cluster.node.address=
nifi.cluster.node.protocol.port=
nifi.cluster.node.protocol.threads=2
# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
nifi.cluster.node.unicast.manager.address=
nifi.cluster.node.unicast.manager.protocol.port=
nifi.cluster.node.unicast.manager.authority.provider.port=
# cluster manager properties (only configure for cluster manager) #
nifi.cluster.is.manager=false
nifi.cluster.manager.address=
nifi.cluster.manager.protocol.port=
nifi.cluster.manager.authority.provider.port=
nifi.cluster.manager.authority.provider.threads=10
nifi.cluster.manager.node.firewall.file=
nifi.cluster.manager.node.event.history.size=10
nifi.cluster.manager.node.api.connection.timeout=30 sec
nifi.cluster.manager.node.api.read.timeout=30 sec
nifi.cluster.manager.node.api.request.threads=10
nifi.cluster.manager.flow.retrieval.delay=5 sec
nifi.cluster.manager.protocol.threads=10
nifi.cluster.manager.safemode.duration=0 sec

View File

@ -1,24 +0,0 @@
# 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.
# properties with whitespace
nifi.whitespace.propWithNoSpace=foo
nifi.whitespace.propWithLeadingSpace= foo
nifi.whitespace.propWithTrailingSpace=foo
nifi.whitespace.propWithLeadingAndTrailingSpace= foo
nifi.whitespace.propWithTrailingTab=foo\t
nifi.whitespace.propWithMultipleLines=foo\
bar\
baz

View File

@ -12,3 +12,6 @@
# 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.
nifi.flow.configuration.file=./conf/flow.xml.gz
nifi.flow.configuration.json.file=./conf/flow.json.gz

View File

@ -0,0 +1,20 @@
# 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.
nifi.flow.configuration.file=./conf/flow.xml.gz
nifi.flow.configuration.json.file=./conf/flow.json.gz
nifi.security.keystorePasswd=Ycac+pAe3AdHbCAC||ImnArC6KZJ+WXDMwJw2cjpOpNJFk1s5XyfbkrB8=
nifi.security.keystorePasswd.protected=aes/gcm/128

View File

@ -57,6 +57,21 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -12,3 +12,5 @@
# 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.
nifi.bootstrap.sensitive.key=0000000000000000000000000000000000000000000000000000000000000000

View File

@ -160,6 +160,14 @@
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-framework-authorization</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
@ -238,6 +246,11 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>

View File

@ -32,7 +32,14 @@ import org.apache.nifi.authentication.generated.Provider;
import org.apache.nifi.bundle.Bundle;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.nar.NarCloseable;
import org.apache.nifi.properties.SensitivePropertyProviderFactoryAware;
import org.apache.nifi.properties.ProtectedPropertyContext;
import org.apache.nifi.properties.SensitivePropertyProvider;
import org.apache.nifi.properties.SensitivePropertyProviderFactory;
import org.apache.nifi.properties.scheme.ProtectionScheme;
import org.apache.nifi.properties.scheme.ProtectionSchemeResolver;
import org.apache.nifi.property.protection.loader.PropertyProtectionURLClassLoader;
import org.apache.nifi.property.protection.loader.PropertyProviderFactoryLoader;
import org.apache.nifi.property.protection.loader.ProtectionSchemeResolverLoader;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.xml.processing.stream.StandardXMLStreamReaderProvider;
import org.apache.nifi.xml.processing.stream.XMLStreamReaderProvider;
@ -59,10 +66,9 @@ import java.util.List;
import java.util.Map;
/**
*
* Spring Factory Bean implementation requires a generic Object return type to handle a null Provider configuration
*/
public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderFactoryAware
implements FactoryBean, DisposableBean, LoginIdentityProviderLookup {
public class LoginIdentityProviderFactoryBean implements FactoryBean<Object>, DisposableBean, LoginIdentityProviderLookup {
private static final String LOGIN_IDENTITY_PROVIDERS_XSD = "/login-identity-providers.xsd";
private static final String JAXB_GENERATED_PATH = "org.apache.nifi.authentication.generated";
@ -94,6 +100,12 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
return loginIdentityProviders.get(identifier);
}
/**
* Get Login Identity Provider Object or null when not configured
*
* @return Login Identity Provider instance or null when not configured
* @throws Exception Thrown on configuration failures
*/
@Override
public Object getObject() throws Exception {
if (loginIdentityProvider == null) {
@ -109,11 +121,7 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
loginIdentityProviders.put(provider.getIdentifier(), createLoginIdentityProvider(provider.getIdentifier(), provider.getClazz()));
}
// configure each login identity provider
for (final Provider provider : loginIdentityProviderConfiguration.getProvider()) {
final LoginIdentityProvider instance = loginIdentityProviders.get(provider.getIdentifier());
instance.onConfigured(loadLoginIdentityProviderConfiguration(provider));
}
loadProviderProperties(loginIdentityProviderConfiguration);
// get the login identity provider instance
loginIdentityProvider = getLoginIdentityProvider(loginIdentityProviderIdentifier);
@ -181,8 +189,8 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
Class<? extends LoginIdentityProvider> loginIdentityProviderClass = rawLoginIdentityProviderClass.asSubclass(LoginIdentityProvider.class);
// otherwise create a new instance
Constructor constructor = loginIdentityProviderClass.getConstructor();
instance = (LoginIdentityProvider) constructor.newInstance();
Constructor<? extends LoginIdentityProvider> constructor = loginIdentityProviderClass.getConstructor();
instance = constructor.newInstance();
// method injection
performMethodInjection(instance, loginIdentityProviderClass);
@ -201,23 +209,66 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
return withNarLoader(instance);
}
private LoginIdentityProviderConfigurationContext loadLoginIdentityProviderConfiguration(final Provider provider) {
private void loadProviderProperties(final LoginIdentityProviders loginIdentityProviderConfiguration) {
final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
final PropertyProtectionURLClassLoader protectionClassLoader = new PropertyProtectionURLClassLoader(contextClassLoader);
Thread.currentThread().setContextClassLoader(protectionClassLoader);
final ProtectionSchemeResolverLoader resolverLoader = new ProtectionSchemeResolverLoader();
final ProtectionSchemeResolver protectionSchemeResolver = resolverLoader.getProtectionSchemeResolver();
final PropertyProviderFactoryLoader factoryLoader = new PropertyProviderFactoryLoader();
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory = factoryLoader.getPropertyProviderFactory();
for (final Provider provider : loginIdentityProviderConfiguration.getProvider()) {
final LoginIdentityProvider instance = loginIdentityProviders.get(provider.getIdentifier());
final LoginIdentityProviderConfigurationContext configurationContext = getConfigurationContext(provider, sensitivePropertyProviderFactory, protectionSchemeResolver);
instance.onConfigured(configurationContext);
}
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}
private LoginIdentityProviderConfigurationContext getConfigurationContext(
final Provider provider,
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory,
final ProtectionSchemeResolver protectionSchemeResolver
) {
final String providerIdentifier = provider.getIdentifier();
final Map<String, String> providerProperties = new HashMap<>();
for (final Property property : provider.getProperty()) {
if (!StringUtils.isBlank(property.getEncryption())) {
String decryptedValue = decryptValue(property.getValue(), property.getEncryption(), property.getName(), provider
.getIdentifier());
providerProperties.put(property.getName(), decryptedValue);
} else {
final String encryption = property.getEncryption();
if (StringUtils.isBlank(encryption)) {
providerProperties.put(property.getName(), property.getValue());
} else {
final String propertyDecrypted = getPropertyDecrypted(providerIdentifier, property, sensitivePropertyProviderFactory, protectionSchemeResolver);
providerProperties.put(property.getName(), propertyDecrypted);
}
}
return new StandardLoginIdentityProviderConfigurationContext(provider.getIdentifier(), providerProperties);
return new StandardLoginIdentityProviderConfigurationContext(providerIdentifier, providerProperties);
}
private void performMethodInjection(final LoginIdentityProvider instance, final Class loginIdentityProviderClass)
private String getPropertyDecrypted(
final String providerIdentifier,
final Property property,
final SensitivePropertyProviderFactory sensitivePropertyProviderFactory,
final ProtectionSchemeResolver protectionSchemeResolver
) {
final String scheme = property.getEncryption();
final ProtectionScheme protectionScheme = protectionSchemeResolver.getProtectionScheme(scheme);
final SensitivePropertyProvider propertyProvider = sensitivePropertyProviderFactory.getProvider(protectionScheme);
final ProtectedPropertyContext protectedPropertyContext = sensitivePropertyProviderFactory.getPropertyContext(providerIdentifier, property.getName());
final String protectedProperty = property.getValue();
return propertyProvider.unprotect(protectedProperty, protectedPropertyContext);
}
private void performMethodInjection(final LoginIdentityProvider instance, final Class<?> loginIdentityProviderClass)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (final Method method : loginIdentityProviderClass.getMethods()) {
@ -245,13 +296,13 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
}
}
final Class parentClass = loginIdentityProviderClass.getSuperclass();
final Class<?> parentClass = loginIdentityProviderClass.getSuperclass();
if (parentClass != null && LoginIdentityProvider.class.isAssignableFrom(parentClass)) {
performMethodInjection(instance, parentClass);
}
}
private void performFieldInjection(final LoginIdentityProvider instance, final Class loginIdentityProviderClass) throws IllegalArgumentException, IllegalAccessException {
private void performFieldInjection(final LoginIdentityProvider instance, final Class<?> loginIdentityProviderClass) throws IllegalArgumentException, IllegalAccessException {
for (final Field field : loginIdentityProviderClass.getDeclaredFields()) {
if (field.isAnnotationPresent(LoginIdentityProviderContext.class)) {
// make the method accessible
@ -277,7 +328,7 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
}
}
final Class parentClass = loginIdentityProviderClass.getSuperclass();
final Class<?> parentClass = loginIdentityProviderClass.getSuperclass();
if (parentClass != null && LoginIdentityProvider.class.isAssignableFrom(parentClass)) {
performFieldInjection(instance, parentClass);
}
@ -317,7 +368,7 @@ public class LoginIdentityProviderFactoryBean extends SensitivePropertyProviderF
}
@Override
public Class getObjectType() {
public Class<?> getObjectType() {
return LoginIdentityProvider.class;
}

View File

@ -1,107 +0,0 @@
/*
* 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.web.security.spring
import org.apache.nifi.authentication.generated.Property
import org.apache.nifi.authentication.generated.Provider
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.crypto.Cipher
import java.security.Security
@RunWith(JUnit4.class)
class LoginIdentityProviderFactoryBeanTest extends GroovyTestCase {
private static final Logger logger = LoggerFactory.getLogger(LoginIdentityProviderFactoryBeanTest.class)
// These blocks configure the constant values depending on JCE policies of the machine running the tests
private static final String KEY_HEX_128 = "0123456789ABCDEFFEDCBA9876543210"
private static final String KEY_HEX_256 = KEY_HEX_128 * 2
public static final String KEY_HEX = isUnlimitedStrengthCryptoAvailable() ? KEY_HEX_256 : KEY_HEX_128
private static final String CIPHER_TEXT_128 = "6pqdM1urBEPHtj+L||ds0Z7RpqOA2321c/+7iPMfxDrqmH5Qx6UwQG0eIYB//3Ng"
private static final String CIPHER_TEXT_256 = "TepMCD7v3LAMF0KX||ydSRWPRl1/JXgTsZtfzCnDXu7a0lTLysjPL2I06EPUCHzw"
public static final String CIPHER_TEXT = isUnlimitedStrengthCryptoAvailable() ? CIPHER_TEXT_256 : CIPHER_TEXT_128
private static final String ENCRYPTION_SCHEME_128 = "aes/gcm/128"
private static final String ENCRYPTION_SCHEME_256 = "aes/gcm/256"
public static
final String ENCRYPTION_SCHEME = isUnlimitedStrengthCryptoAvailable() ? ENCRYPTION_SCHEME_256 : ENCRYPTION_SCHEME_128
private static final String PASSWORD = "thisIsABadPassword"
private LoginIdentityProviderFactoryBean bean
@BeforeClass
static void setUpOnce() throws Exception {
Security.addProvider(new BouncyCastleProvider())
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}
}
@Before
void setUp() {
bean = new LoginIdentityProviderFactoryBean()
bean.configureSensitivePropertyProviderFactory(KEY_HEX, null)
}
private static boolean isUnlimitedStrengthCryptoAvailable() {
Cipher.getMaxAllowedKeyLength("AES") > 128
}
@Test
void testShouldDecryptValue() {
// Arrange
logger.info("Encryption scheme: ${ENCRYPTION_SCHEME}")
logger.info("Cipher text: ${CIPHER_TEXT}")
// Act
String decrypted = bean.decryptValue(CIPHER_TEXT, ENCRYPTION_SCHEME, "propertyName", "ldap-provider")
logger.info("Decrypted ${CIPHER_TEXT} -> ${decrypted}")
// Assert
assert decrypted == PASSWORD
}
@Test
void testShouldLoadEncryptedLoginIdentityProviderConfiguration() {
// Arrange
Provider encryptedProvider = new Provider()
encryptedProvider.identifier ="ldap-provider"
encryptedProvider.clazz = "org.apache.nifi.ldap.LdapProvider"
def managerPasswordName = "Manager Password"
Property managerPasswordProperty = new Property(name: managerPasswordName, value: CIPHER_TEXT, encryption: ENCRYPTION_SCHEME)
encryptedProvider.property = [managerPasswordProperty]
logger.info("Manager Password property: ${managerPasswordProperty.dump()}")
// Act
def context = bean.loadLoginIdentityProviderConfiguration(encryptedProvider)
logger.info("Loaded context: ${context.dump()}")
// Assert
assert context.getProperty(managerPasswordName) == PASSWORD
}
}

View File

@ -0,0 +1,93 @@
/*
* 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.web.security.spring;
import org.apache.nifi.authentication.LoginIdentityProvider;
import org.apache.nifi.bundle.Bundle;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.security.spring.mock.MockLoginIdentityProvider;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class LoginIdentityProviderFactoryBeanTest {
private static final String PROVIDERS_PATH = "/login-identity-providers.xml";
private static final String PROVIDER_ID = "login-identity-provider";
@Mock
NiFiProperties properties;
@Mock
ExtensionManager extensionManager;
@Mock
Bundle bundle;
@Test
void testGetObjectNotConfigured() throws Exception {
final LoginIdentityProviderFactoryBean bean = new LoginIdentityProviderFactoryBean();
bean.setProperties(properties);
bean.setExtensionManager(extensionManager);
final Object object = bean.getObject();
assertNull(object);
}
@Test
void testGetObject() throws Exception {
when(properties.getProperty(eq(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER))).thenReturn(PROVIDER_ID);
when(properties.getLoginIdentityProviderConfigurationFile()).thenReturn(getLoginIdentityProvidersFile());
when(bundle.getClassLoader()).thenReturn(getClass().getClassLoader());
final List<Bundle> bundles = Collections.singletonList(bundle);
when(extensionManager.getBundles(eq(MockLoginIdentityProvider.class.getName()))).thenReturn(bundles);
final LoginIdentityProviderFactoryBean bean = new LoginIdentityProviderFactoryBean();
bean.setProperties(properties);
bean.setExtensionManager(extensionManager);
final Object object = bean.getObject();
assertInstanceOf(LoginIdentityProvider.class, object);
}
private File getLoginIdentityProvidersFile() {
final URL url = LoginIdentityProviderFactoryBeanTest.class.getResource(PROVIDERS_PATH);
if (url == null) {
throw new IllegalStateException(String.format("Providers [%s] not found", PROVIDERS_PATH));
}
return new File(url.getPath());
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.web.security.spring.mock;
import org.apache.nifi.authentication.AuthenticationResponse;
import org.apache.nifi.authentication.LoginCredentials;
import org.apache.nifi.authentication.LoginIdentityProvider;
import org.apache.nifi.authentication.LoginIdentityProviderConfigurationContext;
import org.apache.nifi.authentication.LoginIdentityProviderInitializationContext;
import org.apache.nifi.authentication.exception.IdentityAccessException;
import org.apache.nifi.authentication.exception.InvalidLoginCredentialsException;
import org.apache.nifi.authentication.exception.ProviderCreationException;
import org.apache.nifi.authentication.exception.ProviderDestructionException;
public class MockLoginIdentityProvider implements LoginIdentityProvider {
@Override
public AuthenticationResponse authenticate(final LoginCredentials credentials) throws InvalidLoginCredentialsException, IdentityAccessException {
return null;
}
@Override
public void initialize(LoginIdentityProviderInitializationContext initializationContext) throws ProviderCreationException {
}
@Override
public void onConfigured(LoginIdentityProviderConfigurationContext configurationContext) throws ProviderCreationException {
}
@Override
public void preDestruction() throws ProviderDestructionException {
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
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.
-->
<loginIdentityProviders>
<provider>
<identifier>login-identity-provider</identifier>
<class>org.apache.nifi.web.security.spring.mock.MockLoginIdentityProvider</class>
<property name="strategy">MOCK</property>
</provider>
</loginIdentityProviders>

View File

@ -161,6 +161,11 @@
<artifactId>nifi-property-protection-api</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>

View File

@ -50,5 +50,9 @@
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-factory</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,813 +0,0 @@
/*
* 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.registry.web.api;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.properties.SensitivePropertyProviderFactory;
import org.apache.nifi.properties.StandardSensitivePropertyProviderFactory;
import org.apache.nifi.registry.SecureLdapTestApiApplication;
import org.apache.nifi.registry.authorization.AccessPolicy;
import org.apache.nifi.registry.authorization.AccessPolicySummary;
import org.apache.nifi.registry.authorization.CurrentUser;
import org.apache.nifi.registry.authorization.Permissions;
import org.apache.nifi.registry.authorization.Tenant;
import org.apache.nifi.registry.bucket.Bucket;
import org.apache.nifi.registry.client.AccessClient;
import org.apache.nifi.registry.client.NiFiRegistryClient;
import org.apache.nifi.registry.client.NiFiRegistryClientConfig;
import org.apache.nifi.registry.client.NiFiRegistryException;
import org.apache.nifi.registry.client.RequestConfig;
import org.apache.nifi.registry.client.UserClient;
import org.apache.nifi.registry.client.impl.JerseyNiFiRegistryClient;
import org.apache.nifi.registry.client.impl.request.BearerTokenRequestConfig;
import org.apache.nifi.registry.extension.ExtensionManager;
import org.apache.nifi.registry.properties.NiFiRegistryProperties;
import org.apache.nifi.registry.revision.entity.RevisionInfo;
import org.apache.nifi.registry.security.authorization.Authorizer;
import org.apache.nifi.registry.security.authorization.AuthorizerFactory;
import org.apache.nifi.registry.security.crypto.BootstrapFileCryptoKeyProvider;
import org.apache.nifi.registry.security.crypto.CryptoKeyProvider;
import org.apache.nifi.registry.security.identity.IdentityMapper;
import org.apache.nifi.registry.service.RegistryService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.skyscreamer.jsonassert.JSONAssert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* Deploy the Web API Application using an embedded Jetty Server for local integration testing, with the follow characteristics:
*
* - A NiFiRegistryProperties has to be explicitly provided to the ApplicationContext using a profile unique to this test suite.
* - A NiFiRegistryClientConfig has been configured to create a client capable of completing one-way TLS
* - The database is embed H2 using volatile (in-memory) persistence
* - Custom SQL is clearing the DB before each test method by default, unless method overrides this behavior
*/
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = SecureLdapTestApiApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.profiles.include=ITSecureLdap")
@Import(SecureITClientConfiguration.class)
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:db/clearDB.sql")
public class SecureLdapIT extends IntegrationTestBase {
private static Logger LOGGER = LoggerFactory.getLogger(SecureLdapIT.class);
private static final String tokenLoginPath = "access/token/login";
private static final String tokenIdentityProviderPath = "access/token/identity-provider";
// A JWT signed by a key of 'secret'
private static final String SIGNED_BY_WRONG_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" +
".eyJzdWIiOiJuaWZpYWRtaW4iLCJpc3MiOiJMZGFwSWRlbnRpdHlQcm92aWRlciIsImF1ZCI6IkxkYXB" +
"JZGVudGl0eVByb3ZpZGVyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoibmlmaWFkbWluIiwia2lkIjoiNDd" +
"lMjA1NzctY2I3Yi00M2MzLWFhOGYtZjI0ZDcyODQ3MDEwIiwiaWF0IjoxNTgxNTI5NTA1LCJleHAiOjE" +
"1ODE1NzI3MDV9.vvMpwLJt1w_6Id_tlS1knxTkJ2gv7_j5ySG6PmNjF0s";
@TestConfiguration
@Profile("ITSecureLdap")
public static class LdapTestConfiguration {
static AuthorizerFactory authorizerFactory;
@Primary
@Bean
@DependsOn({"directoryServer"}) // Can't load LdapUserGroupProvider until the embedded LDAP server, which creates the "directoryServer" bean, is running
public static Authorizer getAuthorizer(
@Autowired NiFiRegistryProperties properties,
ExtensionManager extensionManager,
RegistryService registryService,
DataSource dataSource,
IdentityMapper identityMapper) throws Exception {
if (authorizerFactory == null) {
authorizerFactory = new AuthorizerFactory(
properties,
extensionManager,
sensitivePropertyProviderFactory(),
registryService,
dataSource,
identityMapper);
}
return authorizerFactory.getAuthorizer();
}
@Primary
@Bean
public static SensitivePropertyProviderFactory sensitivePropertyProviderFactory() throws Exception {
return StandardSensitivePropertyProviderFactory.withKey(getNiFiRegistryMasterKeyProvider().getKey());
}
private static CryptoKeyProvider getNiFiRegistryMasterKeyProvider() {
return new BootstrapFileCryptoKeyProvider("src/test/resources/conf/secure-ldap/bootstrap.conf");
}
}
private String adminAuthToken;
private List<AccessPolicy> beforeTestAccessPoliciesSnapshot;
@Before
public void setup() {
final String basicAuthCredentials = encodeCredentialsForBasicAuth("nifiadmin", "password");
final String token = client
.target(createURL(tokenIdentityProviderPath))
.request()
.header("Authorization", "Basic " + basicAuthCredentials)
.post(null, String.class);
adminAuthToken = token;
beforeTestAccessPoliciesSnapshot = createAccessPoliciesSnapshot();
}
@After
public void cleanup() {
restoreAccessPoliciesSnapshot(beforeTestAccessPoliciesSnapshot);
}
@Test
public void testTokenGenerationAndAccessStatus() throws Exception {
// Note: this test intentionally does not use the token generated
// for nifiadmin by the @Before method
// Given: the client and server have been configured correctly for LDAP authentication
String expectedJwtPayloadJson = "{" +
"\"sub\":\"nobel\"," +
"\"preferred_username\":\"nobel\"," +
"\"iss\":\"LdapIdentityProvider\"" +
"}";
String expectedAccessStatusJson = "{" +
"\"identity\":\"nobel\"," +
"\"anonymous\":false" +
"}";
// When: the /access/token/login endpoint is queried
final String basicAuthCredentials = encodeCredentialsForBasicAuth("nobel", "password");
final Response tokenResponse = client
.target(createURL(tokenIdentityProviderPath))
.request()
.header("Authorization", "Basic " + basicAuthCredentials)
.post(null, Response.class);
// Then: the server returns 200 OK with an access token
assertEquals(201, tokenResponse.getStatus());
String token = tokenResponse.readEntity(String.class);
assertTrue(StringUtils.isNotEmpty(token));
String[] jwtParts = token.split("\\.");
assertEquals(3, jwtParts.length);
String jwtPayload = new String(Base64.getDecoder().decode(jwtParts[1]), "UTF-8");
JSONAssert.assertEquals(expectedJwtPayloadJson, jwtPayload, false);
// When: the token is returned in the Authorization header
final Response accessResponse = client
.target(createURL("access"))
.request()
.header("Authorization", "Bearer " + token)
.get(Response.class);
// Then: the server acknowledges the client has access
assertEquals(200, accessResponse.getStatus());
String accessStatus = accessResponse.readEntity(String.class);
JSONAssert.assertEquals(expectedAccessStatusJson, accessStatus, false);
}
@Test
public void testTokenGenerationWithIdentityProvider() throws Exception {
// Given: the client and server have been configured correctly for LDAP authentication
String expectedJwtPayloadJson = "{" +
"\"sub\":\"nobel\"," +
"\"preferred_username\":\"nobel\"," +
"\"iss\":\"LdapIdentityProvider\"," +
"\"aud\":\"LdapIdentityProvider\"" +
"}";
String expectedAccessStatusJson = "{" +
"\"identity\":\"nobel\"," +
"\"anonymous\":false" +
"}";
// When: the /access/token/identity-provider endpoint is queried
final String basicAuthCredentials = encodeCredentialsForBasicAuth("nobel", "password");
final Response tokenResponse = client
.target(createURL(tokenIdentityProviderPath))
.request()
.header("Authorization", "Basic " + basicAuthCredentials)
.post(null, Response.class);
// Then: the server returns 200 OK with an access token
assertEquals(201, tokenResponse.getStatus());
String token = tokenResponse.readEntity(String.class);
assertTrue(StringUtils.isNotEmpty(token));
String[] jwtParts = token.split("\\.");
assertEquals(3, jwtParts.length);
String jwtPayload = new String(Base64.getDecoder().decode(jwtParts[1]), "UTF-8");
JSONAssert.assertEquals(expectedJwtPayloadJson, jwtPayload, false);
// When: the token is returned in the Authorization header
final Response accessResponse = client
.target(createURL("access"))
.request()
.header("Authorization", "Bearer " + token)
.get(Response.class);
// Then: the server acknowledges the client has access
assertEquals(200, accessResponse.getStatus());
String accessStatus = accessResponse.readEntity(String.class);
JSONAssert.assertEquals(expectedAccessStatusJson, accessStatus, false);
}
@Test
public void testGetCurrentUserFailsForAnonymous() throws Exception {
// Given: the client is connected to an secured NiFi Registry
final String expectedJson = "{" +
"\"anonymous\":true," +
"\"identity\":\"anonymous\"," +
"\"loginSupported\":true," +
"\"resourcePermissions\":{" +
"\"anyTopLevelResource\":{\"canDelete\":false,\"canRead\":false,\"canWrite\":false}," +
"\"buckets\":{\"canDelete\":false,\"canRead\":false,\"canWrite\":false}," +
"\"policies\":{\"canDelete\":false,\"canRead\":false,\"canWrite\":false}," +
"\"proxy\":{\"canDelete\":false,\"canRead\":false,\"canWrite\":false}," +
"\"tenants\":{\"canDelete\":false,\"canRead\":false,\"canWrite\":false}}" +
"}";
// When: the /access endpoint is queried with no credentials
final Response response = client
.target(createURL("/access"))
.request()
.get(Response.class);
// Then: the server returns a 200 OK with the expected current user
assertEquals(200, response.getStatus());
final String actualJson = response.readEntity(String.class);
JSONAssert.assertEquals(expectedJson, actualJson, false);
}
@Test
public void testGetCurrentUser() throws Exception {
// Given: the client is connected to an unsecured NiFi Registry
String expectedJson = "{" +
"\"identity\":\"nifiadmin\"," +
"\"anonymous\":false," +
"\"resourcePermissions\":{" +
"\"anyTopLevelResource\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"buckets\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"tenants\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"policies\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"proxy\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}}" +
"}";
// When: the /access endpoint is queried using a JWT for the nifiadmin LDAP user
final Response response = client
.target(createURL("/access"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Response.class);
// Then: the server returns a 200 OK with the expected current user
assertEquals(200, response.getStatus());
String actualJson = response.readEntity(String.class);
JSONAssert.assertEquals(expectedJson, actualJson, false);
}
@Test
public void testLogout() {
// Given: the client is connected to an unsecured NiFi Registry
// and the /access endpoint is queried using a JWT for the nifiadmin LDAP user
final Response response = client
.target(createURL("/access"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Response.class);
// and the server returns a 200 OK with the expected current user
assertEquals(200, response.getStatus());
// When: the /access/logout endpoint with the JWT for the nifiadmin logs out the user
final Response logout_response = client
.target(createURL("/access/logout"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.delete(Response.class);
assertEquals(200, logout_response.getStatus());
// Then: the /access endpoint is queried using the logged out JWT
LOGGER.info("*** THE FOLLOWING JwtException IS EXPECTED ***");
LOGGER.info("*** We are validating the access token no longer works following logout ***");
final Response retryResponse = client
.target(createURL("/access"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Response.class);
// and the server returns a 401 Unauthorized as the user is now logged out
assertEquals(401, retryResponse.getStatus());
String retryJson = retryResponse.readEntity(String.class);
assertEquals("Unable to validate the access token. Contact the system administrator.\n", retryJson);
// Reset: We successfully logged out our user. Run setup to fix up the user, so the @After code can run to re-establish authorizations.
setup();
}
@Test
public void testLogoutWithJWTSignedByWrongKey() throws Exception {
// Given: use the /access/logout endpoint with the JWT for the nifiadmin LDAP user to log out
LOGGER.info("*** THE FOLLOWING JwtException IS EXPECTED ***");
final Response logoutResponse = client
.target(createURL("/access"))
.request()
.header("Authorization", "Bearer " + SIGNED_BY_WRONG_KEY)
.delete(Response.class);
assertEquals(401, logoutResponse.getStatus());
String responseMessage = logoutResponse.readEntity(String.class);
assertEquals("Unable to validate the access token. Contact the system administrator.\n", responseMessage);
}
@Test
public void testUsers() throws Exception {
// Given: the client and server have been configured correctly for LDAP authentication
String expectedJson = "[" +
"{\"identity\":\"nifiadmin\",\"userGroups\":[],\"configurable\":false," +
"\"resourcePermissions\":{" +
"\"anyTopLevelResource\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"buckets\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"tenants\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"policies\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}," +
"\"proxy\":{\"canRead\":true,\"canWrite\":true,\"canDelete\":true}}}," +
"{\"identity\":\"euler\",\"userGroups\":[{\"identity\":\"mathematicians\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"euclid\",\"userGroups\":[{\"identity\":\"mathematicians\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"boyle\",\"userGroups\":[{\"identity\":\"chemists\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"newton\",\"userGroups\":[{\"identity\":\"scientists\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"riemann\",\"userGroups\":[{\"identity\":\"mathematicians\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"gauss\",\"userGroups\":[{\"identity\":\"mathematicians\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"galileo\",\"userGroups\":[{\"identity\":\"scientists\"},{\"identity\":\"italians\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"nobel\",\"userGroups\":[{\"identity\":\"chemists\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"pasteur\",\"userGroups\":[{\"identity\":\"chemists\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"tesla\",\"userGroups\":[{\"identity\":\"scientists\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"nogroup\",\"userGroups\":[],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"einstein\",\"userGroups\":[{\"identity\":\"scientists\"}],\"accessPolicies\":[],\"configurable\":false}," +
"{\"identity\":\"curie\",\"userGroups\":[{\"identity\":\"chemists\"}],\"accessPolicies\":[],\"configurable\":false}]";
// When: the /tenants/users endpoint is queried
final String usersJson = client
.target(createURL("tenants/users"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(String.class);
// Then: the server returns a list of all users (see test-ldap-data.ldif)
JSONAssert.assertEquals(expectedJson, usersJson, false);
}
@Test
public void testUserGroups() throws Exception {
// Given: the client and server have been configured correctly for LDAP authentication
String expectedJson = "[" +
"{" +
"\"identity\":\"chemists\"," +
"\"users\":[{\"identity\":\"pasteur\"},{\"identity\":\"boyle\"},{\"identity\":\"curie\"},{\"identity\":\"nobel\"}]," +
"\"accessPolicies\":[]," +
"\"configurable\":false" +
"}," +
"{" +
"\"identity\":\"mathematicians\"," +
"\"users\":[{\"identity\":\"gauss\"},{\"identity\":\"euclid\"},{\"identity\":\"riemann\"},{\"identity\":\"euler\"}]," +
"\"accessPolicies\":[]," +
"\"configurable\":false" +
"}," +
"{" +
"\"identity\":\"scientists\"," +
"\"users\":[{\"identity\":\"einstein\"},{\"identity\":\"tesla\"},{\"identity\":\"newton\"},{\"identity\":\"galileo\"}]," +
"\"accessPolicies\":[]," +
"\"configurable\":false" +
"}," +
"{" +
"\"identity\":\"italians\"," +
"\"users\":[{\"identity\":\"galileo\"}]," +
"\"accessPolicies\":[]," +
"\"configurable\":false" +
"}]";
// When: the /tenants/users endpoint is queried
final String groupsJson = client
.target(createURL("tenants/user-groups"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(String.class);
// Then: the server returns a list of all users (see test-ldap-data.ldif)
JSONAssert.assertEquals(expectedJson, groupsJson, false);
}
@Test
public void testCreateTenantFails() throws Exception {
Long initialVersion = new Long(0);
String clientId = UUID.randomUUID().toString();
RevisionInfo initialRevisionInfo = new RevisionInfo(clientId, initialVersion);
// Given: the server has been configured with the LdapUserGroupProvider, which is non-configurable,
// and: the client wants to create a tenant
Tenant tenant = new Tenant();
tenant.setIdentity("new_tenant");
tenant.setRevision(initialRevisionInfo);
// When: the POST /tenants/users endpoint is accessed
final Response createUserResponse = client
.target(createURL("tenants/users"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.post(Entity.entity(tenant, MediaType.APPLICATION_JSON_TYPE), Response.class);
// Then: an error is returned
assertEquals(409, createUserResponse.getStatus());
// When: the POST /tenants/users endpoint is accessed
final Response createUserGroupResponse = client
.target(createURL("tenants/user-groups"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.post(Entity.entity(tenant, MediaType.APPLICATION_JSON_TYPE), Response.class);
// Then: an error is returned because the UserGroupProvider is non-configurable
assertEquals(409, createUserGroupResponse.getStatus());
}
@Test
public void testAccessPolicyCreation() throws Exception {
Long initialVersion = new Long(0);
String clientId = UUID.randomUUID().toString();
RevisionInfo initialRevisionInfo = new RevisionInfo(clientId, initialVersion);
// Given: the server has been configured with an initial admin "nifiadmin" and a user with no accessPolicies "nobel"
String nobelId = getTenantIdentifierByIdentity("nobel");
String chemistsId = getTenantIdentifierByIdentity("chemists"); // a group containing user "nobel"
final String basicAuthCredentials = encodeCredentialsForBasicAuth("nobel", "password");
final String nobelAuthToken = client
.target(createURL(tokenIdentityProviderPath))
.request()
.header("Authorization", "Basic " + basicAuthCredentials)
.post(null, String.class);
// When: user nobel re-checks top-level permissions
final CurrentUser currentUser = client
.target(createURL("/access"))
.request()
.header("Authorization", "Bearer " + nobelAuthToken)
.get(CurrentUser.class);
// Then: 200 OK is returned indicating user has access to no top-level resources
assertEquals(new Permissions(), currentUser.getResourcePermissions().getBuckets());
assertEquals(new Permissions(), currentUser.getResourcePermissions().getTenants());
assertEquals(new Permissions(), currentUser.getResourcePermissions().getPolicies());
assertEquals(new Permissions(), currentUser.getResourcePermissions().getProxy());
// When: nifiadmin creates a bucket
final Bucket bucket = new Bucket();
bucket.setName("Integration Test Bucket");
bucket.setDescription("A bucket created by an integration test.");
bucket.setRevision(new RevisionInfo(null, 0L));
Response adminCreatesBucketResponse = client
.target(createURL("buckets"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.post(Entity.entity(bucket, MediaType.APPLICATION_JSON), Response.class);
// Then: the server returns a 200 OK
assertEquals(200, adminCreatesBucketResponse.getStatus());
Bucket createdBucket = adminCreatesBucketResponse.readEntity(Bucket.class);
// When: user nobel initial queries /buckets
final Bucket[] buckets1 = client
.target(createURL("buckets"))
.request()
.header("Authorization", "Bearer " + nobelAuthToken)
.get(Bucket[].class);
// Then: an empty list is returned (nobel has no read access yet)
assertNotNull(buckets1);
assertEquals(0, buckets1.length);
// When: nifiadmin grants read access on createdBucket to 'chemists' a group containing nobel
AccessPolicy readPolicy = new AccessPolicy();
readPolicy.setResource("/buckets/" + createdBucket.getIdentifier());
readPolicy.setAction("read");
readPolicy.addUserGroups(Arrays.asList(new Tenant(chemistsId, "chemists")));
readPolicy.setRevision(initialRevisionInfo);
Response adminGrantsReadAccessResponse = client
.target(createURL("policies"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.post(Entity.entity(readPolicy, MediaType.APPLICATION_JSON), Response.class);
// Then: the server returns a 201 Created
assertEquals(201, adminGrantsReadAccessResponse.getStatus());
// When: nifiadmin tries to list all buckets
final Bucket[] adminBuckets = client
.target(createURL("buckets"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Bucket[].class);
// Then: the full list is returned (verifies that per-bucket access policies are additive to base /buckets policy)
assertNotNull(adminBuckets);
assertEquals(1, adminBuckets.length);
assertEquals(createdBucket.getIdentifier(), adminBuckets[0].getIdentifier());
assertEquals(new Permissions().withCanRead(true).withCanWrite(true).withCanDelete(true), adminBuckets[0].getPermissions());
// When: user nobel re-queries /buckets
final Bucket[] buckets2 = client
.target(createURL("buckets"))
.request()
.header("Authorization", "Bearer " + nobelAuthToken)
.get(Bucket[].class);
// Then: the created bucket is now present
assertNotNull(buckets2);
assertEquals(1, buckets2.length);
assertEquals(createdBucket.getIdentifier(), buckets2[0].getIdentifier());
assertEquals(new Permissions().withCanRead(true), buckets2[0].getPermissions());
// When: nifiadmin grants write access on createdBucket to user 'nobel'
AccessPolicy writePolicy = new AccessPolicy();
writePolicy.setResource("/buckets/" + createdBucket.getIdentifier());
writePolicy.setAction("write");
writePolicy.addUsers(Arrays.asList(new Tenant(nobelId, "nobel")));
writePolicy.setRevision(initialRevisionInfo);
Response adminGrantsWriteAccessResponse = client
.target(createURL("policies"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.post(Entity.entity(writePolicy, MediaType.APPLICATION_JSON), Response.class);
// Then: the server returns a 201 Created
assertEquals(201, adminGrantsWriteAccessResponse.getStatus());
// When: user nobel re-queries /buckets
final Bucket[] buckets3 = client
.target(createURL("buckets"))
.request()
.header("Authorization", "Bearer " + nobelAuthToken)
.get(Bucket[].class);
// Then: the authorizedActions are updated
assertNotNull(buckets3);
assertEquals(1, buckets3.length);
assertEquals(createdBucket.getIdentifier(), buckets3[0].getIdentifier());
assertEquals(new Permissions().withCanRead(true).withCanWrite(true), buckets3[0].getPermissions());
}
@Test
public void testAccessClient() throws IOException, NiFiRegistryException {
final String baseUrl = createBaseURL();
LOGGER.info("Using base url = " + baseUrl);
final NiFiRegistryClientConfig clientConfig = createClientConfig(baseUrl);
Assert.assertNotNull(clientConfig);
final NiFiRegistryClient client = new JerseyNiFiRegistryClient.Builder()
.config(clientConfig)
.build();
final String username = "pasteur";
final String password = "password";
// authenticate with the username and password to obtain a token
final AccessClient accessClient = client.getAccessClient();
final String token = accessClient.getToken(username, password);
assertNotNull(token);
// use the token to check the status of the current user
final RequestConfig requestConfig = new BearerTokenRequestConfig(token);
final UserClient userClient = client.getUserClient(requestConfig);
assertEquals(username, userClient.getAccessStatus().getIdentity());
// use the token to logout
accessClient.logout(token);
// check the status of the current user again and should be unauthorized
LOGGER.info("*** THE FOLLOWING JwtException IS EXPECTED ***");
LOGGER.info("*** We are validating the access token no longer works following logout ***");
try {
userClient.getAccessStatus();
Assert.fail("Should have failed with an unauthorized exception");
} catch (Exception e) {
//LOGGER.error(e.getMessage(), e);
}
// try to get a token with an invalid username and password
try {
accessClient.getToken("user-does-not-exist", "bad-password");
Assert.fail("Should have failed with an unauthorized exception");
} catch (Exception e) {
}
}
/** A helper method to lookup identifiers for tenant identities using the REST API
*
* @param tenantIdentity - the identity to lookup
* @return A string containing the identifier of the tenant, or null if the tenant identity is not found.
*/
private String getTenantIdentifierByIdentity(String tenantIdentity) {
final Tenant[] users = client
.target(createURL("tenants/users"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Tenant[].class);
final Tenant[] groups = client
.target(createURL("tenants/user-groups"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Tenant[].class);
final Tenant matchedTenant = Stream.concat(Arrays.stream(users), Arrays.stream(groups))
.filter(tenant -> tenant.getIdentity().equalsIgnoreCase(tenantIdentity))
.findFirst()
.orElse(null);
return matchedTenant != null ? matchedTenant.getIdentifier() : null;
}
/** A helper method to lookup access policies
*
* @return A string containing the identifier of the policy, or null if the policy identity is not found.
*/
private AccessPolicy getPolicyByResourceAction(String action, String resource) {
final AccessPolicySummary[] policies = client
.target(createURL("policies"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(AccessPolicySummary[].class);
final AccessPolicySummary matchedPolicy = Arrays.stream(policies)
.filter(p -> p.getAction().equalsIgnoreCase(action) && p.getResource().equalsIgnoreCase(resource))
.findFirst()
.orElse(null);
if (matchedPolicy == null) {
return null;
}
String policyId = matchedPolicy.getIdentifier();
final AccessPolicy policy = client
.target(createURL("policies/" + policyId))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(AccessPolicy.class);
return policy;
}
private List<AccessPolicy> createAccessPoliciesSnapshot() {
final AccessPolicySummary[] policySummaries = client
.target(createURL("policies"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(AccessPolicySummary[].class);
final List<AccessPolicy> policies = new ArrayList<>(policySummaries.length);
for (AccessPolicySummary s : policySummaries) {
AccessPolicy policy = client
.target(createURL("policies/" + s.getIdentifier()))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(AccessPolicy.class);
policies.add(policy);
}
return policies;
}
private void restoreAccessPoliciesSnapshot(List<AccessPolicy> accessPoliciesSnapshot) {
List<AccessPolicy> currentAccessPolicies = createAccessPoliciesSnapshot();
Set<String> policiesToRestore = accessPoliciesSnapshot.stream()
.map(AccessPolicy::getIdentifier)
.collect(Collectors.toSet());
Set<AccessPolicy> policiesToDelete = currentAccessPolicies.stream()
.filter(p -> !policiesToRestore.contains(p.getIdentifier()))
.collect(Collectors.toSet());
for (AccessPolicy originalPolicy : accessPoliciesSnapshot) {
Response getCurrentPolicy = client
.target(createURL("policies/" + originalPolicy.getIdentifier()))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.get(Response.class);
if (getCurrentPolicy.getStatus() == 200) {
// update policy to match original
client.target(createURL("policies/" + originalPolicy.getIdentifier()))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.put(Entity.entity(originalPolicy, MediaType.APPLICATION_JSON));
} else {
// post the original policy
client.target(createURL("policies"))
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.post(Entity.entity(originalPolicy, MediaType.APPLICATION_JSON));
}
}
for (AccessPolicy policyToDelete : policiesToDelete) {
try {
final RevisionInfo revisionInfo = policyToDelete.getRevision();
final Long version = revisionInfo == null ? 0 : revisionInfo.getVersion();
client.target(createURL("policies/" + policyToDelete.getIdentifier()))
.queryParam("version", version.longValue())
.request()
.header("Authorization", "Bearer " + adminAuthToken)
.delete();
} catch (Exception e) {
LOGGER.error("Error cleaning up policies after test due to: " + e.getMessage(), e);
}
}
}
private static String encodeCredentialsForBasicAuth(String username, String password) {
final String credentials = username + ":" + password;
final String base64credentials = new String(Base64.getEncoder().encode(credentials.getBytes(Charset.forName("UTF-8"))));
return base64credentials;
}
}

View File

@ -126,6 +126,11 @@
<artifactId>nifi-property-protection-factory</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-utils</artifactId>

View File

@ -44,6 +44,11 @@
<artifactId>nifi-property-protection-factory</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-property-protection-loader</artifactId>
<version>1.17.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi.registry</groupId>
<artifactId>nifi-registry-properties</artifactId>

View File

@ -880,7 +880,7 @@ class ConfigEncryptionTool {
passwords.each { password ->
if (isVerbose) {
logger.info("Attempting to encrypt ${password.name()} using protection scheme ${protectionScheme}")
logger.info("Attempting to encrypt ${password.name()} using protection scheme ${protectionScheme.path}")
}
final ProtectedPropertyContext context = getContext(providerFactory, (String) password.@name, groupIdentifier)
String encryptedValue = sensitivePropertyProvider.protect((String) password.text().trim(), context)
@ -928,7 +928,7 @@ class ConfigEncryptionTool {
passwords.each { password ->
if (isVerbose) {
logger.info("Attempting to encrypt ${password.name()} using protection scheme ${protectionScheme}")
logger.info("Attempting to encrypt ${password.name()} using protection scheme ${protectionScheme.path}")
}
final ProtectedPropertyContext context = getContext(providerFactory, (String) password.@name, groupIdentifier)
String encryptedValue = sensitivePropertyProvider.protect((String) password.text().trim(), context)
@ -982,18 +982,18 @@ class ConfigEncryptionTool {
// Iterate over each -- encrypt and add .protected if populated
sensitivePropertyKeys.each { String key ->
if (!plainProperties.getProperty(key)) {
logger.debug("Skipping encryption of ${key} because it is empty")
logger.debug("Skipping encryption of [${key}] because it is empty")
} else {
String protectedValue = spp.protect(plainProperties.getProperty(key), ProtectedPropertyContext.defaultContext(key))
// Add the encrypted value
encryptedProperties.setProperty(key, protectedValue)
logger.info("Protected ${key} with ${protectionScheme} -> \t${protectedValue}")
logger.info("Protected [${key}] using [${protectionScheme.path}] -> \t${protectedValue}")
// Add the protection key ("x.y.z.protected" -> "aes/gcm/{128,256}")
String protectionKey = ApplicationPropertiesProtector.getProtectionKey(key)
encryptedProperties.setProperty(protectionKey, spp.getIdentifierKey())
logger.info("Updated protection key ${protectionKey}")
logger.info("Updated protection key [${protectionKey}]")
keysToSkip << key << protectionKey
}
@ -1330,7 +1330,7 @@ class ConfigEncryptionTool {
boolean niFiPropertiesAreEncrypted() {
if (niFiPropertiesPath) {
try {
def nfp = getNiFiPropertiesLoader(keyHex).readProtectedPropertiesFromDisk(new File(niFiPropertiesPath))
def nfp = getNiFiPropertiesLoader(keyHex).loadProtectedProperties(new File(niFiPropertiesPath))
return nfp.hasProtectedKeys()
} catch (SensitivePropertyProtectionException | IOException e) {
logger.debug("Read Protected Properties failed {}", e.getMessage())

View File

@ -17,8 +17,6 @@
package org.apache.nifi.properties
import groovy.test.GroovyLogTestCase
import groovy.test.GroovyShellTestCase
import groovy.test.GroovyTestCase
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.CommandLineParser
import org.apache.commons.cli.DefaultParser
@ -974,7 +972,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
File originalFile = new File(originalNiFiPropertiesPath)
List<String> originalLines = originalFile.readLines()
ProtectedNiFiProperties protectedProperties = NiFiPropertiesLoader.withKey(KEY_HEX).readProtectedPropertiesFromDisk(new File(originalNiFiPropertiesPath))
ProtectedNiFiProperties protectedProperties = NiFiPropertiesLoader.withKey(KEY_HEX).loadProtectedProperties(new File(originalNiFiPropertiesPath))
int originalProtectedPropertyCount = protectedProperties.getProtectedPropertyKeys().size()
protectedProperties.addSensitivePropertyProvider(DEFAULT_PROVIDER_FACTORY.getProvider(ConfigEncryptionTool.DEFAULT_PROTECTION_SCHEME))
@ -1181,7 +1179,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) != originalValue
@ -1257,7 +1255,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) != originalValue
@ -1345,7 +1343,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) != originalValue
@ -1460,7 +1458,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was re-encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) != originalValue
@ -3276,7 +3274,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) != originalValue
@ -3472,7 +3470,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for everything is the same except the sensitive props key
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(workingNiFiPropertiesFile)
assert updatedProperties.size() == inputProperties.size()
assert updatedProperties.getProperty(NiFiProperties.SENSITIVE_PROPS_KEY) == newFlowPassword
originalSensitiveValues.every { String key, String originalValue ->
@ -3569,7 +3567,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
final List<String> updatedPropertiesLines = workingNiFiPropertiesFile.readLines()
// Check that the output values for everything is the same including the sensitive props key
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(workingNiFiPropertiesFile)
assert updatedProperties.size() == inputProperties.size()
originalSensitiveValues.every { String key, String originalValue ->
assert updatedProperties.getProperty(key) == originalValue
@ -3654,7 +3652,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
final String SENSITIVE_PROTECTION_KEY = ApplicationPropertiesProtector.getProtectionKey(NiFiProperties.SENSITIVE_PROPS_KEY)
ProtectedNiFiProperties encryptedProperties = niFiPropertiesLoader.readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
ProtectedNiFiProperties encryptedProperties = niFiPropertiesLoader.loadProtectedProperties(workingNiFiPropertiesFile)
def originalEncryptedValues = encryptedProperties.getSensitivePropertyKeys().collectEntries { String key -> [(key): encryptedProperties.getProperty(key)] }
logger.info("Original encrypted values: ${originalEncryptedValues}")
String originalSensitiveKeyProtectionScheme = encryptedProperties.getProperty(SENSITIVE_PROTECTION_KEY)
@ -3675,7 +3673,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
.getProvider(ConfigEncryptionTool.DEFAULT_PROTECTION_SCHEME)
// Check that the output values for everything is the same except the sensitive props key
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(workingNiFiPropertiesFile)
assert updatedProperties.size() == inputProperties.size()
String newSensitivePropertyKey = updatedProperties.getProperty(NiFiProperties.SENSITIVE_PROPS_KEY)
@ -3787,7 +3785,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
final String SENSITIVE_PROTECTION_KEY = ApplicationPropertiesProtector.getProtectionKey(NiFiProperties.SENSITIVE_PROPS_KEY)
ProtectedNiFiProperties encryptedProperties = niFiPropertiesLoader.readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
ProtectedNiFiProperties encryptedProperties = niFiPropertiesLoader.loadProtectedProperties(workingNiFiPropertiesFile)
def originalEncryptedValues = encryptedProperties.getSensitivePropertyKeys().collectEntries { String key -> [(key): encryptedProperties.getProperty(key)] }
logger.info("Original encrypted values: ${originalEncryptedValues}")
String originalSensitiveKeyProtectionScheme = encryptedProperties.getProperty(SENSITIVE_PROTECTION_KEY)
@ -3808,7 +3806,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
.getProvider(ConfigEncryptionTool.DEFAULT_PROTECTION_SCHEME)
// Check that the output values for everything is the same except the sensitive props key
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(workingNiFiPropertiesFile)
assert updatedProperties.size() == inputProperties.size()
String newSensitivePropertyKey = updatedProperties.getProperty(NiFiProperties.SENSITIVE_PROPS_KEY)
@ -3922,7 +3920,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("Original sensitive values: ${originalSensitiveValues}")
final String SENSITIVE_PROTECTION_KEY = ApplicationPropertiesProtector.getProtectionKey(NiFiProperties.SENSITIVE_PROPS_KEY)
ProtectedNiFiProperties encryptedProperties = niFiPropertiesLoader.readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
ProtectedNiFiProperties encryptedProperties = niFiPropertiesLoader.loadProtectedProperties(workingNiFiPropertiesFile)
def originalEncryptedValues = encryptedProperties.getSensitivePropertyKeys().collectEntries { String key -> [(key): encryptedProperties.getProperty(key)] }
logger.info("Original encrypted values: ${originalEncryptedValues}")
String originalSensitiveKeyProtectionScheme = encryptedProperties.getProperty(SENSITIVE_PROTECTION_KEY)
@ -3960,7 +3958,7 @@ class ConfigEncryptionToolTest extends GroovyLogTestCase {
logger.info("Updated key line: ${updatedSensitiveKeyLine}")
// Check that the output values for everything are the same except the sensitive props key
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(workingNiFiPropertiesFile)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().loadProtectedProperties(workingNiFiPropertiesFile)
assert updatedProperties.size() == inputProperties.size()
String newSensitivePropertyKey = updatedProperties.getProperty(NiFiProperties.SENSITIVE_PROPS_KEY)

View File

@ -193,11 +193,9 @@ class EncryptConfigMainTest extends GroovyTestCase {
/*** NiFi Properties Assertions ***/
final List<String> updatedPropertiesLines = outputPropertiesFile.readLines()
logger.info("Updated nifi.properties:")
logger.info("\n" * 2 + updatedPropertiesLines.join("\n"))
// Check that the output values for sensitive properties are not the same as the original (i.e. it was encrypted)
NiFiProperties updatedProperties = new NiFiPropertiesLoader().readProtectedPropertiesFromDisk(outputPropertiesFile)
NiFiProperties updatedProperties = NiFiPropertiesLoader.withKey(TestUtil.KEY_HEX).load(outputPropertiesFile)
assert updatedProperties.size() >= inputProperties.size()
// Check that the new NiFiProperties instance matches the output file (values still encrypted)