NIFI-2208 - initial commit Custom Property Expression Language support with Variable Registry, includes bug fix for NIFI-2057
This closes #529 Signed-off-by: jpercivall <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/8412d266 Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/8412d266 Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/8412d266 Branch: refs/heads/master Commit: 8412d2662ae1cab6c52be62272a2971d199719df Parents: b213ed9 Author: Yolanda M. Davis <[email protected]> Authored: Thu Jun 23 13:25:17 2016 -0400 Committer: jpercivall <[email protected]> Committed: Fri Jul 29 17:10:20 2016 -0400 ---------------------------------------------------------------------- nifi-api/pom.xml | 4 +- .../nifi/registry/FileVariableRegistry.java | 67 +++++++ .../apache/nifi/registry/ImmutableMultiMap.java | 145 ++++++++++++++ .../nifi/registry/MultiMapVariableRegistry.java | 70 +++++++ .../registry/PropertiesVariableRegistry.java | 82 ++++++++ .../apache/nifi/registry/VariableRegistry.java | 60 ++++++ .../nifi/registry/VariableRegistryFactory.java | 48 +++++ .../nifi/registry/VariableRegistryProvider.java | 23 +++ .../nifi/registry/VariableRegistryUtils.java | 87 +++++++++ .../nifi/registry/TestVariableRegistry.java | 170 +++++++++++++++++ .../registry/TestVariableRegistryUtils.java | 143 ++++++++++++++ .../TestVariableRegistry/foobar.properties | 16 ++ .../TestVariableRegistry/test.properties | 17 ++ nifi-bootstrap/pom.xml | 5 + .../bootstrap/NotificationServiceManager.java | 17 +- .../NotificationValidationContext.java | 10 +- .../NotificationServiceManagerSpec.groovy | 50 +++++ .../TestCustomNotificationService.java | 85 +++++++++ .../test/resources/notification-services.xml | 24 +++ .../expression/language/EmptyPreparedQuery.java | 35 +--- .../language/InvalidPreparedQuery.java | 33 +--- .../expression/language/PreparedQuery.java | 16 +- .../attribute/expression/language/Query.java | 190 +------------------ .../language/StandardAttributeExpression.java | 9 +- .../StandardExpressionLanguageCompiler.java | 9 +- .../language/StandardPreparedQuery.java | 37 +--- .../language/StandardPropertyValue.java | 23 ++- .../expression/language/QueryGroovyTest.groovy | 17 +- .../expression/language/TestQuery.java | 112 +++++++---- .../language/TestStandardPreparedQuery.java | 7 +- .../org/apache/nifi/util/NiFiProperties.java | 27 +++ .../nifi/web/NiFiWebConfigurationContext.java | 7 +- .../nifi/util/MockConfigurationContext.java | 13 +- .../apache/nifi/util/MockProcessContext.java | 23 ++- .../org/apache/nifi/util/MockPropertyValue.java | 18 +- .../apache/nifi/util/MockReportingContext.java | 7 +- .../apache/nifi/util/MockValidationContext.java | 15 +- .../nifi/util/StandardProcessorTestRunner.java | 15 +- .../java/org/apache/nifi/util/TestRunners.java | 8 +- .../CurrentTestStandardProcessorTestRunner.java | 3 +- .../nifi/util/TestMockProcessContext.java | 3 +- .../ambari/TestAmbariReportingTask.java | 12 +- .../elasticsearch/TestFetchElasticsearch.java | 6 +- .../authorization/AuthorizerFactoryBean.java | 10 +- .../main/resources/nifi-authorizer-context.xml | 1 + .../nifi/authorization/FileAuthorizerTest.java | 37 ++-- .../StandardAuthorizerConfigurationContext.java | 7 +- .../apache/nifi/controller/FlowController.java | 90 +++++---- .../reporting/AbstractReportingTaskNode.java | 13 +- .../reporting/StandardReportingContext.java | 10 +- .../reporting/StandardReportingTaskNode.java | 12 +- .../scheduling/EventDrivenSchedulingAgent.java | 8 +- .../scheduling/QuartzSchedulingAgent.java | 8 +- .../scheduling/StandardProcessScheduler.java | 9 +- .../scheduling/TimerDrivenSchedulingAgent.java | 8 +- .../service/StandardConfigurationContext.java | 9 +- .../service/StandardControllerServiceNode.java | 18 +- .../StandardControllerServiceProvider.java | 12 +- .../manager/StandardStateManagerProvider.java | 27 +-- .../nifi/groups/StandardProcessGroup.java | 12 +- .../nifi/processor/StandardProcessContext.java | 11 +- .../processor/StandardValidationContext.java | 18 +- .../StandardValidationContextFactory.java | 9 +- .../nifi/spring/FlowControllerFactoryBean.java | 16 +- .../src/main/resources/nifi-context.xml | 6 + .../controller/StandardFlowServiceTest.java | 7 +- .../nifi/controller/TestFlowController.java | 8 +- .../scheduling/TestProcessorLifecycle.java | 4 +- .../TestStandardProcessScheduler.java | 29 +-- .../StandardControllerServiceProviderTest.java | 6 +- .../TestStandardControllerServiceProvider.java | 27 +-- .../local/TestWriteAheadLocalStateProvider.java | 8 +- .../zookeeper/TestZooKeeperStateProvider.java | 8 +- .../processor/TestStandardPropertyValue.java | 27 +-- .../src/main/resources/conf/nifi.properties | 6 +- .../StandardNiFiWebConfigurationContext.java | 11 ++ .../nifi/web/controller/ControllerFacade.java | 12 +- .../web/controller/StandardSearchContext.java | 7 +- .../src/main/resources/nifi-web-api-context.xml | 2 + .../authorization/TestRangerNiFiAuthorizer.java | 26 +-- .../processors/script/TestInvokeGroovy.java | 13 +- .../TestSiteToSiteProvenanceReportingTask.java | 3 +- .../standard/TestRouteOnAttribute.java | 8 +- .../nifi/controller/MonitorMemoryTest.java | 3 +- .../cache/server/TestServerAndClient.java | 14 +- .../attributes/UpdateAttributeModelFactory.java | 9 +- .../update/attributes/api/RuleResource.java | 20 +- 87 files changed, 1769 insertions(+), 608 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-api/pom.xml b/nifi-api/pom.xml index 103eedd..34d8069 100644 --- a/nifi-api/pom.xml +++ b/nifi-api/pom.xml @@ -21,5 +21,5 @@ <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>nifi-api</artifactId> - <packaging>jar</packaging> -</project> + <packaging>jar</packaging> + </project> http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/FileVariableRegistry.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/FileVariableRegistry.java b/nifi-api/src/main/java/org/apache/nifi/registry/FileVariableRegistry.java new file mode 100644 index 0000000..9d77d6c --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/FileVariableRegistry.java @@ -0,0 +1,67 @@ +/* + * 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; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Map; + + +abstract class FileVariableRegistry extends MultiMapVariableRegistry { + + FileVariableRegistry() { + super(); + } + + FileVariableRegistry(File... files) throws IOException{ + super(); + addVariables(files); + } + + FileVariableRegistry(Path... paths) throws IOException{ + super(); + addVariables(paths); + } + + private void addVariables(File ...files) throws IOException{ + if(files != null) { + for (final File file : files) { + Map<String,String> map = convertFile(file); + if(map != null) { + registry.addMap(convertFile(file)); + } + } + + } + } + + private void addVariables(Path ...paths) throws IOException{ + if(paths != null) { + for (final Path path : paths) { + Map<String,String> map = convertFile(path.toFile()); + if(map != null) { + registry.addMap(map); + } + } + } + } + + protected abstract Map<String,String> convertFile(File file) throws IOException; + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/ImmutableMultiMap.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/ImmutableMultiMap.java b/nifi-api/src/main/java/org/apache/nifi/registry/ImmutableMultiMap.java new file mode 100644 index 0000000..2fba560 --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/ImmutableMultiMap.java @@ -0,0 +1,145 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ImmutableMultiMap<V> implements Map<String,V> { + + private final List<Map<String,V>> maps; + + ImmutableMultiMap() { + this.maps = new ArrayList<>(); + } + + @Override + public int size() { + return keySet().size(); + } + + @Override + public boolean isEmpty() { + for (final Map<String,V> map : maps) { + if (!map.isEmpty()) { + return false; + } + } + return true; + } + + @Override + public boolean containsKey(final Object key) { + if (key == null) { + return false; + } + + for (final Map<String,V> map : maps) { + if (map.containsKey(key)) { + return true; + } + } + return false; + } + + @Override + public boolean containsValue(final Object value) { + for (final Map<String,V> map : maps) { + if (map.containsValue(value)) { + return true; + } + } + return false; + } + + @Override + @SuppressWarnings("rawtypes") + public V get(final Object key) { + if (key == null) { + throw new IllegalArgumentException("Null Keys are not allowed"); + } + + for (final Map<String,V> map : maps) { + final V val = map.get(key); + if (val != null) { + return val; + } + } + return null; + } + + @Override + public V put(String key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map<? extends String, ? extends V> m) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Set<String> keySet() { + final Set<String> keySet = new HashSet<>(); + for (final Map map : maps) { + keySet.addAll(map.keySet()); + } + return keySet; + } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Collection<V> values() { + final Set<V> values = new HashSet<>(); + for (final Map map : maps) { + values.addAll(map.values()); + } + return values; + } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public Set<java.util.Map.Entry<String, V>> entrySet() { + final Set<java.util.Map.Entry<String, V>> entrySet = new HashSet<>(); + for (final Map map : maps) { + entrySet.addAll(map.entrySet()); + } + return entrySet; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + void addMap(Map<String,V> map){ + this.maps.add(map); + } + + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/MultiMapVariableRegistry.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/MultiMapVariableRegistry.java b/nifi-api/src/main/java/org/apache/nifi/registry/MultiMapVariableRegistry.java new file mode 100644 index 0000000..029bfb5 --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/MultiMapVariableRegistry.java @@ -0,0 +1,70 @@ +/* + * 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; + +import java.util.Map; +import java.util.Set; + +/*** + * This implementation of variable registry uses the ImmutableMultiMap which stores one or more + * registries that can be searched, accessed and appended. NOTE: Duplicate values within + * or between added registries will be stored however on retrieval the first value encountered will be returned. + * */ +public class MultiMapVariableRegistry implements VariableRegistry { + + protected final ImmutableMultiMap<String> registry; + + MultiMapVariableRegistry() { + this.registry = new ImmutableMultiMap<>(); + } + + @SafeVarargs + MultiMapVariableRegistry(Map<String,String>...maps){ + this(); + if(maps != null) { + for (Map<String, String> map : maps) { + addVariables(map); + } + } + } + + public void addVariables(Map<String, String> map) { + this.registry.addMap(map); + } + + @Override + public void addRegistry(VariableRegistry variableRegistry) { + if(variableRegistry != null && !variableRegistry.getVariables().isEmpty()) { + this.registry.addMap(variableRegistry.getVariables()); + } + } + + @Override + public Map<String, String> getVariables() { + return registry; + } + + @Override + public String getVariableValue(String variable) { + return registry.get(variable); + } + + @Override + public Set<String> getVariableNames() { + return this.registry.keySet(); + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/PropertiesVariableRegistry.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/PropertiesVariableRegistry.java b/nifi-api/src/main/java/org/apache/nifi/registry/PropertiesVariableRegistry.java new file mode 100644 index 0000000..8798930 --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/PropertiesVariableRegistry.java @@ -0,0 +1,82 @@ +/* + * 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; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class PropertiesVariableRegistry extends FileVariableRegistry { + + private static final Logger LOG = LoggerFactory.getLogger(PropertiesVariableRegistry.class); + + PropertiesVariableRegistry(File... files) throws IOException{ + super(files); + } + + PropertiesVariableRegistry(Path... paths) throws IOException { + super(paths); + } + + PropertiesVariableRegistry(Properties...properties){ + super(); + addVariables(properties); + } + + private void addVariables(Properties... properties){ + if(properties != null) { + for (Properties props : properties) { + addVariables(convertToMap(props)); + } + } + } + + @Override + protected Map<String,String> convertFile(File file) throws IOException{ + + if(file.exists()) { + try (final InputStream inStream = new BufferedInputStream(new FileInputStream(file))) { + Properties properties = new Properties(); + properties.load(inStream); + return convertToMap(properties); + } + }else{ + LOG.warn("Could not add file " + file.getName() + ". file did not exist."); + return null; + } + + } + + private Map<String,String> convertToMap(Properties properties){ + HashMap<String,String> propertiesMap = new HashMap<>(properties.keySet().size()); + for(Object key: properties.keySet()){ + propertiesMap.put((String)key,(String) properties.get(key)); + } + return propertiesMap; + } + + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistry.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistry.java b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistry.java new file mode 100644 index 0000000..48eacfd --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistry.java @@ -0,0 +1,60 @@ +/* + * 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; + + +import java.util.Map; +import java.util.Set; + +/** + * Access key/value pairs throughout the application. + */ +public interface VariableRegistry { + + /** + * Returns a map of key/value pairs stored in the registry + * @return variables + **/ + Map<String, String> getVariables(); + + /** + * Return a value for a given variable + * @param variable variable + * @return value + **/ + String getVariableValue(String variable); + + /** + * Concatenate a variable registry + * @param variableRegistry variableRegistry + * */ + void addRegistry(VariableRegistry variableRegistry); + + /** + * Returns a set variable names in the registry + * @return variableNames + **/ + Set<String> getVariableNames(); + + /** + * Concatenate variable key value pair to registry + * @param variables variable Map + * */ + void addVariables(Map<String,String> variables); + + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryFactory.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryFactory.java b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryFactory.java new file mode 100644 index 0000000..1852ad4 --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryFactory.java @@ -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.registry; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Map; +import java.util.Properties; + +public class VariableRegistryFactory { + + public static VariableRegistry getPropertiesInstance(final Properties...properties){ + return new PropertiesVariableRegistry(properties); + } + + public static VariableRegistry getPropertiesInstance(final Path... paths) throws IOException{ + return new PropertiesVariableRegistry(paths); + } + + public static VariableRegistry getPropertiesInstance(final File ...files) throws IOException{ + return new PropertiesVariableRegistry(files); + } + + @SafeVarargs + public static VariableRegistry getInstance(final Map<String,String> ...maps){ + return new MultiMapVariableRegistry(maps); + } + + public static VariableRegistry getInstance(){ + return new MultiMapVariableRegistry(); + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryProvider.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryProvider.java b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryProvider.java new file mode 100644 index 0000000..af7ab38 --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryProvider.java @@ -0,0 +1,23 @@ +/* + * 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; + +public interface VariableRegistryProvider { + + VariableRegistry getVariableRegistry(); + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryUtils.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryUtils.java b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryUtils.java new file mode 100644 index 0000000..6e280d6 --- /dev/null +++ b/nifi-api/src/main/java/org/apache/nifi/registry/VariableRegistryUtils.java @@ -0,0 +1,87 @@ +/* + * 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; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +import org.apache.nifi.flowfile.FlowFile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VariableRegistryUtils { + + private final static Logger LOG = LoggerFactory.getLogger(VariableRegistryUtils.class); + + public static VariableRegistry createSystemVariableRegistry(){ + VariableRegistry variableRegistry = VariableRegistryFactory.getInstance(); + VariableRegistry propRegistry = VariableRegistryFactory.getPropertiesInstance(System.getProperties()); + VariableRegistry envRegistry = VariableRegistryFactory.getInstance(System.getenv()); + variableRegistry.addRegistry(propRegistry); + variableRegistry.addRegistry(envRegistry); + return variableRegistry; + } + + public static VariableRegistry createCustomVariableRegistry(Path[] properties){ + + VariableRegistry customRegistry = null; + try { + customRegistry = VariableRegistryFactory.getPropertiesInstance(properties); + customRegistry.addRegistry(createSystemVariableRegistry()); + } catch (IOException ioe){ + LOG.error("Exception thrown while attempting to add properties to registry",ioe); + } + return customRegistry; + } + + public static VariableRegistry createFlowVariableRegistry(VariableRegistry variableRegistry, final FlowFile flowFile, final Map<String, String> additionalAttributes){ + final Map<String, String> flowFileAttributes = flowFile == null ? null : flowFile.getAttributes(); + final Map<String, String> additionalMap = additionalAttributes == null ? null : additionalAttributes; + + Map<String, String> flowFileProps = null; + if (flowFile != null) { + flowFileProps = new HashMap<>(); + flowFileProps.put("flowFileId", String.valueOf(flowFile.getId())); + flowFileProps.put("fileSize", String.valueOf(flowFile.getSize())); + flowFileProps.put("entryDate", String.valueOf(flowFile.getEntryDate())); + flowFileProps.put("lineageStartDate", String.valueOf(flowFile.getLineageStartDate())); + flowFileProps.put("lastQueueDate",String.valueOf(flowFile.getLastQueueDate())); + flowFileProps.put("queueDateIndex",String.valueOf(flowFile.getQueueDateIndex())); + } + + VariableRegistry newRegistry = VariableRegistryFactory.getInstance(); + + if(flowFileAttributes != null) { + newRegistry.addVariables(flowFileAttributes); + } + if(additionalMap != null) { + newRegistry.addVariables(additionalMap); + } + if(flowFileProps != null) { + newRegistry.addVariables(flowFileProps); + } + + if(variableRegistry != null) { + newRegistry.addRegistry(variableRegistry); + } + + return newRegistry; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistry.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistry.java b/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistry.java new file mode 100644 index 0000000..93099b2 --- /dev/null +++ b/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistry.java @@ -0,0 +1,170 @@ +/* + * 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; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class TestVariableRegistry { + + @Test + public void testReadMap(){ + Map<String,String> variables1 = new HashMap<>(); + variables1.put("fake.property.1","fake test value"); + + Map<String,String> variables2 = new HashMap<>(); + variables1.put("fake.property.2","fake test value"); + + VariableRegistry registry = VariableRegistryFactory.getInstance(variables1,variables2); + + Map<String,String> variables = registry.getVariables(); + assertTrue(variables.size() == 2); + assertTrue(variables.get("fake.property.1").equals("fake test value")); + assertTrue(registry.getVariableValue("fake.property.2").equals("fake test value")); + } + + @Test + public void testReadProperties(){ + Properties properties = new Properties(); + properties.setProperty("fake.property.1","fake test value"); + VariableRegistry registry = VariableRegistryFactory.getPropertiesInstance(properties); + Map<String,String> variables = registry.getVariables(); + assertTrue(variables.get("fake.property.1").equals("fake test value")); + } + + @Test + public void testReadFiles() throws IOException{ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + VariableRegistry registry = VariableRegistryFactory.getPropertiesInstance(fooPath.toFile(),testPath.toFile()); + Map<String,String> variables = registry.getVariables(); + assertTrue(variables.size() == 3); + assertTrue(variables.get("fake.property.1").equals("test me out 1")); + assertTrue(variables.get("fake.property.3").equals("test me out 3, test me out 4")); + } + + @Test + public void testExcludeInvalidFiles() throws IOException{ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + final Path fakePath = Paths.get("src/test/resources/TestVariableRegistry/fake.properties"); + VariableRegistry registry = VariableRegistryFactory.getPropertiesInstance(fooPath.toFile(),testPath.toFile(),fakePath.toFile()); + Map<String,String> variables = registry.getVariables(); + assertTrue(variables.size() == 3); + assertTrue(variables.get("fake.property.1").equals("test me out 1")); + assertTrue(variables.get("fake.property.3").equals("test me out 3, test me out 4")); + } + + + @Test + public void testReadPaths() throws IOException{ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + VariableRegistry registry = VariableRegistryFactory.getPropertiesInstance(fooPath,testPath); + Map<String,String> variables = registry.getVariables(); + assertTrue(variables.size() == 3); + assertTrue(variables.get("fake.property.1").equals("test me out 1")); + assertTrue(variables.get("fake.property.3").equals("test me out 3, test me out 4")); + } + + @Test + public void testExcludeInvalidPaths() throws IOException{ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + final Path fakePath = Paths.get("src/test/resources/TestVariableRegistry/fake.properties"); + VariableRegistry registry = VariableRegistryFactory.getPropertiesInstance(fooPath,testPath,fakePath); + Map<String,String> variables = registry.getVariables(); + assertTrue(variables.size() == 3); + } + + @Test + public void testAddRegistry() throws IOException{ + + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + VariableRegistry pathRegistry = VariableRegistryFactory.getPropertiesInstance(fooPath); + + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + VariableRegistry fileRegistry = VariableRegistryFactory.getPropertiesInstance(testPath.toFile()); + + Properties properties = new Properties(); + properties.setProperty("fake.property.5","test me out 5"); + VariableRegistry propRegistry = VariableRegistryFactory.getPropertiesInstance(properties); + + propRegistry.addRegistry(pathRegistry); + propRegistry.addRegistry(fileRegistry); + + Map<String,String> variables = propRegistry.getVariables(); + assertTrue(variables.size() == 4); + } + + @Test + public void testAttemptToAddNullRegistry() throws IOException{ + + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + VariableRegistry pathRegistry = VariableRegistryFactory.getPropertiesInstance(fooPath); + VariableRegistry nullRegistry = null; + pathRegistry.addRegistry(nullRegistry); + assertTrue(pathRegistry.getVariables().size() == 1); + } + + @Test + public void testNoOverwriteRegistry()throws IOException{ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + VariableRegistry pathRegistry = VariableRegistryFactory.getPropertiesInstance(fooPath); + + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + VariableRegistry fileRegistry = VariableRegistryFactory.getPropertiesInstance(testPath.toFile()); + + Properties properties = new Properties(); + properties.setProperty("fake.property.3","test me out 5"); + VariableRegistry propRegistry = VariableRegistryFactory.getPropertiesInstance(properties); + + propRegistry.addRegistry(pathRegistry); + propRegistry.addRegistry(fileRegistry); + + Map<String,String> variables = propRegistry.getVariables(); + String testDuplicate = propRegistry.getVariableValue("fake.property.3"); + assertTrue(variables.size() == 3); + assertTrue(testDuplicate.equals("test me out 5")); + } + + @Test + public void testGetVariableNames() throws IOException{ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + VariableRegistry registry = VariableRegistryFactory.getPropertiesInstance(fooPath,testPath); + Set<String> variableNames= registry.getVariableNames(); + assertTrue(variableNames.size() == 3); + assertTrue(variableNames.contains("fake.property.1")); + assertTrue(variableNames.contains("fake.property.2")); + assertTrue(variableNames.contains("fake.property.3")); + assertTrue(!variableNames.contains("fake.property.4")); + } + + + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistryUtils.java ---------------------------------------------------------------------- diff --git a/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistryUtils.java b/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistryUtils.java new file mode 100644 index 0000000..a3c4ae4 --- /dev/null +++ b/nifi-api/src/test/java/org/apache/nifi/registry/TestVariableRegistryUtils.java @@ -0,0 +1,143 @@ +/* + * 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; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import org.apache.nifi.flowfile.FlowFile; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class TestVariableRegistryUtils { + + @Test + public void testCreateSystemVariableRegistry(){ + System.setProperty("fake","test"); + VariableRegistry variableRegistry = VariableRegistryUtils.createSystemVariableRegistry(); + Map<String,String> variables = variableRegistry.getVariables(); + assertTrue(variables.containsKey("PATH")); + assertTrue(variables.get("fake").equals("test")); + } + + @Test + public void testCreateCustomVariableRegistry(){ + final Path fooPath = Paths.get("src/test/resources/TestVariableRegistry/foobar.properties"); + final Path testPath = Paths.get("src/test/resources/TestVariableRegistry/test.properties"); + Path[] paths = {fooPath,testPath}; + System.setProperty("fake","test"); + VariableRegistry variableRegistry = VariableRegistryUtils.createCustomVariableRegistry(paths); + Map<String,String> variables = variableRegistry.getVariables(); + assertTrue(variables.containsKey("PATH")); + assertTrue(variables.containsKey("fake.property.3")); + assertTrue(variables.get("fake").equals("test")); + assertTrue(variables.get("fake.property.3").equals("test me out 3, test me out 4")); + } + + @Test + public void testCreateFlowVariableRegistry(){ + System.setProperty("fake","test"); + FlowFile flowFile = createFlowFile(); + + VariableRegistry variableRegistry = VariableRegistryUtils.createSystemVariableRegistry(); + VariableRegistry populatedRegistry = VariableRegistryUtils.createFlowVariableRegistry(variableRegistry,flowFile,null); + Map<String,String> variables = populatedRegistry.getVariables(); + assertTrue(variables.containsKey("PATH")); + assertTrue(variables.get("fake").equals("test")); + assertTrue(variables.get("flowFileId").equals("1")); + assertTrue(variables.get("fileSize").equals("50")); + assertTrue(variables.get("entryDate").equals("1000")); + assertTrue(variables.get("lineageStartDate").equals("10000")); + assertTrue(variables.get("filename").equals("fakefile.txt")); + } + + @Test + public void testPopulateRegistryWithEmptyFlowFileAndAttributes(){ + System.setProperty("fake","test"); + VariableRegistry variableRegistry = VariableRegistryUtils.createSystemVariableRegistry(); + VariableRegistry populatedRegistry = VariableRegistryUtils.createFlowVariableRegistry(variableRegistry,null,null); + Map<String,String> variables = populatedRegistry.getVariables(); + assertTrue( variables.containsKey("PATH")); + assertTrue( variables.get("fake").equals("test")); + } + + + private FlowFile createFlowFile(){ + return new FlowFile() { + @Override + public long getId() { + return 1; + } + + @Override + public long getEntryDate() { + return 1000; + } + + @Override + public long getLineageStartDate() { + return 10000; + } + + @Override + public Long getLastQueueDate() { + return null; + } + + @Override + public boolean isPenalized() { + return false; + } + + @Override + public String getAttribute(String key) { + return null; + } + + @Override + public long getSize() { + return 50; + } + + @Override + public long getLineageStartIndex() { + return 0; + } + + @Override + public long getQueueDateIndex() { + return 0; + } + + @Override + public Map<String, String> getAttributes() { + Map<String,String> attributes = new HashMap<>(); + attributes.put("filename","fakefile.txt"); + return attributes; + } + + @Override + public int compareTo(FlowFile o) { + return 0; + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/test/resources/TestVariableRegistry/foobar.properties ---------------------------------------------------------------------- diff --git a/nifi-api/src/test/resources/TestVariableRegistry/foobar.properties b/nifi-api/src/test/resources/TestVariableRegistry/foobar.properties new file mode 100644 index 0000000..1094e1b --- /dev/null +++ b/nifi-api/src/test/resources/TestVariableRegistry/foobar.properties @@ -0,0 +1,16 @@ +# 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. + +fake.property.3=test me out 3, test me out 4 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-api/src/test/resources/TestVariableRegistry/test.properties ---------------------------------------------------------------------- diff --git a/nifi-api/src/test/resources/TestVariableRegistry/test.properties b/nifi-api/src/test/resources/TestVariableRegistry/test.properties new file mode 100644 index 0000000..6191449 --- /dev/null +++ b/nifi-api/src/test/resources/TestVariableRegistry/test.properties @@ -0,0 +1,17 @@ +# 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. + +fake.property.1=test me out 1 +fake.property.2=test me out 2 http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-bootstrap/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-bootstrap/pom.xml b/nifi-bootstrap/pom.xml index ce30cd7..5694fd9 100644 --- a/nifi-bootstrap/pom.xml +++ b/nifi-bootstrap/pom.xml @@ -41,5 +41,10 @@ <groupId>org.apache.nifi</groupId> <artifactId>nifi-expression-language</artifactId> </dependency> + <dependency> + <groupId>org.spockframework</groupId> + <artifactId>spock-core</artifactId> + <scope>test</scope> + </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java ---------------------------------------------------------------------- diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java index 21d8e82..233c66d 100644 --- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java +++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java @@ -46,6 +46,8 @@ import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.PropertyValue; import org.apache.nifi.components.ValidationContext; import org.apache.nifi.components.ValidationResult; +import org.apache.nifi.registry.VariableRegistry; +import org.apache.nifi.registry.VariableRegistryUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -62,8 +64,15 @@ public class NotificationServiceManager { private final ScheduledExecutorService notificationExecutor; private int maxAttempts = 5; + private final VariableRegistry variableRegistry; + public NotificationServiceManager() { + this(VariableRegistryUtils.createSystemVariableRegistry()); + } + + NotificationServiceManager(VariableRegistry variableRegistry){ + this.variableRegistry = variableRegistry; notificationExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() { @Override public Thread newThread(final Runnable r) { @@ -141,7 +150,7 @@ public class NotificationServiceManager { } // Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications - final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config)); + final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config), variableRegistry); final Collection<ValidationResult> validationResults = service.validate(validationContext); final List<String> invalidReasons = new ArrayList<>(); @@ -179,7 +188,7 @@ public class NotificationServiceManager { @Override public void run() { // Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications - final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config)); + final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config), variableRegistry); final Collection<ValidationResult> validationResults = service.validate(validationContext); final List<String> invalidReasons = new ArrayList<>(); @@ -247,7 +256,7 @@ public class NotificationServiceManager { configuredValue = fullPropDescriptor.getDefaultValue(); } - return new StandardPropertyValue(configuredValue, null); + return new StandardPropertyValue(configuredValue, null, variableRegistry); } @Override @@ -364,7 +373,7 @@ public class NotificationServiceManager { value = descriptor.getDefaultValue(); } - return new StandardPropertyValue(value, null); + return new StandardPropertyValue(value, null, variableRegistry); } @Override http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java ---------------------------------------------------------------------- diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java index f29c1c9..99d3b23 100644 --- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java +++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java @@ -30,12 +30,14 @@ import org.apache.nifi.components.ValidationContext; import org.apache.nifi.controller.ControllerService; import org.apache.nifi.controller.ControllerServiceLookup; import org.apache.nifi.expression.ExpressionLanguageCompiler; +import org.apache.nifi.registry.VariableRegistry; public class NotificationValidationContext implements ValidationContext { private final NotificationContext context; private final Map<String, Boolean> expressionLanguageSupported; + private final VariableRegistry variableRegistry; - public NotificationValidationContext(final NotificationContext processContext) { + public NotificationValidationContext(final NotificationContext processContext, VariableRegistry variableRegistry) { this.context = processContext; final Map<PropertyDescriptor, String> properties = processContext.getProperties(); @@ -43,17 +45,19 @@ public class NotificationValidationContext implements ValidationContext { for (final PropertyDescriptor descriptor : properties.keySet()) { expressionLanguageSupported.put(descriptor.getName(), descriptor.isExpressionLanguageSupported()); } + this.variableRegistry = variableRegistry; } @Override public PropertyValue newPropertyValue(final String rawValue) { - return new StandardPropertyValue(rawValue, null); + return new StandardPropertyValue(rawValue, null, variableRegistry); } @Override public ExpressionLanguageCompiler newExpressionLanguageCompiler() { - return new StandardExpressionLanguageCompiler(); + + return new StandardExpressionLanguageCompiler(null); } @Override http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/NotificationServiceManagerSpec.groovy ---------------------------------------------------------------------- diff --git a/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/NotificationServiceManagerSpec.groovy b/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/NotificationServiceManagerSpec.groovy new file mode 100644 index 0000000..7bd4c52 --- /dev/null +++ b/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/NotificationServiceManagerSpec.groovy @@ -0,0 +1,50 @@ +/* + * 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.bootstrap + +import org.apache.nifi.bootstrap.notification.NotificationType +import org.apache.nifi.registry.VariableRegistry +import spock.lang.Specification +import java.nio.file.Paths + +class NotificationServiceManagerSpec extends Specification{ + + def setupSpec(){ + } + + def "should acess variable registry to replace EL values"(){ + + given: + def mockRegistry = Mock(VariableRegistry.class) + def notificationServiceManager = new NotificationServiceManager(mockRegistry); + def file = Paths.get("src/test/resources/notification-services.xml").toFile() + notificationServiceManager.loadNotificationServices(file) + //testing with stopped becasue it will block until method is completed + notificationServiceManager.registerNotificationService(NotificationType.NIFI_STOPPED,"custom-notification") + + when: + notificationServiceManager.notify(NotificationType.NIFI_STOPPED,"NiFi Stopped","NiFi Stopped") + + then: + 6 * mockRegistry.getVariables() >> ["test.server":"smtp://fakeserver.com","test.username":"user","test.password":"pass"] + + + } + + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/notification/TestCustomNotificationService.java ---------------------------------------------------------------------- diff --git a/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/notification/TestCustomNotificationService.java b/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/notification/TestCustomNotificationService.java new file mode 100644 index 0000000..3685cb1 --- /dev/null +++ b/nifi-bootstrap/src/test/groovy/org/apache/nifi/bootstrap/notification/TestCustomNotificationService.java @@ -0,0 +1,85 @@ +package org.apache.nifi.bootstrap.notification; + +/* + * 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. + */ + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.processor.util.StandardValidators; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestCustomNotificationService extends AbstractNotificationService { + + private static Logger logger = LoggerFactory.getLogger(TestCustomNotificationService.class); + + public static final PropertyDescriptor CUSTOM_HOSTNAME = new PropertyDescriptor.Builder() + .name("Custom Hostname") + .description("The hostname of the Custom Server that is used to send notifications") + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .expressionLanguageSupported(true) + .required(true) + .build(); + public static final PropertyDescriptor CUSTOM_USERNAME = new PropertyDescriptor.Builder() + .name("Custom Username") + .description("Username for the account") + .expressionLanguageSupported(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .required(false) + .build(); + public static final PropertyDescriptor CUSTOM_PASSWORD = new PropertyDescriptor.Builder() + .name("Custom Password") + .description("Password for the account") + .expressionLanguageSupported(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .required(false) + .sensitive(true) + .build(); + + /** + * Mapping of the mail properties to the NiFi PropertyDescriptors that will be evaluated at runtime + */ + private static final Map<String, PropertyDescriptor> propertyToContext = new HashMap<>(); + + static { + propertyToContext.put("custom.host", CUSTOM_HOSTNAME); + propertyToContext.put("custom.user", CUSTOM_USERNAME); + propertyToContext.put("custom.password", CUSTOM_PASSWORD); + } + + @Override + protected List<PropertyDescriptor> getSupportedPropertyDescriptors() { + final List<PropertyDescriptor> properties = new ArrayList<>(); + properties.add(CUSTOM_HOSTNAME); + properties.add(CUSTOM_USERNAME); + properties.add(CUSTOM_PASSWORD); + return properties; + } + + @Override + public void notify(NotificationContext context, String subject, String message) throws NotificationFailedException { + logger.info(context.getProperty(CUSTOM_HOSTNAME).evaluateAttributeExpressions().getValue()); + logger.info(context.getProperty(CUSTOM_USERNAME).evaluateAttributeExpressions().getValue()); + logger.info(context.getProperty(CUSTOM_PASSWORD).evaluateAttributeExpressions().getValue()); + } + + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-bootstrap/src/test/resources/notification-services.xml ---------------------------------------------------------------------- diff --git a/nifi-bootstrap/src/test/resources/notification-services.xml b/nifi-bootstrap/src/test/resources/notification-services.xml new file mode 100644 index 0000000..5f02a3b --- /dev/null +++ b/nifi-bootstrap/src/test/resources/notification-services.xml @@ -0,0 +1,24 @@ +<?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. +--> +<services> + <service> + <id>custom-notification</id> + <class>org.apache.nifi.bootstrap.notification.TestCustomNotificationService</class> + <property name="Custom Hostname">${test.server}</property> + <property name="Custom Username">${test.username}</property> + <property name="Custom Password">${test.password}</property> + </service> +</services> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/EmptyPreparedQuery.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/EmptyPreparedQuery.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/EmptyPreparedQuery.java index d85c9ef..5dec2fa 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/EmptyPreparedQuery.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/EmptyPreparedQuery.java @@ -16,11 +16,10 @@ */ package org.apache.nifi.attribute.expression.language; -import java.util.Map; import org.apache.nifi.expression.AttributeValueDecorator; -import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.exception.ProcessException; +import org.apache.nifi.registry.VariableRegistry; public class EmptyPreparedQuery implements PreparedQuery { @@ -31,37 +30,7 @@ public class EmptyPreparedQuery implements PreparedQuery { } @Override - public String evaluateExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { - return value; - } - - @Override - public String evaluateExpressions() throws ProcessException { - return value; - } - - @Override - public String evaluateExpressions(final AttributeValueDecorator decorator) throws ProcessException { - return value; - } - - @Override - public String evaluateExpressions(final FlowFile flowFile) throws ProcessException { - return value; - } - - @Override - public String evaluateExpressions(Map<String, String> attributes) throws ProcessException { - return value; - } - - @Override - public String evaluateExpressions(Map<String, String> attributes, AttributeValueDecorator decorator) throws ProcessException { - return value; - } - - @Override - public String evaluateExpressions(FlowFile flowFile, Map<String, String> additionalAttributes, AttributeValueDecorator decorator) throws ProcessException { + public String evaluateExpressions(VariableRegistry variableRegistry, AttributeValueDecorator decorator) throws ProcessException { return value; } } http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java index aa2428d..0ca9a8f 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/InvalidPreparedQuery.java @@ -16,12 +16,11 @@ */ package org.apache.nifi.attribute.expression.language; -import java.util.Map; import org.apache.nifi.attribute.expression.language.exception.AttributeExpressionLanguageException; import org.apache.nifi.expression.AttributeValueDecorator; -import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.exception.ProcessException; +import org.apache.nifi.registry.VariableRegistry; /** * An implementation of PreparedQuery that throws an @@ -40,37 +39,9 @@ public class InvalidPreparedQuery implements PreparedQuery { } @Override - public String evaluateExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { + public String evaluateExpressions(final VariableRegistry variableRegistry, final AttributeValueDecorator decorator) throws ProcessException { throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); } - @Override - public String evaluateExpressions() throws ProcessException { - throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); - } - - @Override - public String evaluateExpressions(final AttributeValueDecorator decorator) throws ProcessException { - throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); - } - - @Override - public String evaluateExpressions(final FlowFile flowFile) throws ProcessException { - throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); - } - @Override - public String evaluateExpressions(final Map<String, String> attributes) throws ProcessException { - throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); - } - - @Override - public String evaluateExpressions(final Map<String, String> attributes, final AttributeValueDecorator decorator) throws ProcessException { - throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); - } - - @Override - public String evaluateExpressions(FlowFile flowFile, Map<String, String> additionalAttributes, AttributeValueDecorator decorator) throws ProcessException { - throw new AttributeExpressionLanguageException("Invalid Expression: " + query + " due to " + explanation); - } } http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/PreparedQuery.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/PreparedQuery.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/PreparedQuery.java index ad9225d..37d8b86 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/PreparedQuery.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/PreparedQuery.java @@ -16,25 +16,13 @@ */ package org.apache.nifi.attribute.expression.language; -import java.util.Map; import org.apache.nifi.expression.AttributeValueDecorator; -import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.exception.ProcessException; +import org.apache.nifi.registry.VariableRegistry; public interface PreparedQuery { - String evaluateExpressions(FlowFile flowFile, AttributeValueDecorator decorator) throws ProcessException; + String evaluateExpressions(VariableRegistry registry, AttributeValueDecorator decorator) throws ProcessException; - String evaluateExpressions() throws ProcessException; - - String evaluateExpressions(AttributeValueDecorator decorator) throws ProcessException; - - String evaluateExpressions(FlowFile flowFile) throws ProcessException; - - String evaluateExpressions(Map<String, String> attributes) throws ProcessException; - - String evaluateExpressions(Map<String, String> attributes, AttributeValueDecorator decorator) throws ProcessException; - - String evaluateExpressions(FlowFile flowFile, Map<String, String> additionalAttributes, AttributeValueDecorator decorator) throws ProcessException; } http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java index 6985bfc..f2d3915 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/Query.java @@ -18,13 +18,9 @@ package org.apache.nifi.attribute.expression.language; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionLexer; @@ -198,6 +194,7 @@ import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpre import static org.apache.nifi.attribute.expression.language.antlr.AttributeExpressionParser.UUID; import org.apache.nifi.attribute.expression.language.evaluation.selection.MappingEvaluator; +import org.apache.nifi.registry.VariableRegistry; /** * Class used for creating and evaluating NiFi Expression Language. Once a Query @@ -367,8 +364,8 @@ public class Query { return -1; } - static String evaluateExpression(final Tree tree, final String queryText, final Map<String, String> expressionMap, final AttributeValueDecorator decorator) throws ProcessException { - final Object evaluated = Query.fromTree(tree, queryText).evaluate(expressionMap).getValue(); + static String evaluateExpression(final Tree tree, final String queryText, final VariableRegistry registry, final AttributeValueDecorator decorator) throws ProcessException { + final Object evaluated = Query.fromTree(tree, queryText).evaluate(registry).getValue(); if (evaluated == null) { return null; } @@ -378,29 +375,12 @@ public class Query { return decorator == null ? escaped : decorator.decorate(escaped); } - static String evaluateExpressions(final String rawValue, Map<String, String> expressionMap) throws ProcessException { - return evaluateExpressions(rawValue, expressionMap, null); + static String evaluateExpressions(final String rawValue, VariableRegistry registry) throws ProcessException { + return evaluateExpressions(rawValue, registry, null); } - static String evaluateExpressions(final String rawValue) throws ProcessException { - return evaluateExpressions(rawValue, createExpressionMap(null), null); - } - - static String evaluateExpressions(final String rawValue, final FlowFile flowFile) throws ProcessException { - return evaluateExpressions(rawValue, createExpressionMap(flowFile), null); - } - - static String evaluateExpressions(final String rawValue, Map<String, String> expressionMap, final AttributeValueDecorator decorator) throws ProcessException { - return Query.prepare(rawValue).evaluateExpressions(expressionMap, decorator); - } - - public static String evaluateExpressions(final String rawValue, final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { - if (rawValue == null) { - return null; - } - - final Map<String, String> expressionMap = createExpressionMap(flowFile); - return evaluateExpressions(rawValue, expressionMap, decorator); + static String evaluateExpressions(final String rawValue, VariableRegistry registry, final AttributeValueDecorator decorator) throws ProcessException { + return Query.prepare(rawValue).evaluateExpressions(registry, decorator); } private static Evaluator<?> getRootSubjectEvaluator(final Evaluator<?> evaluator) { @@ -426,150 +406,6 @@ public class Query { return value.replaceAll("\\$\\$(?=\\$*\\{.*?\\})", "\\$"); } - static Map<String, String> createExpressionMap(final FlowFile flowFile) { - return createExpressionMap(flowFile, null); - } - - static Map<String, String> createExpressionMap(final FlowFile flowFile, final Map<String, String> additionalAttributes) { - final Map<String, String> attributeMap = flowFile == null ? Collections.emptyMap() : flowFile.getAttributes(); - final Map<String, String> additionalOrEmpty = additionalAttributes == null ? Collections.emptyMap() : additionalAttributes; - final Map<String, String> envMap = System.getenv(); - final Map<?, ?> sysProps = System.getProperties(); - - final Map<String, String> flowFileProps = new HashMap<>(); - if (flowFile != null) { - flowFileProps.put("flowFileId", String.valueOf(flowFile.getId())); - flowFileProps.put("fileSize", String.valueOf(flowFile.getSize())); - flowFileProps.put("entryDate", String.valueOf(flowFile.getEntryDate())); - flowFileProps.put("lineageStartDate", String.valueOf(flowFile.getLineageStartDate())); - } - - return wrap(additionalOrEmpty, attributeMap, flowFileProps, envMap, sysProps); - } - - private static Map<String, String> wrap(final Map<String, String> additional, final Map<String, String> attributes, final Map<String, String> flowFileProps, - final Map<String, String> env, final Map<?, ?> sysProps) { - @SuppressWarnings("rawtypes") - final Map[] maps = new Map[] {additional, attributes, flowFileProps, env, sysProps}; - - return new Map<String, String>() { - @Override - public int size() { - int size = 0; - for (final Map<?, ?> map : maps) { - size += map.size(); - } - return size; - } - - @Override - public boolean isEmpty() { - for (final Map<?, ?> map : maps) { - if (!map.isEmpty()) { - return false; - } - } - return true; - } - - @Override - public boolean containsKey(final Object key) { - if (key == null) { - return false; - } - if (!(key instanceof String)) { - return false; - } - - for (final Map<?, ?> map : maps) { - if (map.containsKey(key)) { - return true; - } - } - return false; - } - - @Override - public boolean containsValue(final Object value) { - for (final Map<?, ?> map : maps) { - if (map.containsValue(value)) { - return true; - } - } - return false; - } - - @Override - @SuppressWarnings("rawtypes") - public String get(final Object key) { - if (key == null) { - throw new IllegalArgumentException("Null Keys are not allowed"); - } - if (!(key instanceof String)) { - return null; - } - - for (final Map map : maps) { - final Object val = map.get(key); - if (val != null) { - return String.valueOf(val); - } - } - return null; - } - - @Override - public String put(String key, String value) { - throw new UnsupportedOperationException(); - } - - @Override - public String remove(final Object key) { - throw new UnsupportedOperationException(); - } - - @Override - public void putAll(final Map<? extends String, ? extends String> m) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public Set<String> keySet() { - final Set<String> keySet = new HashSet<>(); - for (final Map map : maps) { - keySet.addAll(map.keySet()); - } - return keySet; - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public Collection<String> values() { - final Set<String> values = new HashSet<>(); - for (final Map map : maps) { - values.addAll(map.values()); - } - return values; - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public Set<java.util.Map.Entry<String, String>> entrySet() { - final Set<java.util.Map.Entry<String, String>> entrySet = new HashSet<>(); - for (final Map map : maps) { - entrySet.addAll(map.entrySet()); - } - return entrySet; - } - - }; - } public static Query fromTree(final Tree tree, final String text) { return new Query(text, tree, buildEvaluator(tree)); @@ -706,20 +542,12 @@ public class Query { return evaluator.getResultType(); } - QueryResult<?> evaluate() { - return evaluate(createExpressionMap(null)); - } - - QueryResult<?> evaluate(final FlowFile flowFile) { - return evaluate(createExpressionMap(flowFile)); - } - - QueryResult<?> evaluate(final Map<String, String> attributes) { + QueryResult<?> evaluate(final VariableRegistry registry) { if (evaluated.getAndSet(true)) { throw new IllegalStateException("A Query cannot be evaluated more than once"); } - return evaluator.evaluate(attributes); + return evaluator.evaluate(registry.getVariables()); } Tree getTree() { http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardAttributeExpression.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardAttributeExpression.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardAttributeExpression.java index 49ef6ef..1e18953 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardAttributeExpression.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardAttributeExpression.java @@ -20,13 +20,17 @@ import org.apache.nifi.expression.AttributeExpression; import org.apache.nifi.expression.AttributeValueDecorator; import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.exception.ProcessException; +import org.apache.nifi.registry.VariableRegistry; +import org.apache.nifi.registry.VariableRegistryUtils; public class StandardAttributeExpression implements AttributeExpression { private final Query query; + private final VariableRegistry variableRegistry; - public StandardAttributeExpression(final Query query) { + public StandardAttributeExpression(final Query query, final VariableRegistry variableRegistry) { this.query = query; + this.variableRegistry = variableRegistry; } @Override @@ -51,7 +55,8 @@ public class StandardAttributeExpression implements AttributeExpression { @Override public String evaluate(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { - final Object evaluationResult = query.evaluate(flowFile).getValue(); + VariableRegistry flowFileRegistry = VariableRegistryUtils.createFlowVariableRegistry(variableRegistry,flowFile,null); + final Object evaluationResult = query.evaluate(flowFileRegistry).getValue(); if (evaluationResult == null) { return ""; } http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardExpressionLanguageCompiler.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardExpressionLanguageCompiler.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardExpressionLanguageCompiler.java index cec73d1..e85853f 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardExpressionLanguageCompiler.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardExpressionLanguageCompiler.java @@ -20,13 +20,20 @@ import org.apache.nifi.attribute.expression.language.exception.AttributeExpressi import org.apache.nifi.expression.AttributeExpression; import org.apache.nifi.expression.ExpressionLanguageCompiler; import org.apache.nifi.expression.AttributeExpression.ResultType; +import org.apache.nifi.registry.VariableRegistry; public class StandardExpressionLanguageCompiler implements ExpressionLanguageCompiler { + private final VariableRegistry variableRegistry; + + public StandardExpressionLanguageCompiler(final VariableRegistry variableRegistry) { + this.variableRegistry = variableRegistry; + } + @Override public AttributeExpression compile(final String expression) throws IllegalArgumentException { try { - return new StandardAttributeExpression(Query.compile(expression)); + return new StandardAttributeExpression(Query.compile(expression),variableRegistry); } catch (final AttributeExpressionLanguageParsingException e) { throw new IllegalArgumentException(e.getMessage()); } http://git-wip-us.apache.org/repos/asf/nifi/blob/8412d266/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardPreparedQuery.java ---------------------------------------------------------------------- diff --git a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardPreparedQuery.java b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardPreparedQuery.java index b81a583..4ee3e02 100644 --- a/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardPreparedQuery.java +++ b/nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/StandardPreparedQuery.java @@ -22,10 +22,10 @@ import java.util.List; import java.util.Map; import org.apache.nifi.expression.AttributeValueDecorator; -import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.exception.ProcessException; import org.antlr.runtime.tree.Tree; +import org.apache.nifi.registry.VariableRegistry; public class StandardPreparedQuery implements PreparedQuery { @@ -37,20 +37,16 @@ public class StandardPreparedQuery implements PreparedQuery { this.trees = new HashMap<>(trees); } - @Override - public String evaluateExpressions(Map<String, String> attributes) throws ProcessException { - return evaluateExpressions(attributes, null); - } @Override - public String evaluateExpressions(final Map<String, String> attributes, final AttributeValueDecorator decorator) throws ProcessException { + public String evaluateExpressions(final VariableRegistry registry, final AttributeValueDecorator decorator) throws ProcessException { final StringBuilder sb = new StringBuilder(); for (final String val : queryStrings) { final Tree tree = trees.get(val); if (tree == null) { sb.append(val); } else { - final String evaluated = Query.evaluateExpression(tree, val, attributes, decorator); + final String evaluated = Query.evaluateExpression(tree, val, registry, decorator); if (evaluated != null) { sb.append(evaluated); } @@ -59,31 +55,4 @@ public class StandardPreparedQuery implements PreparedQuery { return sb.toString(); } - @Override - public String evaluateExpressions(final FlowFile flowFile, final Map<String, String> additionalAttributes, final AttributeValueDecorator decorator) throws ProcessException { - final Map<String, String> expressionMap = Query.createExpressionMap(flowFile, additionalAttributes); - return evaluateExpressions(expressionMap, decorator); - } - - @Override - public String evaluateExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException { - final Map<String, String> expressionMap = Query.createExpressionMap(flowFile); - return evaluateExpressions(expressionMap, decorator); - } - - @Override - public String evaluateExpressions() throws ProcessException { - return evaluateExpressions((FlowFile) null, null); - } - - @Override - public String evaluateExpressions(final AttributeValueDecorator decorator) throws ProcessException { - return evaluateExpressions((FlowFile) null, decorator); - } - - @Override - public String evaluateExpressions(final FlowFile flowFile) throws ProcessException { - return evaluateExpressions(flowFile, null); - } - }
