diff --git a/nifi-assembly/pom.xml b/nifi-assembly/pom.xml
index abcbd91366..76e001c4cb 100644
--- a/nifi-assembly/pom.xml
+++ b/nifi-assembly/pom.xml
@@ -336,12 +336,6 @@ language governing permissions and limitations under the License. -->
2.0.0-SNAPSHOTnar
-
- org.apache.nifi
- nifi-html-nar
- 2.0.0-SNAPSHOT
- nar
- org.apache.nifinifi-lookup-services-nar
@@ -420,12 +414,6 @@ language governing permissions and limitations under the License. -->
2.0.0-SNAPSHOTnar
-
- org.apache.nifi
- nifi-hl7-nar
- 2.0.0-SNAPSHOT
- nar
- org.apache.nifinifi-language-translation-nar
@@ -494,7 +482,7 @@ language governing permissions and limitations under the License. -->
org.apache.nifi
- nifi-riemann-nar
+ nifi-hl7-nar2.0.0-SNAPSHOTnar
@@ -552,12 +540,6 @@ language governing permissions and limitations under the License. -->
2.0.0-SNAPSHOTnar
-
- org.apache.nifi
- nifi-cybersecurity-nar
- 2.0.0-SNAPSHOT
- nar
- org.apache.nifinifi-email-nar
@@ -696,12 +678,6 @@ language governing permissions and limitations under the License. -->
2.0.0-SNAPSHOTnar
-
- org.apache.nifi
- nifi-tcp-nar
- 2.0.0-SNAPSHOT
- nar
- org.apache.nifinifi-gcp-nar
@@ -792,18 +768,6 @@ language governing permissions and limitations under the License. -->
2.0.0-SNAPSHOTnar
-
- org.apache.nifi
- nifi-metrics-reporter-service-api-nar
- 2.0.0-SNAPSHOT
- nar
-
-
- org.apache.nifi
- nifi-metrics-reporting-nar
- 2.0.0-SNAPSHOT
- nar
- org.apache.nifinifi-kerberos-credentials-service-nar
@@ -1084,24 +1048,6 @@ language governing permissions and limitations under the License. -->
-
- include-rules
-
-
- false
-
- allProfiles
-
-
-
-
- org.apache.nifi
- nifi-rules-action-handler-nar
- 2.0.0-SNAPSHOT
- nar
-
-
- include-sql-reporting
@@ -1118,12 +1064,6 @@ language governing permissions and limitations under the License. -->
2.0.0-SNAPSHOTnar
-
- org.apache.nifi
- nifi-rules-action-handler-nar
- 2.0.0-SNAPSHOT
- nar
-
@@ -1440,23 +1380,6 @@ language governing permissions and limitations under the License. -->
-
- include-riemann
-
- false
-
- allProfiles
-
-
-
-
- org.apache.nifi
- nifi-riemann-nar
- 2.0.0-SNAPSHOT
- nar
-
-
- include-snowflake
diff --git a/nifi-docs/src/main/asciidoc/developer-guide.adoc b/nifi-docs/src/main/asciidoc/developer-guide.adoc
index 509d81a9ae..185883d655 100644
--- a/nifi-docs/src/main/asciidoc/developer-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/developer-guide.adoc
@@ -2730,10 +2730,7 @@ deprecationLogger.warn(
| ASN.1 Support | include-asn1 | Adds support for ASN.1
| Contribution Check | contrib-check | Runs various quality checks that are required to be accepted before a contribution can be accepted into the core NiFi code base.
| Graph Database Bundle | include-graph | Adds support for various common graph database scenarios. Support is currently for https://neo4j.com/developer/cypher[Cypher] and https://tinkerpop.apache.org/gremlin.html[Gremlin]-compatible databases such as Neo4J and JanusGraph. Includes controller services that provide driver functionality and a suite of processors for ingestion and querying.
-| GRPC Bundle | include-grpc | **This profile is active in official builds and should be active** Provides support for the GRPC protocol.
| Media Bundle | include-media | The media bundle provides functionality based on https://tika.apache.org[Apache Tika] for extracting content and metadata from various types of binary formats supported by Apache Tika (ex. PDF, Microsoft Office).
-| Riemann Bundle | include-riemann | Adds support for Riemann database components
-| Rules Engine Bundle | include-rules | Adds support for creating scripted rules engines that can be integrated into existing flows. These rules engines can provide flexibility to people who need more complex flow logic or are more comfortable with flow decision-making using custom code.
| Snowflake Bundle | include-snowflake | Adds support for integration with the https://www.snowflake.com[Snowflake platform].
| SQL Reporting Bundle | include-sql-reporting | Adds reporting tasks that are designed to use SQL to update a RDBMS with metrics and other related data from Apache NiFi.
|==================================================================================================================================================
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/pom.xml b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/pom.xml
deleted file mode 100644
index a2e244f23d..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- 4.0.0
-
-
- org.apache.nifi
- nifi-cybersecurity-bundle
- 2.0.0-SNAPSHOT
-
-
- nifi-cybersecurity-nar
- nar
-
- true
- true
-
-
-
-
- org.apache.nifi
- nifi-cybersecurity-processors
- 2.0.0-SNAPSHOT
-
-
-
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/src/main/resources/META-INF/LICENSE b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/src/main/resources/META-INF/LICENSE
deleted file mode 100644
index 1806c0a1d2..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/src/main/resources/META-INF/LICENSE
+++ /dev/null
@@ -1,257 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed 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.
-
- APACHE NIFI SUBCOMPONENTS:
-
- The Apache NiFi project contains subcomponents with separate copyright
- notices and license terms. Your use of the source code for the these
- subcomponents is subject to the terms and conditions of the following
- licenses.
-
- The binary distribution of this project bundles "java-spamsum"
- which is available under an MIT style license.
-
- Copyright 2015 Thibault Debatty.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- The binary distribution of this project bundles "java-string-similarity"
- which is available under an MIT style license.
-
- Copyright 2015 Thibault Debatty.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/src/main/resources/META-INF/NOTICE b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index 15b9022255..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-nar/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,34 +0,0 @@
-nifi-cybersecurity-nar
-Copyright 2015-2020 The Apache Software Foundation
-
-
-===========================================
-Apache Software License v2
-===========================================
-
-The following binary components are provided under the Apache Software License v2
-
- (ASLv2) tlsh
- The following NOTICE information applies:
- Java port of Trend Locality Sensitive Hash (TLSH)
- Copyright 2000-2016 Idealista, S.A
-
- This product includes software developed at
- Idealista, S.A (http://www.idealista.com/)
-
- Based on the algorithms described in Trend Micro's TLSH official
- repository, available in:
-
- https://github.com/trendmicro/tlsh
-
- Refer to the following publication for more information:
-
- Jonathan Oliver, Chun Cheng and Yanggui Chen, “TLSH - A Locality
- Sensitive Hash” - 4th Cybercrime and Trustworthy Computing Workshop,
- Sydney, November 2013
-
- https://drive.google.com/file/d/0B6FS3SVQ1i0GTXk5eDl3Y29QWlk/edit?usp=sharing
-
- This software is inspired in the previous Java port developed by TripleCheck:
-
- https://github.com/triplecheck/TLSH
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/pom.xml b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/pom.xml
deleted file mode 100644
index e6385d5430..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/pom.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
- 4.0.0
-
-
- org.apache.nifi
- nifi-cybersecurity-bundle
- 2.0.0-SNAPSHOT
-
-
- nifi-cybersecurity-processors
- jar
-
-
-
- org.apache.nifi
- nifi-api
-
-
- org.apache.nifi
- nifi-utils
- 2.0.0-SNAPSHOT
-
-
- info.debatty
- java-spamsum
- 0.2
-
-
- com.idealista
- tlsh
- 1.0.0
-
-
- org.apache.nifi
- nifi-mock
- 2.0.0-SNAPSHOT
- test
-
-
- org.apache.nifi
- nifi-properties
- compile
-
-
-
-
-
- org.apache.rat
- apache-rat-plugin
-
-
- src/test/resources/blank_ssdeep.list
- src/test/resources/empty.list
- src/test/resources/ssdeep.list
- src/test/resources/tlsh.list
-
-
-
-
-
-
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/AbstractFuzzyHashProcessor.java b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/AbstractFuzzyHashProcessor.java
deleted file mode 100644
index c5b560d7d2..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/AbstractFuzzyHashProcessor.java
+++ /dev/null
@@ -1,88 +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.processors.cybersecurity;
-
-
-import com.idealista.tlsh.TLSH;
-import info.debatty.java.spamsum.SpamSum;
-import org.apache.nifi.components.AllowableValue;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.processor.AbstractProcessor;
-import org.apache.nifi.processor.Relationship;
-import org.apache.nifi.processor.util.StandardValidators;
-
-import java.util.List;
-import java.util.Set;
-
-abstract class AbstractFuzzyHashProcessor extends AbstractProcessor {
- final protected static String ssdeep = "ssdeep";
- final protected static String tlsh = "tlsh";
-
- public static final AllowableValue allowableValueSSDEEP = new AllowableValue(
- ssdeep,
- ssdeep,
- "Uses ssdeep / SpamSum 'context triggered piecewise hash'.");
- public static final AllowableValue allowableValueTLSH = new AllowableValue(
- tlsh,
- tlsh,
- "Uses TLSH (Trend 'Locality Sensitive Hash'). Note: FlowFile Content must be at least 512 characters long");
-
- public static final PropertyDescriptor ATTRIBUTE_NAME = new PropertyDescriptor.Builder()
- .name("ATTRIBUTE_NAME")
- .displayName("Hash Attribute Name")
- .description("The name of the FlowFile Attribute that should hold the Fuzzy Hash Value")
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .defaultValue("fuzzyhash.value")
- .build();
-
- public static final PropertyDescriptor HASH_ALGORITHM = new PropertyDescriptor.Builder()
- .name("HASH_ALGORITHM")
- .displayName("Hashing Algorithm")
- .description("The hashing algorithm utilised")
- .allowableValues(allowableValueSSDEEP, allowableValueTLSH)
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .build();
-
-
- protected List descriptors;
-
- protected Set relationships;
-
- protected boolean checkMinimumAlgorithmRequirements(String algorithm, FlowFile flowFile) {
- // Check if content matches minimum length requirement
- if (algorithm.equals(tlsh) && flowFile.getSize() < 512 ) {
- return false;
- } else {
- return true;
- }
- }
-
-
- protected String generateHash(String algorithm, String content) {
- switch (algorithm) {
- case tlsh:
- return new TLSH(content).hash();
- case ssdeep:
- return new SpamSum().HashString(content);
- default:
- return null;
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/CompareFuzzyHash.java b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/CompareFuzzyHash.java
deleted file mode 100644
index af520740e1..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/CompareFuzzyHash.java
+++ /dev/null
@@ -1,266 +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.processors.cybersecurity;
-
-import org.apache.nifi.annotation.behavior.InputRequirement;
-import org.apache.nifi.annotation.behavior.SideEffectFree;
-import org.apache.nifi.annotation.behavior.SupportsBatching;
-import org.apache.nifi.annotation.behavior.WritesAttribute;
-import org.apache.nifi.annotation.behavior.WritesAttributes;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.SeeAlso;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.components.AllowableValue;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.resource.ResourceCardinality;
-import org.apache.nifi.components.resource.ResourceType;
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.processor.ProcessContext;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.ProcessorInitializationContext;
-import org.apache.nifi.processor.Relationship;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.processors.cybersecurity.matchers.FuzzyHashMatcher;
-import org.apache.nifi.processors.cybersecurity.matchers.SSDeepHashMatcher;
-import org.apache.nifi.processors.cybersecurity.matchers.TLSHHashMatcher;
-import org.apache.nifi.util.StringUtils;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-
-@SideEffectFree
-@SupportsBatching
-@InputRequirement(InputRequirement.Requirement.INPUT_REQUIRED)
-@SeeAlso({FuzzyHashContent.class})
-@Tags({"hashing", "fuzzy-hashing", "cyber-security"})
-@CapabilityDescription("Compares an attribute containing a Fuzzy Hash against a file containing a list of fuzzy hashes, " +
- "appending an attribute to the FlowFile in case of a successful match.")
-
-@WritesAttributes({
- @WritesAttribute(attribute = "XXXX.N.match", description = "The match that resembles the attribute specified " +
- "by the property. Note that: 'XXX' gets replaced with the "),
- @WritesAttribute(attribute = "XXXX.N.similarity", description = "The similarity score between this flowfile" +
- "and its match of the same number N. Note that: 'XXX' gets replaced with the ")})
-
-public class CompareFuzzyHash extends AbstractFuzzyHashProcessor {
- public static final AllowableValue singleMatch = new AllowableValue(
- "single",
- "single",
- "Send FlowFile to matched after the first match above threshold");
- public static final AllowableValue multiMatch = new AllowableValue(
- "multi-match",
- "multi-match",
- "Iterate full list of hashes before deciding to send FlowFile to matched or unmatched");
-
- public static final PropertyDescriptor HASH_LIST_FILE = new PropertyDescriptor.Builder()
- .name("HASH_LIST_FILE")
- .displayName("Hash List Source File")
- .description("Path to the file containing hashes to be validated against")
- .required(true)
- .identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE)
- .build();
-
- // Note we add a PropertyDescriptor HASH_ALGORITHM and ATTRIBUTE_NAME from parent class
-
- public static final PropertyDescriptor MATCH_THRESHOLD = new PropertyDescriptor.Builder()
- // Note that while both TLSH and SSDeep seems to return int, we treat them as double in code.
- // The rationale behind being the expectation that other algorithms thatmay return double values
- // may be added to the processor later on.
- .name("MATCH_THRESHOLD")
- .displayName("Match Threshold")
- .description("The similarity score must exceed or be equal to in order for" +
- "match to be considered true. Refer to Additional Information for differences between TLSH " +
- "and SSDEEP scores and how they relate to this property.")
- .required(true)
- .addValidator(StandardValidators.NUMBER_VALIDATOR)
- .build();
-
- public static final PropertyDescriptor MATCHING_MODE = new PropertyDescriptor.Builder()
- .name("MATCHING_MODE")
- .displayName("Matching Mode")
- .description("Defines if the Processor should try to match as many entries as possible (" + multiMatch.getDisplayName() +
- ") or if it should stop after the first match (" + singleMatch.getDisplayName() + ")")
- .required(true)
- .allowableValues(singleMatch,multiMatch)
- .defaultValue(singleMatch.getValue())
- .build();
-
- public static final Relationship REL_FOUND = new Relationship.Builder()
- .name("found")
- .description("Any FlowFile that is successfully matched to an existing hash will be sent to this Relationship.")
- .build();
-
- public static final Relationship REL_NOT_FOUND = new Relationship.Builder()
- .name("not-found")
- .description("Any FlowFile that cannot be matched to an existing hash will be sent to this Relationship.")
- .build();
-
- public static final Relationship REL_FAILURE = new Relationship.Builder()
- .name("failure")
- .description("Any FlowFile that cannot be matched, e.g. (lacks the attribute) will be sent to this Relationship.")
- .build();
-
- @Override
- protected void init(final ProcessorInitializationContext context) {
- final List descriptors = new ArrayList();
- descriptors.add(HASH_LIST_FILE);
- // As mentioned above, add the PropertyDescriptor HASH_ALGORITHM and ATTRIBUTE_NAME from parent class
- descriptors.add(HASH_ALGORITHM);
- descriptors.add(ATTRIBUTE_NAME);
- descriptors.add(MATCH_THRESHOLD);
- descriptors.add(MATCHING_MODE);
- this.descriptors = Collections.unmodifiableList(descriptors);
-
- final Set relationships = new HashSet();
- relationships.add(REL_FOUND);
- relationships.add(REL_NOT_FOUND);
- relationships.add(REL_FAILURE);
- this.relationships = Collections.unmodifiableSet(relationships);
- }
-
- @Override
- public Set getRelationships() {
- return this.relationships;
- }
-
- @Override
- public final List getSupportedPropertyDescriptors() {
- return descriptors;
- }
-
-
- @Override
- public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
-
- FlowFile flowFile = session.get();
- if (flowFile == null) {
- return;
- }
-
- final ComponentLog logger = getLogger();
- String algorithm = context.getProperty(HASH_ALGORITHM).getValue();
-
- final String attributeName = context.getProperty(ATTRIBUTE_NAME).getValue();
- String inputHash = flowFile.getAttribute(attributeName);
-
- if (inputHash == null) {
- getLogger().info("FlowFile {} lacks the required '{}' attribute, routing to failure.",
- new Object[]{flowFile, attributeName});
- session.transfer(flowFile, REL_FAILURE);
- return;
- }
-
- final FuzzyHashMatcher fuzzyHashMatcher;
-
- switch (algorithm) {
- case tlsh:
- fuzzyHashMatcher = new TLSHHashMatcher(getLogger());
- break;
- case ssdeep:
- fuzzyHashMatcher = new SSDeepHashMatcher(getLogger());
- break;
- default:
- getLogger().error("Seems like the processor is configured to use unsupported algorithm '{}' ? Yielding.",
- new Object[]{algorithm});
- context.yield();
- return;
- }
-
- if (!fuzzyHashMatcher.isValidHash(inputHash)) {
- // and if that is the case we log
- logger.error("Invalid hash provided for {}. Sending to failure", flowFile);
- // and send to failure
- session.transfer(flowFile, REL_FAILURE);
- return;
- }
-
- double similarity = 0;
- double matchThreshold = context.getProperty(MATCH_THRESHOLD).asDouble();
-
- try {
- Map matched = new LinkedHashMap<>();
-
- try (BufferedReader reader = fuzzyHashMatcher.getReader(context.getProperty(HASH_LIST_FILE).getValue())) {
- String line = null;
-
- while ((line = reader.readLine()) != null) {
- similarity = fuzzyHashMatcher.getSimilarity(inputHash, line);
-
- if (fuzzyHashMatcher.matchExceedsThreshold(similarity, matchThreshold)) {
- String match = fuzzyHashMatcher.getMatch(line);
- // A malformed file may cause a match with no filename
- // Because this would simply look odd, we ignore such entry and log
- if (!StringUtils.isEmpty(match)) {
- matched.put(match, similarity);
- } else {
- logger.error("Found a match against a malformed entry '{}'. Please inspect the contents of" +
- "the {} file and ensure they are properly formatted",
- new Object[]{line, HASH_LIST_FILE.getDisplayName()});
- }
- }
-
- // Check if single match is desired and if a match has been made
- if (Objects.equals(context.getProperty(MATCHING_MODE).getValue(), singleMatch.getValue()) && (matched.size() > 0)) {
- // and save time by breaking the outer loop
- break;
- }
- }
- }
-
- // Then by iterating over the hashmap of matches
- if (matched.size() > 0) {
- // no matter if the break was called or not, Continue processing
- // First by creating a new map to hold attributes
- final Map attributes = new HashMap<>();
-
- int x = 0;
- for (Map.Entry entry : matched.entrySet()) {
- // defining attributes accordingly
- attributes.put(attributeName + "." + x + ".match", entry.getKey());
- attributes.put(attributeName + "." + x + ".similarity", String.valueOf(entry.getValue()));
- x++;
- }
-
- // Finally, append the attributes to the flowfile and sent to match
- flowFile = session.putAllAttributes(flowFile, attributes);
- session.transfer(flowFile, REL_FOUND);
- } else {
- // Otherwise send it to non-match
- session.transfer(flowFile, REL_NOT_FOUND);
- }
- } catch (final IOException e) {
- logger.error("Error while reading the hash input source for {}", flowFile, e);
- session.transfer(flowFile, REL_FAILURE);
- }
- }
-
-
-
-}
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/FuzzyHashContent.java b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/FuzzyHashContent.java
deleted file mode 100644
index f6acd1f11c..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/FuzzyHashContent.java
+++ /dev/null
@@ -1,175 +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.processors.cybersecurity;
-
-import com.idealista.tlsh.exceptions.InsufficientComplexityException;
-
-import org.apache.nifi.annotation.behavior.InputRequirement;
-import org.apache.nifi.annotation.behavior.SideEffectFree;
-import org.apache.nifi.annotation.behavior.SupportsBatching;
-import org.apache.nifi.annotation.behavior.WritesAttribute;
-import org.apache.nifi.annotation.behavior.WritesAttributes;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.SeeAlso;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnScheduled;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.processor.ProcessContext;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.ProcessorInitializationContext;
-import org.apache.nifi.processor.Relationship;
-import org.apache.nifi.processor.io.InputStreamCallback;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.util.StringUtils;
-
-import org.apache.nifi.stream.io.StreamUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-
-
-@SideEffectFree
-@SupportsBatching
-@InputRequirement(InputRequirement.Requirement.INPUT_REQUIRED)
-@Tags({"hashing", "fuzzy-hashing", "cyber-security"})
-@CapabilityDescription("Calculates a fuzzy/locality-sensitive hash value for the Content of a FlowFile and puts that " +
- "hash value on the FlowFile as an attribute whose name is determined by the property." +
- "Note: this processor only offers non-cryptographic hash algorithms. And it should be not be " +
- "seen as a replacement to the HashContent processor." +
- "Note: The underlying library loads the entirety of the streamed content into and performs result " +
- "evaluations in memory. Accordingly, it is important to consider the anticipated profile of content being " +
- "evaluated by this processor and the hardware supporting it especially when working against large files.")
-
-@SeeAlso(value = {CompareFuzzyHash.class})
-@WritesAttributes({@WritesAttribute(attribute = "", description = "This Processor adds an attribute whose value is the result of Hashing the "
- + "existing FlowFile content. The name of this attribute is specified by the property")})
-
-public class FuzzyHashContent extends AbstractFuzzyHashProcessor {
-
-
-
- public static final PropertyDescriptor HASH_ALGORITHM = new PropertyDescriptor.Builder()
- .name("HASH_ALGORITHM")
- .displayName("Hashing Algorithm")
- .description("The hashing algorithm utilised")
- .allowableValues(allowableValueSSDEEP, allowableValueTLSH)
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .build();
-
- public static final Relationship REL_SUCCESS = new Relationship.Builder()
- .name("success")
- .description("Any FlowFile that is successfully hashed will be sent to this Relationship.")
- .build();
-
- public static final Relationship REL_FAILURE = new Relationship.Builder()
- .name("failure")
- .description("Any FlowFile that is successfully hashed will be sent to this Relationship.")
- .build();
-
- private List descriptors;
-
- private Set relationships;
-
- @Override
- protected void init(final ProcessorInitializationContext context) {
- final List descriptors = new ArrayList();
- descriptors.add(ATTRIBUTE_NAME);
- descriptors.add(HASH_ALGORITHM);
- this.descriptors = Collections.unmodifiableList(descriptors);
-
- final Set relationships = new HashSet();
- relationships.add(REL_SUCCESS);
- relationships.add(REL_FAILURE);
- this.relationships = Collections.unmodifiableSet(relationships);
- }
-
- @Override
- public Set getRelationships() {
- return this.relationships;
- }
-
- @Override
- public final List getSupportedPropertyDescriptors() {
- return descriptors;
- }
-
- @OnScheduled
- public void onScheduled(final ProcessContext context) {
- }
-
- @Override
- public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
- FlowFile flowFile = session.get();
- if (flowFile == null) {
- return;
- }
-
- final ComponentLog logger = getLogger();
- String algorithm = context.getProperty(HASH_ALGORITHM).getValue();
-
- // Check if content matches minimum length requirement
-
- if (checkMinimumAlgorithmRequirements(algorithm, flowFile) == false) {
- logger.error("The content of '{}' is smaller than the minimum required by {}, routing to failure",
- new Object[]{flowFile, algorithm});
- session.transfer(flowFile, REL_FAILURE);
- return;
- }
-
- final AtomicReference hashValueHolder = new AtomicReference<>(null);
-
- try {
- session.read(flowFile, new InputStreamCallback() {
- @Override
- public void process(final InputStream in) throws IOException {
- try (ByteArrayOutputStream holder = new ByteArrayOutputStream()) {
- StreamUtils.copy(in,holder);
-
- String hashValue = generateHash(algorithm, holder.toString());
- if (StringUtils.isBlank(hashValue) == false) {
- hashValueHolder.set(hashValue);
- }
-
-
- }
- }
- });
-
- final String attributeName = context.getProperty(ATTRIBUTE_NAME).getValue();
- flowFile = session.putAttribute(flowFile, attributeName, hashValueHolder.get());
- logger.info("Successfully added attribute '{}' to {} with a value of {}; routing to success", new Object[]{attributeName, flowFile, hashValueHolder.get()});
- session.getProvenanceReporter().modifyAttributes(flowFile);
- session.transfer(flowFile, REL_SUCCESS);
- } catch (final InsufficientComplexityException | ProcessException e) {
- logger.error("Failed to process {} due to {}; routing to failure", new Object[]{flowFile, e});
- session.transfer(flowFile, REL_FAILURE);
- }
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/FuzzyHashMatcher.java b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/FuzzyHashMatcher.java
deleted file mode 100644
index 91dbd1237c..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/FuzzyHashMatcher.java
+++ /dev/null
@@ -1,35 +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.processors.cybersecurity.matchers;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-
-public interface FuzzyHashMatcher {
-
- BufferedReader getReader(String source) throws IOException;
-
- boolean matchExceedsThreshold(double similarity, double matchThreshold) ;
-
- double getSimilarity(String inputHash, String existingHash);
-
- boolean isValidHash(String inputHash);
-
- String getHash(String line);
-
- String getMatch(String line);
-}
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/SSDeepHashMatcher.java b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/SSDeepHashMatcher.java
deleted file mode 100644
index 9371bfd527..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/SSDeepHashMatcher.java
+++ /dev/null
@@ -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.
- */
-package org.apache.nifi.processors.cybersecurity.matchers;
-
-import info.debatty.java.spamsum.SpamSum;
-import org.apache.nifi.logging.ComponentLog;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Scanner;
-
-public class SSDeepHashMatcher implements FuzzyHashMatcher {
-
- ComponentLog logger;
-
- public SSDeepHashMatcher() {
-
- }
-
- public SSDeepHashMatcher(ComponentLog logger) {
- this.logger = logger;
- }
-
- @Override
- public BufferedReader getReader(String source) throws IOException {
-
- File file = new File(source);
-
- FileInputStream fileInputStream = new FileInputStream(file);
- BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
-
- // If SSdeep skip the first line (as the usual format used by other tools add a header line
- // to a file list
- reader.readLine();
-
- return reader;
- }
-
- @Override
- public boolean matchExceedsThreshold(double similarity, double matchThreshold) {
- if (similarity >= matchThreshold) {
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public double getSimilarity(String inputHash, String existingHash) {
- String[] hashToCompare = existingHash.split(",", 2);
- if (hashToCompare.length > 0) {
- return new SpamSum().match(inputHash, hashToCompare[0]);
- } else {
- return Double.NaN;
- }
- }
-
- @Override
- public boolean isValidHash(String inputHash) {
- // format looks like
- // blocksize:hash:hash
-
- String [] fields = inputHash.split(":", 3);
-
- if (fields.length == 3) {
- Scanner sc = new Scanner(fields[0]);
-
- boolean isNumber = sc.hasNextInt();
- if (isNumber == false && logger != null) {
- if (logger.isDebugEnabled()) {
- logger.debug("Field should be numeric but got '{}'. Will tell processor to ignore.",
- new Object[] {fields[0]});
- }
- }
-
- boolean hashOneIsNotEmpty = !fields[1].isEmpty();
- boolean hashTwoIsNotEmpty = !fields[2].isEmpty();
-
- if (isNumber && hashOneIsNotEmpty && hashTwoIsNotEmpty) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String getHash(String line) {
- if (isValidHash(line)) {
- return line.split(",", 2)[0];
- } else {
- return null;
- }
- }
-
- @Override
- public String getMatch(String line) {
- if (isValidHash(line)) {
- String[] match = line.split(",", 2);
- // Because the file can be malformed and contain an unammed match,
- // if match has a filename...
- if (match.length == 2) {
- // Return it.
- return match[1];
- }
- }
- // Or return null
- return null;
- }
-}
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/TLSHHashMatcher.java b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/TLSHHashMatcher.java
deleted file mode 100644
index 73a140a5bb..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/java/org/apache/nifi/processors/cybersecurity/matchers/TLSHHashMatcher.java
+++ /dev/null
@@ -1,117 +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.processors.cybersecurity.matchers;
-
-
-import com.idealista.tlsh.digests.Digest;
-import com.idealista.tlsh.digests.DigestBuilder;
-import org.apache.nifi.logging.ComponentLog;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import static org.apache.nifi.processors.cybersecurity.CompareFuzzyHash.HASH_LIST_FILE;
-
-public class TLSHHashMatcher implements FuzzyHashMatcher {
-
- ComponentLog logger;
-
- public TLSHHashMatcher(ComponentLog logger) {
- this.logger = logger;
- }
-
- @Override
- public BufferedReader getReader(String source) throws IOException {
-
- File file = new File(source);
-
- FileInputStream fileInputStream = new FileInputStream(file);
- BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
-
- return reader;
- }
-
- @Override
- public boolean matchExceedsThreshold(double similarity, double matchThreshold) {
- if (similarity <= matchThreshold) {
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public double getSimilarity(String inputHash, String existingHash) {
- String[] hashToCompare = existingHash.split("\t", 2);
- // This will return null in case it fails validation
- if (isValidHash(inputHash) && isValidHash(hashToCompare[0])) {
- Digest inputDigest = new DigestBuilder().withHash(inputHash).build();
- Digest existingHashDigest = new DigestBuilder().withHash(hashToCompare[0]).build();
-
- return inputDigest.calculateDifference(existingHashDigest, true);
- } else {
- return Double.NaN;
- }
- }
-
- @Override
- public boolean isValidHash(String stringFromHashList) {
- String[] hashToCompare = stringFromHashList.split("\t", 2);
- // This will return null in case it fails validation
- if (hashToCompare.length > 0) {
- // Because DigestBuilder raises all sort of exceptions, so in order to keep the onTrigger loop a
- // bit cleaner, we capture them here and return NaN to the loop above, otherwise simply return the
- // similarity score.
- try {
- Digest digest = new DigestBuilder().withHash(hashToCompare[0]).build();
- return true;
- } catch (ArrayIndexOutOfBoundsException | StringIndexOutOfBoundsException | NumberFormatException e) {
- logger.error("Got {} while processing the string '{}'. This usually means the file " +
- "defined by '{}' property contains invalid entries.",
- new Object[]{e.getCause(), hashToCompare[0], HASH_LIST_FILE.getDisplayName()});
- }
- }
- return false;
- }
-
- @Override
- public String getHash(String line) {
- if (isValidHash(line)) {
- return line.split("\t", 2)[0];
- } else {
- return null;
- }
- }
-
- @Override
- public String getMatch(String line) {
- if (isValidHash(line)) {
- String[] match = line.split("\t", 2);
- // Because the file can be malformed and contain an unammed match,
- // if match has a filename...
- if (match.length == 2) {
- // Return it.
- return match[1];
- }
- }
- // Or return null
- return null;
- }
-}
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
deleted file mode 100644
index e7cb5f7fca..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
+++ /dev/null
@@ -1,16 +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.
-org.apache.nifi.processors.cybersecurity.FuzzyHashContent
-org.apache.nifi.processors.cybersecurity.CompareFuzzyHash
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/resources/docs/org/apache/nifi/processors/cybersecurity/CompareFuzzyHash/additionalDetails.html b/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/resources/docs/org/apache/nifi/processors/cybersecurity/CompareFuzzyHash/additionalDetails.html
deleted file mode 100644
index ae2d5d3296..0000000000
--- a/nifi-nar-bundles/nifi-cybersecurity-bundle/nifi-cybersecurity-processors/src/main/resources/docs/org/apache/nifi/processors/cybersecurity/CompareFuzzyHash/additionalDetails.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
- CompareFuzzyHash
-
-
-
-
-
-
Description:
-
This Processor compares a an attribute containing a Fuzzy Hash (TLSH or SSDeep) value and compares it against a list
- of hashes of the same family (i.e. TLSH is compared with a list of TLSH hashes), routing them to match or non-match
- depending on a user configured threshold for similarity.
-
-
-
It is important to note that:
-
-
-
TLSH similarity increases as product of its comparison function decreases (i.e. 0 indicates nearly identical files)
-
SSDeep similarity directly relates to the product of its comparison function (e.g. 99 indicates nearly identical files
-
-
Based on the above, this processor when referring to "exceed the score" may be referring to:
-
-
-
a value equal or lower than the configured threshold (in case of TLSH)
-
a value equal or higher than the configured threshold (in case of SSDeep)
'")
- .required(true)
- .allowableValues(APPEND_ELEMENT, PREPEND_ELEMENT)
- .defaultValue(APPEND_ELEMENT)
- .build();
-
- public static final PropertyDescriptor PUT_VALUE = new PropertyDescriptor.Builder()
- .name("Put Value")
- .description("Value used when creating the new Element. Value should be a valid HTML element. " +
- "The text should be supplied unencoded: characters like '<', '>', etc will be properly HTML " +
- "encoded in the resulting output.")
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .build();
-
- private List descriptors;
-
- private Set relationships;
-
- @Override
- protected void init(final ProcessorInitializationContext context) {
- final List descriptors = new ArrayList();
- descriptors.add(CSS_SELECTOR);
- descriptors.add(HTML_CHARSET);
- descriptors.add(PUT_LOCATION_TYPE);
- descriptors.add(PUT_VALUE);
- this.descriptors = Collections.unmodifiableList(descriptors);
-
- final Set relationships = new HashSet();
- relationships.add(REL_ORIGINAL);
- relationships.add(REL_SUCCESS);
- relationships.add(REL_INVALID_HTML);
- relationships.add(REL_NOT_FOUND);
- this.relationships = Collections.unmodifiableSet(relationships);
- }
-
- @Override
- public Set getRelationships() {
- return this.relationships;
- }
-
- @Override
- public final List getSupportedPropertyDescriptors() {
- return descriptors;
- }
-
- /**
- * This processor used to support URL property, but it has been removed
- * since it's not required when altering HTML elements.
- * Support URL as dynamic property so that existing data flow can stay in valid state without modification.
- */
- @Override
- protected PropertyDescriptor getSupportedDynamicPropertyDescriptor(final String propertyDescriptorName) {
- return URL;
- }
-
- @Override
- public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
- final FlowFile flowFile = session.get();
- if (flowFile == null) {
- return;
- }
-
- final Document doc;
- final Elements eles;
- try {
- doc = parseHTMLDocumentFromFlowfile(flowFile, context, session);
- eles = doc.select(context.getProperty(CSS_SELECTOR).evaluateAttributeExpressions(flowFile).getValue());
- } catch (Exception ex) {
- getLogger().error("Failed to extract HTML from {} due to {}; routing to {}", flowFile, ex.toString(), REL_INVALID_HTML.getName(), ex);
- session.transfer(flowFile, REL_INVALID_HTML);
- return;
- }
-
-
- if (eles == null || eles.isEmpty()) {
- // No element found
- session.transfer(flowFile, REL_NOT_FOUND);
- } else {
- final String putValue = context.getProperty(PUT_VALUE).evaluateAttributeExpressions(flowFile).getValue();
-
- for (final Element ele : eles) {
- switch (context.getProperty(PUT_LOCATION_TYPE).getValue()) {
- case APPEND_ELEMENT:
- ele.append(putValue);
- break;
- case PREPEND_ELEMENT:
- ele.prepend(putValue);
- break;
- }
- }
-
- FlowFile ff = session.write(session.create(flowFile), new StreamCallback() {
- @Override
- public void process(final InputStream in, final OutputStream out) throws IOException {
- out.write(doc.html().getBytes(StandardCharsets.UTF_8));
- }
- });
-
- session.transfer(ff, REL_SUCCESS);
-
- // Transfer the original HTML
- session.transfer(flowFile, REL_ORIGINAL);
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
deleted file mode 100644
index aea106050c..0000000000
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
+++ /dev/null
@@ -1,17 +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.
-org.apache.nifi.GetHTMLElement
-org.apache.nifi.ModifyHTMLElement
-org.apache.nifi.PutHTMLElement
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/AbstractHTMLTest.java b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/AbstractHTMLTest.java
deleted file mode 100644
index ba34be1d3f..0000000000
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/AbstractHTMLTest.java
+++ /dev/null
@@ -1,26 +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;
-
-public abstract class AbstractHTMLTest {
- protected final String ATL_WEATHER_TEXT = "Atlanta Weather";
- protected final String GDR_WEATHER_TEXT = "Grand Rapids Weather";
- protected final String ATL_WEATHER_LINK = "http://w1.weather.gov/obhistory/KPDK.html";
- protected final String AUTHOR_NAME = "Apache NiFi Community";
- protected final String ATL_ID = "ATL";
- protected final String GDR_ID = "GDR";
-}
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestGetHTMLElement.java b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestGetHTMLElement.java
deleted file mode 100644
index 36c81fed62..0000000000
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestGetHTMLElement.java
+++ /dev/null
@@ -1,352 +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;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.nifi.util.MockFlowFile;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.select.Selector;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class TestGetHTMLElement extends AbstractHTMLTest {
-
- private TestRunner testRunner;
-
- @BeforeEach
- public void init() {
- testRunner = TestRunners.newTestRunner(GetHTMLElement.class);
- testRunner.setProperty(GetHTMLElement.URL, "http://localhost");
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_HTML);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.HTML_CHARSET, "UTF-8");
- }
-
- @Test
- public void testCSSSelectorSyntaxValidator() throws IOException {
- Document doc = Jsoup.parse(new File("src/test/resources/Weather.html"), StandardCharsets.UTF_8.name());
- assertThrows(Selector.SelectorParseException.class, () -> doc.select("---invalidCssSelector"));
- }
-
- @Test
- public void testNoElementFound() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "b"); //Bold element is not present in sample HTML
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 1);
- }
-
- @Test
- public void testInvalidSelector() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "InvalidCSSSelectorSyntax");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 1);
- }
-
- @Test
- public void testSingleElementFound() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "head");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
- }
-
- @Test
- public void testMultipleElementFound() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "a");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 3);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
- }
-
- @Test
- public void testElementFoundWriteToAttribute() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "href");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertAttributeEquals(GetHTMLElement.HTML_ELEMENT_ATTRIBUTE_NAME, ATL_WEATHER_LINK);
- }
-
- @Test
- public void testElementFoundWriteToContent() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "href");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals(ATL_WEATHER_LINK);
- }
-
- @Test
- public void testValidPrependValueToFoundElement() throws Exception {
- final String PREPEND_VALUE = "TestPrepend";
- testRunner.setProperty(GetHTMLElement.PREPEND_ELEMENT_VALUE, PREPEND_VALUE);
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "href");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals(PREPEND_VALUE + ATL_WEATHER_LINK);
- }
-
- @Test
- public void testValidPrependValueToNotFoundElement() throws Exception {
- final String PREPEND_VALUE = "TestPrepend";
- testRunner.setProperty(GetHTMLElement.PREPEND_ELEMENT_VALUE, PREPEND_VALUE);
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "b");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_TEXT);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 1);
- }
-
- @Test
- public void testValidAppendValueToFoundElement() throws Exception {
- final String APPEND_VALUE = "TestAppend";
- testRunner.setProperty(GetHTMLElement.APPEND_ELEMENT_VALUE, APPEND_VALUE);
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "href");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals(ATL_WEATHER_LINK + APPEND_VALUE);
- }
-
- @Test
- public void testValidAppendValueToNotFoundElement() throws Exception {
- final String APPEND_VALUE = "TestAppend";
- testRunner.setProperty(GetHTMLElement.APPEND_ELEMENT_VALUE, APPEND_VALUE);
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "b");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_TEXT);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 1);
- }
-
- @Test
- public void testExtractAttributeFromElement() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "meta[name=author]");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "Content");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals(AUTHOR_NAME);
- }
-
- @Test
- public void testExtractAttributeFromElementRelativeUrl() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "script");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "src");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals("js/scripts.js");
- }
-
- @Test
- public void testExtractAttributeFromElementAbsoluteUrl() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "script");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "abs:src");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals("http://localhost/js/scripts.js");
- }
-
- @Test
- public void testExtractAttributeFromElementAbsoluteUrlWithEL() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "script");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "abs:src");
- testRunner.setProperty(GetHTMLElement.URL, "${contentUrl}");
-
- final Map attributes = new HashMap<>();
- attributes.put("contentUrl", "https://example.com/a/b/c/Weather.html");
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath(), attributes);
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals("https://example.com/a/b/c/js/scripts.js");
- }
-
- @Test
- public void testExtractAttributeFromElementAbsoluteUrlWithEmptyElResult() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "script");
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(GetHTMLElement.ATTRIBUTE_KEY, "abs:src");
- // Expression Language returns empty string because flow-file doesn't have contentUrl attribute.
- testRunner.setProperty(GetHTMLElement.URL, "${contentUrl}");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
- }
-
- @Test
- public void testExtractTextFromElement() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_TEXT);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals(ATL_WEATHER_TEXT);
- }
-
- @Test
- public void testExtractHTMLFromElement() throws Exception {
- testRunner.setProperty(GetHTMLElement.CSS_SELECTOR, "#" + GDR_ID);
- testRunner.setProperty(GetHTMLElement.DESTINATION, GetHTMLElement.DESTINATION_CONTENT);
- testRunner.setProperty(GetHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_HTML);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(GetHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(GetHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(GetHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(GetHTMLElement.REL_SUCCESS);
- ffs.get(0).assertContentEquals(GDR_WEATHER_TEXT);
- }
-}
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestModifyHTMLElement.java b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestModifyHTMLElement.java
deleted file mode 100644
index ba21693892..0000000000
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestModifyHTMLElement.java
+++ /dev/null
@@ -1,204 +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;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.util.MockFlowFile;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.io.File;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class TestModifyHTMLElement extends AbstractHTMLTest {
-
- private TestRunner testRunner;
-
- @BeforeEach
- public void init() {
- testRunner = TestRunners.newTestRunner(ModifyHTMLElement.class);
- testRunner = TestRunners.newTestRunner(ModifyHTMLElement.class);
- testRunner.setProperty(ModifyHTMLElement.URL, "http://localhost");
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, GetHTMLElement.ELEMENT_HTML);
- testRunner.setProperty(ModifyHTMLElement.HTML_CHARSET, "UTF-8");
- }
-
- @Test
- public void testModifyText() throws Exception {
- final String MOD_VALUE = "Newly modified value to replace " + ATL_WEATHER_TEXT;
- testRunner.setProperty(ModifyHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, ModifyHTMLElement.ELEMENT_TEXT);
- testRunner.setProperty(ModifyHTMLElement.MODIFIED_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(ModifyHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(ModifyHTMLElement.REL_SUCCESS);
- assertTrue(ffs.size() == 1);
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#" + ATL_ID);
- Element ele = eles.get(0);
-
- assertTrue(StringUtils.equals(MOD_VALUE, ele.text()));
- }
-
- @Test
- public void testModifyHTMLWithExpressionLanguage() throws Exception {
-
- final String MOD_VALUE = "Newly modified value to replace " + ATL_WEATHER_TEXT;
-
- testRunner.setProperty(ModifyHTMLElement.CSS_SELECTOR, "#" + ATL_ID);
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, ModifyHTMLElement.ELEMENT_TEXT);
- testRunner.setProperty(ModifyHTMLElement.MODIFIED_VALUE, "${\" " + MOD_VALUE + " \":trim()}");
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(ModifyHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(ModifyHTMLElement.REL_SUCCESS);
- assertTrue(ffs.size() == 1);
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#" + ATL_ID);
- Element ele = eles.get(0);
-
- assertNotNull(ele.text());
- }
-
- @Test
- public void testModifyHTML() throws Exception {
- final String MOD_VALUE = "Newly modified HTML to replace " + GDR_WEATHER_TEXT;
- testRunner.setProperty(ModifyHTMLElement.CSS_SELECTOR, "#" + GDR_ID);
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, ModifyHTMLElement.ELEMENT_HTML);
- testRunner.setProperty(ModifyHTMLElement.MODIFIED_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(ModifyHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(ModifyHTMLElement.REL_SUCCESS);
- assertTrue(ffs.size() == 1);
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#" + GDR_ID);
- Element ele = eles.get(0);
-
- assertTrue(StringUtils.equals(MOD_VALUE, ele.html()));
- }
-
- @Test
- public void testModifyAttribute() throws Exception {
- final String MOD_VALUE = "http://localhost/newlink";
- testRunner.setProperty(ModifyHTMLElement.CSS_SELECTOR, "#" + GDR_ID);
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, ModifyHTMLElement.ELEMENT_ATTRIBUTE);
- testRunner.setProperty(ModifyHTMLElement.ATTRIBUTE_KEY, "href");
- testRunner.setProperty(ModifyHTMLElement.MODIFIED_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(ModifyHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(ModifyHTMLElement.REL_SUCCESS);
- assertTrue(ffs.size() == 1);
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#" + GDR_ID);
- Element ele = eles.get(0);
-
- assertTrue(StringUtils.equals(MOD_VALUE, ele.attr("href")));
- }
-
- @Test
- public void testModifyElementNotFound() throws Exception {
- final String MOD_VALUE = "http://localhost/newlink";
- testRunner.setProperty(ModifyHTMLElement.CSS_SELECTOR, "b");
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, ModifyHTMLElement.ELEMENT_HTML);
- testRunner.setProperty(ModifyHTMLElement.MODIFIED_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(ModifyHTMLElement.REL_SUCCESS, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_ORIGINAL, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_NOT_FOUND, 1);
- }
-
- @Test
- public void testModifyValueContainsHTMLCharacters() throws Exception {
- final String MOD_VALUE = "Text that contains > and < characters";
- testRunner.setProperty(ModifyHTMLElement.CSS_SELECTOR, "#" + GDR_ID);
- testRunner.setProperty(ModifyHTMLElement.OUTPUT_TYPE, ModifyHTMLElement.ELEMENT_HTML);
- testRunner.setProperty(ModifyHTMLElement.MODIFIED_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(ModifyHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(ModifyHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(ModifyHTMLElement.REL_SUCCESS);
- assertTrue(ffs.size() == 1);
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#" + GDR_ID);
- Element ele = eles.get(0);
-
- assertTrue(StringUtils.equals(MOD_VALUE, ele.text()));
- assertTrue(StringUtils.equals(MOD_VALUE.replace(">", ">").replace("<", "<"), ele.html()));
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestPutHTMLElement.java b/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestPutHTMLElement.java
deleted file mode 100644
index e9a7fcb926..0000000000
--- a/nifi-nar-bundles/nifi-html-bundle/nifi-html-processors/src/test/java/org/apache/nifi/TestPutHTMLElement.java
+++ /dev/null
@@ -1,127 +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;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.util.MockFlowFile;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.io.File;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class TestPutHTMLElement extends AbstractHTMLTest {
-
- private TestRunner testRunner;
-
- @BeforeEach
- public void init() {
- testRunner = TestRunners.newTestRunner(PutHTMLElement.class);
- testRunner.setProperty(PutHTMLElement.URL, "http://localhost");
- }
-
- @Test
- public void testAddNewElementToRoot() throws Exception {
- final String MOD_VALUE = "
modified value
";
- testRunner.setProperty(PutHTMLElement.CSS_SELECTOR, "body");
- testRunner.setProperty(PutHTMLElement.PUT_LOCATION_TYPE, PutHTMLElement.PREPEND_ELEMENT);
- testRunner.setProperty(PutHTMLElement.PUT_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(PutHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(PutHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(PutHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(PutHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(PutHTMLElement.REL_SUCCESS);
- assertEquals(1, ffs.size());
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("body > p");
- Element ele = eles.get(0);
-
- assertTrue(StringUtils.equals(MOD_VALUE.replace("
";
- testRunner.setProperty(PutHTMLElement.CSS_SELECTOR, "#put");
- testRunner.setProperty(PutHTMLElement.PUT_LOCATION_TYPE, PutHTMLElement.PREPEND_ELEMENT);
- testRunner.setProperty(PutHTMLElement.PUT_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(PutHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(PutHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(PutHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(PutHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(PutHTMLElement.REL_SUCCESS);
- assertEquals(1, ffs.size());
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#put");
- Element ele = eles.get(0);
-
- assertEquals("
modified value
", ele.html());
- }
-
- @Test
- public void testAppendPElementToDiv() throws Exception {
- final String MOD_VALUE = "
modified value
";
- testRunner.setProperty(PutHTMLElement.CSS_SELECTOR, "#put");
- testRunner.setProperty(PutHTMLElement.PUT_LOCATION_TYPE, PutHTMLElement.APPEND_ELEMENT);
- testRunner.setProperty(PutHTMLElement.PUT_VALUE, MOD_VALUE);
-
- testRunner.enqueue(new File("src/test/resources/Weather.html").toPath());
- testRunner.run();
-
- testRunner.assertTransferCount(PutHTMLElement.REL_SUCCESS, 1);
- testRunner.assertTransferCount(PutHTMLElement.REL_INVALID_HTML, 0);
- testRunner.assertTransferCount(PutHTMLElement.REL_ORIGINAL, 1);
- testRunner.assertTransferCount(PutHTMLElement.REL_NOT_FOUND, 0);
-
- List ffs = testRunner.getFlowFilesForRelationship(PutHTMLElement.REL_SUCCESS);
- assertEquals(1, ffs.size());
- String data = new String(testRunner.getContentAsByteArray(ffs.get(0)));
-
- //Contents will be the entire HTML doc. So lets use Jsoup again just the grab the element we want.
- Document doc = Jsoup.parse(data);
- Elements eles = doc.select("#put");
- Element ele = eles.get(0);
-
- assertEquals("
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-html-bundle/pom.xml b/nifi-nar-bundles/nifi-html-bundle/pom.xml
deleted file mode 100644
index ae5422aaf1..0000000000
--- a/nifi-nar-bundles/nifi-html-bundle/pom.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- 4.0.0
-
-
- org.apache.nifi
- nifi-nar-bundles
- 2.0.0-SNAPSHOT
-
-
- nifi-html-bundle
- pom
-
-
- nifi-html-processors
- nifi-html-nar
-
-
-
-
-
- org.apache.nifi
- nifi-html-processors
- 2.0.0-SNAPSHOT
-
-
-
-
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api-nar/pom.xml b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api-nar/pom.xml
deleted file mode 100644
index 31d649949e..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api-nar/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
- nifi-metrics-reporting-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- nar
- 4.0.0
-
- nifi-metrics-reporter-service-api-nar
-
-
- org.apache.nifi
- nifi-standard-services-api-nar
- 2.0.0-SNAPSHOT
- nar
-
-
- org.apache.nifi
- nifi-metrics-reporter-service-api
- 2.0.0-SNAPSHOT
-
-
-
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api-nar/src/main/resources/META-INF/NOTICE b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api-nar/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index f4828546c5..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api-nar/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,30 +0,0 @@
-nifi-metrics-reporter-service-api-nar
-Copyright 2015-2020 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-******************
-Apache Software License v2
-******************
-
-The following binary components are provided under the Apache Software License v2
-
- (ASLv2) Dropwizard Metrics
- The following NOTICE information applies:
- Metrics
- Copyright 2010-2013 Coda Hale and Yammer, Inc., 2014-2017 Dropwizard Team
- This product includes software developed by Coda Hale and Yammer, Inc.
-
- This product includes code derived from the JSR-166 project (ThreadLocalRandom, Striped64,
- LongAdder), which was released with the following comments:
-
- Written by Doug Lea with assistance from members of JCP JSR-166
- Expert Group and released to the public domain, as explained at
- http://creativecommons.org/publicdomain/zero/1.0/
-
- The derived work in the nifi-metrics module is adapted from
- https://github.com/dropwizard/metrics/blob/v2.2.0/metrics-core/src/main/java/com/yammer/metrics/core/VirtualMachineMetrics.java
- and can be found in
- nifi-commons/nifi-metrics/src/main/java/org/apache/nifi/metrics/jvm/JvmMetrics.java
- nifi-commons/nifi-metrics/src/main/java/org/apache/nifi/metrics/jvm/JmxJvmMetrics.java
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api/pom.xml b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api/pom.xml
deleted file mode 100644
index 9a9010aa03..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api/pom.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
- nifi-metrics-reporting-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- 4.0.0
-
- nifi-metrics-reporter-service-api
-
-
-
- org.apache.nifi
- nifi-metrics
-
-
-
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api/src/main/java/org/apache/nifi/metrics/reporting/reporter/service/MetricReporterService.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api/src/main/java/org/apache/nifi/metrics/reporting/reporter/service/MetricReporterService.java
deleted file mode 100644
index d87be15f83..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporter-service-api/src/main/java/org/apache/nifi/metrics/reporting/reporter/service/MetricReporterService.java
+++ /dev/null
@@ -1,40 +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.metrics.reporting.reporter.service;
-
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.ScheduledReporter;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.processor.exception.ProcessException;
-
-/**
- * An interface for controller services used by MetricsReportingTask. In order to report to a new
- * client, implement this interface and make sure to return the desired implementation of {@link ScheduledReporter}.
- *
- * @author Omer Hadari
- */
-public interface MetricReporterService extends ControllerService {
-
- /**
- * Create a reporter to a metric client (i.e. graphite).
- *
- * @param metricRegistry registry with the metrics to report.
- * @return an instance of the reporter.
- * @throws ProcessException if there was an error creating the reporter.
- */
- ScheduledReporter createReporter(MetricRegistry metricRegistry) throws ProcessException;
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-nar/pom.xml b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-nar/pom.xml
deleted file mode 100644
index d752cd98d6..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-nar/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- nifi-metrics-reporting-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- nar
- 4.0.0
-
- nifi-metrics-reporting-nar
-
-
-
- org.apache.nifi
- nifi-metrics-reporting-task
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-metrics-reporter-service-api-nar
- 2.0.0-SNAPSHOT
- nar
-
-
-
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-nar/src/main/resources/META-INF/NOTICE b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-nar/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index 1eaddb63f7..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-nar/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,30 +0,0 @@
-nifi-metrics-reporting-nar
-Copyright 2015-2020 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-******************
-Apache Software License v2
-******************
-
-The following binary components are provided under the Apache Software License v2
-
- (ASLv2) Dropwizard Metrics
- The following NOTICE information applies:
- Metrics
- Copyright 2010-2013 Coda Hale and Yammer, Inc., 2014-2017 Dropwizard Team
- This product includes software developed by Coda Hale and Yammer, Inc.
-
- This product includes code derived from the JSR-166 project (ThreadLocalRandom, Striped64,
- LongAdder), which was released with the following comments:
-
- Written by Doug Lea with assistance from members of JCP JSR-166
- Expert Group and released to the public domain, as explained at
- http://creativecommons.org/publicdomain/zero/1.0/
-
- The derived work in the nifi-metrics module is adapted from
- https://github.com/dropwizard/metrics/blob/v2.2.0/metrics-core/src/main/java/com/yammer/metrics/core/VirtualMachineMetrics.java
- and can be found in
- nifi-commons/nifi-metrics/src/main/java/org/apache/nifi/metrics/jvm/JvmMetrics.java
- nifi-commons/nifi-metrics/src/main/java/org/apache/nifi/metrics/jvm/JmxJvmMetrics.java
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/pom.xml b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/pom.xml
deleted file mode 100644
index ad21f118f3..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
- nifi-metrics-reporting-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- 4.0.0
-
- nifi-metrics-reporting-task
-
-
-
- org.apache.nifi
- nifi-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-metrics-reporter-service-api
- 2.0.0-SNAPSHOT
- provided
-
-
- io.dropwizard.metrics
- metrics-graphite
- 4.2.19
-
-
- org.apache.nifi
- nifi-metrics
-
-
- org.apache.nifi
- nifi-mock
- 2.0.0-SNAPSHOT
- test
-
-
-
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/FlowMetricSet.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/FlowMetricSet.java
deleted file mode 100644
index d6e2fbab8c..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/FlowMetricSet.java
+++ /dev/null
@@ -1,95 +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.metrics;
-
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.Metric;
-import com.codahale.metrics.MetricSet;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.controller.status.ProcessorStatus;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * A metric set of NiFi instance related metrics.
- *
- * @author Omer Hadari
- */
-public class FlowMetricSet implements MetricSet {
-
-
- /**
- * Reference to the process status that should be reported. Should be updated when the status changes.
- */
- private final AtomicReference currentStatusReference;
-
- /**
- * Create a metric set that will look at a given process status reference for deciding metrics.
- *
- * @param currentStatusReference a reference to the process status.
- */
- public FlowMetricSet(AtomicReference currentStatusReference) {
- this.currentStatusReference = currentStatusReference;
- }
-
- /**
- * Create a map of {@link Gauge}s for the {@link #currentStatusReference}. This methods reports the metrics as
- * found in the reference.
- *
- * @return map between the metric name and a {@link Gauge} to it's value.
- */
- @Override
- public Map getMetrics() {
-
- Map metrics = new HashMap<>();
-
- metrics.put(MetricNames.ACTIVE_THREADS, (Gauge) () -> currentStatusReference.get().getActiveThreadCount());
- metrics.put(MetricNames.BYTES_QUEUED, (Gauge) () -> currentStatusReference.get().getQueuedContentSize());
- metrics.put(MetricNames.BYTES_READ, (Gauge) () -> currentStatusReference.get().getBytesRead());
- metrics.put(MetricNames.BYTES_RECEIVED, (Gauge) () -> currentStatusReference.get().getBytesReceived());
- metrics.put(MetricNames.BYTES_SENT, (Gauge) () -> currentStatusReference.get().getBytesSent());
- metrics.put(MetricNames.BYTES_WRITTEN, (Gauge) () -> currentStatusReference.get().getBytesWritten());
- metrics.put(MetricNames.FLOW_FILES_RECEIVED, (Gauge) () -> currentStatusReference.get().getFlowFilesReceived());
- metrics.put(MetricNames.FLOW_FILES_QUEUED, (Gauge) () -> currentStatusReference.get().getQueuedCount());
- metrics.put(MetricNames.FLOW_FILES_SENT, (Gauge) () -> currentStatusReference.get().getFlowFilesSent());
- metrics.put(MetricNames.TOTAL_TASK_DURATION_NANOS, (Gauge) () -> calculateProcessingNanos(currentStatusReference.get()));
-
- return metrics;
- }
-
- /**
- * Calculate the total processing time of a process group.
- *
- * @param status the current process group status.
- * @return the total amount of nanoseconds spent in each processor in the process group.
- */
- private long calculateProcessingNanos(final ProcessGroupStatus status) {
- long nanos = 0L;
-
- for (final ProcessorStatus procStats : status.getProcessorStatus()) {
- nanos += procStats.getProcessingNanos();
- }
-
- for (final ProcessGroupStatus childGroupStatus : status.getProcessGroupStatus()) {
- nanos += calculateProcessingNanos(childGroupStatus);
- }
-
- return nanos;
- }
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/MetricNames.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/MetricNames.java
deleted file mode 100644
index fa06b8b984..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/MetricNames.java
+++ /dev/null
@@ -1,35 +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.metrics;
-
-/**
- * The Metric names to send to Ambari.
- */
-public interface MetricNames {
-
- // NiFi Metrics
- String FLOW_FILES_RECEIVED = "FlowFilesReceivedLast5Minutes";
- String BYTES_RECEIVED = "BytesReceivedLast5Minutes";
- String FLOW_FILES_SENT = "FlowFilesSentLast5Minutes";
- String BYTES_SENT = "BytesSentLast5Minutes";
- String FLOW_FILES_QUEUED = "FlowFilesQueued";
- String BYTES_QUEUED = "BytesQueued";
- String BYTES_READ = "BytesReadLast5Minutes";
- String BYTES_WRITTEN = "BytesWrittenLast5Minutes";
- String ACTIVE_THREADS = "ActiveThreads";
- String TOTAL_TASK_DURATION_NANOS = "TotalTaskDurationNanoSeconds";
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/reporting/reporter/service/GraphiteMetricReporterService.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/reporting/reporter/service/GraphiteMetricReporterService.java
deleted file mode 100644
index 32c644938d..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/reporting/reporter/service/GraphiteMetricReporterService.java
+++ /dev/null
@@ -1,181 +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.metrics.reporting.reporter.service;
-
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.ScheduledReporter;
-import com.codahale.metrics.graphite.Graphite;
-import com.codahale.metrics.graphite.GraphiteReporter;
-import com.codahale.metrics.graphite.GraphiteSender;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnDisabled;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.controller.AbstractControllerService;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.expression.ExpressionLanguageScope;
-import org.apache.nifi.metrics.reporting.task.MetricsReportingTask;
-import org.apache.nifi.processor.util.StandardValidators;
-
-import javax.net.SocketFactory;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A controller service that provides metric reporters for graphite, can be used by {@link MetricsReportingTask}.
- *
- * @author Omer Hadari
- */
-@Tags({"metrics", "reporting", "graphite"})
-@CapabilityDescription("A controller service that provides metric reporters for graphite. " +
- "Used by MetricsReportingTask.")
-public class GraphiteMetricReporterService extends AbstractControllerService implements MetricReporterService {
-
- /**
- * Points to the hostname of the graphite listener.
- */
- public static final PropertyDescriptor HOST = new PropertyDescriptor.Builder()
- .name("host")
- .displayName("Host")
- .description("The hostname of the carbon listener")
- .required(true)
- .addValidator(StandardValidators.URI_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .build();
-
- /**
- * Points to the port on which the graphite server listens.
- */
- public static final PropertyDescriptor PORT = new PropertyDescriptor.Builder()
- .name("port")
- .displayName("Port")
- .description("The port on which carbon listens")
- .required(true)
- .addValidator(StandardValidators.PORT_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .build();
-
- /**
- * Points to the charset name that the graphite server expects.
- */
- public static final PropertyDescriptor CHARSET = new PropertyDescriptor.Builder()
- .name("charset")
- .displayName("Charset")
- .description("The charset used by the graphite server")
- .required(true)
- .defaultValue("UTF-8")
- .addValidator(StandardValidators.CHARACTER_SET_VALIDATOR)
- .build();
-
- /**
- * Prefix for all metric names sent by reporters - for separation of NiFi stats in graphite.
- */
- protected static final PropertyDescriptor METRIC_NAME_PREFIX = new PropertyDescriptor.Builder()
- .name("metric name prefix")
- .displayName("Metric Name Prefix")
- .description("A prefix that will be used for all metric names sent by reporters provided by this service.")
- .required(true)
- .defaultValue("nifi")
- .addValidator(StandardValidators.NON_BLANK_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .build();
-
- /**
- * List of property descriptors used by the service.
- */
- private static final List properties;
-
- static {
- final List props = new ArrayList<>();
- props.add(HOST);
- props.add(PORT);
- props.add(CHARSET);
- props.add(METRIC_NAME_PREFIX);
- properties = Collections.unmodifiableList(props);
- }
-
- /**
- * Graphite sender, a connection to the server.
- */
- private GraphiteSender graphiteSender;
-
- /**
- * The configured {@link #METRIC_NAME_PREFIX} value.
- */
- private String metricNamePrefix;
-
- /**
- * Create the {@link #graphiteSender} according to configuration.
- *
- * @param context used to access properties.
- */
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) {
- String host = context.getProperty(HOST).evaluateAttributeExpressions().getValue();
- int port = context.getProperty(PORT).evaluateAttributeExpressions().asInteger();
- Charset charset = Charset.forName(context.getProperty(CHARSET).getValue());
- graphiteSender = createSender(host, port, charset);
- metricNamePrefix = context.getProperty(METRIC_NAME_PREFIX).evaluateAttributeExpressions().getValue();
- }
-
- /**
- * Close the graphite sender.
- *
- * @throws IOException if failed to close the connection.
- */
- @OnDisabled
- public void shutdown() throws IOException {
- try {
- graphiteSender.close();
- } finally {
- graphiteSender = null;
- }
- }
-
- /**
- * Use the {@link #graphiteSender} in order to create a reporter.
- *
- * @param metricRegistry registry with the metrics to report.
- * @return a reporter instance.
- */
- @Override
- public ScheduledReporter createReporter(MetricRegistry metricRegistry) {
- return GraphiteReporter.forRegistry(metricRegistry).prefixedWith(metricNamePrefix).build(graphiteSender);
-
- }
-
- /**
- * Create a sender.
- *
- * @param host the hostname of the server to connect to.
- * @param port the port on which the server listens.
- * @param charset the charset in which the server expects logs.
- * @return The created sender.
- */
- protected GraphiteSender createSender(String host, int port, Charset charset) {
- return new Graphite(host, port, SocketFactory.getDefault(), charset);
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return properties;
- }
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/reporting/task/MetricsReportingTask.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/reporting/task/MetricsReportingTask.java
deleted file mode 100644
index dfd6f7916b..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/java/org/apache/nifi/metrics/reporting/task/MetricsReportingTask.java
+++ /dev/null
@@ -1,152 +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.metrics.reporting.task;
-
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.ScheduledReporter;
-import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnScheduled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.expression.ExpressionLanguageScope;
-import org.apache.nifi.metrics.FlowMetricSet;
-import org.apache.nifi.metrics.reporting.reporter.service.MetricReporterService;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.reporting.AbstractReportingTask;
-import org.apache.nifi.reporting.ReportingContext;
-import org.apache.nifi.reporting.ReportingInitializationContext;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * A reporting task for NiFi instance and JVM related metrics.
- *
- * This task reports metrics to services according to a provided {@link ScheduledReporter}, reached by using a
- * {@link MetricReporterService}. In order to report to different clients, simply use different implementations of
- * the controller service.
- *
- * @author Omer Hadari
- * @see MetricReporterService
- */
-@Tags({"metrics", "reporting"})
-@CapabilityDescription("This reporting task reports a set of metrics regarding the JVM and the NiFi instance" +
- "to a reporter. The reporter is provided by a MetricReporterService. It can be optionally used for a specific" +
- "process group if a property with the group id is provided.")
-public class MetricsReportingTask extends AbstractReportingTask {
-
- /**
- * Points to the service which provides {@link ScheduledReporter} instances.
- */
- protected static final PropertyDescriptor REPORTER_SERVICE = new PropertyDescriptor.Builder()
- .name("metric reporter service")
- .displayName("Metric Reporter Service")
- .description("The service that provides a reporter for the gathered metrics")
- .identifiesControllerService(MetricReporterService.class)
- .required(true)
- .build();
-
- /**
- * Metrics of the process group with this ID should be reported. If not specified, use the root process group.
- */
- protected static final PropertyDescriptor PROCESS_GROUP_ID = new PropertyDescriptor.Builder()
- .name("process group id")
- .displayName("Process Group ID")
- .description("The id of the process group to report. If not specified, metrics of the root process group" +
- "are reported.")
- .required(false)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .build();
-
- /**
- * Contains the metrics that should be reported.
- */
- private MetricRegistry metricRegistry;
-
- /**
- * Used for actually reporting metrics.
- */
- private ScheduledReporter reporter;
-
- // Protected for testing sake. DO NOT ACCESS FOR OTHER PURPOSES.
- /**
- * Points to the most recent process group status seen by this task.
- */
- protected AtomicReference currentStatusReference;
-
- /**
- * Register all wanted metrics to {@link #metricRegistry}.
- *
- * {@inheritDoc}
- */
- @Override
- protected void init(ReportingInitializationContext config) {
- metricRegistry = new MetricRegistry();
- currentStatusReference = new AtomicReference<>();
- metricRegistry.registerAll(new MemoryUsageGaugeSet());
- metricRegistry.registerAll(new FlowMetricSet(currentStatusReference));
- }
-
- /**
- * Populate {@link #reporter} using the {@link MetricReporterService}. If the reporter is active already,
- * do nothing.
- *
- * @param context used for accessing the controller service.
- */
- @OnScheduled
- public void connect(ConfigurationContext context) {
- if (reporter == null) {
- reporter = ((MetricReporterService) context.getProperty(REPORTER_SERVICE).asControllerService())
- .createReporter(metricRegistry);
- }
- }
-
- /**
- * Report the registered metrics.
- *
- * @param context used for getting the most recent {@link ProcessGroupStatus}.
- */
- @Override
- public void onTrigger(ReportingContext context) {
- String groupId = context.getProperty(PROCESS_GROUP_ID).evaluateAttributeExpressions().getValue();
-
- ProcessGroupStatus statusToReport = groupId == null
- ? context.getEventAccess().getControllerStatus()
- : context.getEventAccess().getGroupStatus(groupId);
-
- if (statusToReport != null) {
- currentStatusReference.set(statusToReport);
- reporter.report();
- } else {
- getLogger().error("Process group with provided group id could not be found.");
- }
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- List properties = new ArrayList<>();
- properties.add(REPORTER_SERVICE);
- properties.add(PROCESS_GROUP_ID);
- return Collections.unmodifiableList(properties);
- }
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
deleted file mode 100644
index 0ddc70ac8e..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
+++ /dev/null
@@ -1,15 +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.
-org.apache.nifi.metrics.reporting.reporter.service.GraphiteMetricReporterService
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/resources/META-INF/services/org.apache.nifi.reporting.ReportingTask b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/resources/META-INF/services/org.apache.nifi.reporting.ReportingTask
deleted file mode 100644
index 8c554a4252..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/main/resources/META-INF/services/org.apache.nifi.reporting.ReportingTask
+++ /dev/null
@@ -1,15 +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.
-org.apache.nifi.metrics.reporting.task.MetricsReportingTask
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/test/java/org/apache/nifi/metrics/reporting/reporter/service/GraphiteMetricReporterServiceTest.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/test/java/org/apache/nifi/metrics/reporting/reporter/service/GraphiteMetricReporterServiceTest.java
deleted file mode 100644
index dff6ca7780..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/test/java/org/apache/nifi/metrics/reporting/reporter/service/GraphiteMetricReporterServiceTest.java
+++ /dev/null
@@ -1,209 +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.metrics.reporting.reporter.service;
-
-import com.codahale.metrics.Gauge;
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.ScheduledReporter;
-import com.codahale.metrics.graphite.GraphiteSender;
-import org.apache.nifi.processor.Processor;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-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.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-
-/**
- * Test class for {@link GraphiteMetricReporterService}.
- *
- * @author Omer Hadari
- */
-@ExtendWith(MockitoExtension.class)
-public class GraphiteMetricReporterServiceTest {
-
- /**
- * Service identifier for registerting the tested service to the tests runner.
- */
- private static final String SERVICE_IDENTIFIER = "graphite-metric-reporter-service";
-
- /**
- * Sample host name for the {@link GraphiteMetricReporterService#HOST} property.
- */
- private static final String TEST_HOST = "some-host";
-
- /**
- * Sample port for the {@link GraphiteMetricReporterService#PORT} property.
- */
- private static final int TEST_PORT = 12345;
-
- /**
- * Sample charset for the {@link GraphiteMetricReporterService#CHARSET} property.
- */
- private static final Charset TEST_CHARSET = StandardCharsets.UTF_16LE;
-
- /**
- * Sample prefix for metric names.
- */
- private static final String METRIC_NAMES_PREFIX = "test-metric-name-prefix";
-
- /**
- * Sample metric for verifying that a graphite sender with the correct configuration is used.
- */
- private static final String TEST_METRIC_NAME = "test-metric";
-
- /**
- * The fixed value of {@link #TEST_METRIC_NAME}.
- */
- private static final int TEST_METRIC_VALUE = 2;
-
- /**
- * Dummy processor for creating {@link #runner}.
- */
- @Mock
- private Processor processorDummy;
-
- /**
- * Mock sender for verifying creation with the correct configuration.
- */
- @Mock
- private GraphiteSender graphiteSenderMock;
-
- /**
- * Stub metric registry, that contains the test metrics.
- */
- private MetricRegistry metricRegistryStub;
-
- /**
- * Test runner for activating and configuring the service.
- */
- private TestRunner runner;
-
- /**
- * The test subject.
- */
- private GraphiteMetricReporterService testedService;
-
- /**
- * Instantiate the runner and mocks between tests. Register metrics to the {@link #metricRegistryStub}.
- */
- @BeforeEach
- public void setUp() throws Exception {
- runner = TestRunners.newTestRunner(processorDummy);
- testedService = new GraphiteMetricReporterService();
-
- metricRegistryStub = new MetricRegistry();
- metricRegistryStub.register(TEST_METRIC_NAME, ((Gauge) () -> TEST_METRIC_VALUE));
-
- }
-
-
- /**
- * Make sure that a correctly configured service can be activated.
- */
- @Test
- public void testGraphiteMetricReporterSanityConfiguration() throws Exception {
- runner.addControllerService(SERVICE_IDENTIFIER, testedService);
- setServiceProperties(TEST_HOST, TEST_PORT, TEST_CHARSET, METRIC_NAMES_PREFIX);
- runner.enableControllerService(testedService);
-
- runner.assertValid(testedService);
- }
-
-
- /**
- * Make sure that a correctly configured service provides a reporter for the matching configuration, and
- * actually reports to the correct address.
- */
- @Test
- public void testCreateReporterUsesCorrectSender() throws Exception {
- testedService = new TestableGraphiteMetricReporterService();
- runner.addControllerService(SERVICE_IDENTIFIER, testedService);
- setServiceProperties(TEST_HOST, TEST_PORT, TEST_CHARSET, METRIC_NAMES_PREFIX);
- runner.enableControllerService(testedService);
-
- ScheduledReporter createdReporter = testedService.createReporter(metricRegistryStub);
- createdReporter.report();
-
- String expectedMetricName = MetricRegistry.name(METRIC_NAMES_PREFIX, TEST_METRIC_NAME);
- verify(graphiteSenderMock).send(eq(expectedMetricName), eq(String.valueOf(TEST_METRIC_VALUE)), anyLong());
- }
-
- /**
- * Make sure that {@link GraphiteMetricReporterService#shutdown()} closes the connection to graphite.
- */
- @Test
- public void testShutdownClosesSender() throws Exception {
- testedService = new TestableGraphiteMetricReporterService();
- runner.addControllerService(SERVICE_IDENTIFIER, testedService);
- setServiceProperties(TEST_HOST, TEST_PORT, TEST_CHARSET, METRIC_NAMES_PREFIX);
- runner.enableControllerService(testedService);
- runner.disableControllerService(testedService);
-
- verify(graphiteSenderMock).close();
- }
-
- /**
- * Set the test subject's properties.
- *
- * @param host populates {@link GraphiteMetricReporterService#HOST}.
- * @param port populates {@link GraphiteMetricReporterService#PORT}.
- * @param charset populates {@link GraphiteMetricReporterService#CHARSET}.
- * @param metricNamesPrefix populates {@link GraphiteMetricReporterService#METRIC_NAME_PREFIX}.
- */
- private void setServiceProperties(String host, int port, Charset charset, String metricNamesPrefix) {
- runner.setProperty(testedService, GraphiteMetricReporterService.HOST, host);
- runner.setProperty(testedService, GraphiteMetricReporterService.PORT, String.valueOf(port));
- runner.setProperty(testedService, GraphiteMetricReporterService.CHARSET, charset.name());
- runner.setProperty(testedService, GraphiteMetricReporterService.METRIC_NAME_PREFIX, metricNamesPrefix);
- }
-
- /**
- * This class is a patch. It overrides {@link GraphiteMetricReporterService#createSender(String, int, Charset)}
- * so that it is possible to verify a correct creation of graphite senders according to property values.
- */
- private class TestableGraphiteMetricReporterService extends GraphiteMetricReporterService {
-
- /**
- * Overrides the actual methods in order to inject the mock {@link #graphiteSenderMock}.
- *
- * If this method is called with the test property values, it returns the mock. Otherwise operate
- * regularly.
- *
- * @param host the provided hostname.
- * @param port the provided port.
- * @param charset the provided graphite server charset.
- * @return {@link #graphiteSenderMock} if all params were the constant test params, regular result otherwise.
- */
- @Override
- protected GraphiteSender createSender(String host, int port, Charset charset) {
- if (TEST_HOST.equals(host) && TEST_PORT == port && TEST_CHARSET.equals(charset)) {
- return graphiteSenderMock;
-
- }
- return super.createSender(host, port, charset);
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/test/java/org/apache/nifi/metrics/reporting/task/MetricsReportingTaskTest.java b/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/test/java/org/apache/nifi/metrics/reporting/task/MetricsReportingTaskTest.java
deleted file mode 100644
index 22f1385d16..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/nifi-metrics-reporting-task/src/test/java/org/apache/nifi/metrics/reporting/task/MetricsReportingTaskTest.java
+++ /dev/null
@@ -1,256 +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.metrics.reporting.task;
-
-import com.codahale.metrics.Metric;
-import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.ScheduledReporter;
-import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.status.ProcessGroupStatus;
-import org.apache.nifi.metrics.FlowMetricSet;
-import org.apache.nifi.metrics.reporting.reporter.service.MetricReporterService;
-import org.apache.nifi.reporting.ReportingContext;
-import org.apache.nifi.reporting.ReportingInitializationContext;
-import org.apache.nifi.state.MockStateManager;
-import org.apache.nifi.util.MockComponentLog;
-import org.apache.nifi.util.MockConfigurationContext;
-import org.apache.nifi.util.MockReportingContext;
-import org.apache.nifi.util.MockReportingInitializationContext;
-import org.apache.nifi.util.MockVariableRegistry;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.junit.jupiter.MockitoSettings;
-import org.mockito.quality.Strictness;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Test class for {@link MetricsReportingTask}.
- *
- * @author Omer Hadari
- */
-@ExtendWith(MockitoExtension.class)
-@MockitoSettings(strictness = Strictness.LENIENT)
-public class MetricsReportingTaskTest {
-
- /**
- * Identifier for {@link #reporterServiceStub}.
- */
- private static final String REPORTER_SERVICE_IDENTIFIER = "reporter-service";
-
- /**
- * Id for the group with status {@link #innerGroupStatus}.
- */
- private static final String TEST_GROUP_ID = "test-process-group-id";
-
- /**
- * Id for the {@link #reportingInitContextStub}.
- */
- private static final String TEST_INIT_CONTEXT_ID = "test-init-context-id";
-
- /**
- * Name for {@link #reportingInitContextStub}.
- */
- private static final String TEST_INIT_CONTEXT_NAME = "test-init-context-name";
-
- /**
- * Id for the tested tested reporting task.
- */
- private static final String TEST_TASK_ID = "test-task-id";
-
-
- /**
- * Stub context, used by {@link MetricsReportingTask#onTrigger(ReportingContext)} for reaching the status.
- */
- private MockReportingContext reportingContextStub;
-
- /**
- * Stub context, used by {@link MetricsReportingTask#connect(ConfigurationContext)} for reaching the service.
- */
- private MockConfigurationContext configurationContextStub;
-
- /**
- * Stub service for providing {@link #reporterMock}, used for actual reporting
- */
- @Mock
- private MetricReporterService reporterServiceStub;
-
- /**
- * Mock reporter, used for verifying actual reporting.
- */
- @Mock
- private ScheduledReporter reporterMock;
-
- /**
- * A status for the "root" process group.
- */
- private ProcessGroupStatus rootGroupStatus;
-
- /**
- * Same as {@link #rootGroupStatus}, used when {@link MetricsReportingTask#PROCESS_GROUP_ID} is set.
- */
- private ProcessGroupStatus innerGroupStatus;
-
- /**
- * Stub initialization context for calling {@link MetricsReportingTask#initialize(ReportingInitializationContext)}.
- */
- private MockReportingInitializationContext reportingInitContextStub;
-
- /**
- * The test subject.
- */
- private MetricsReportingTask testedReportingTask;
-
- /**
- * Set up the test environment and mock behaviour. This includes registering {@link #reporterServiceStub} in the
- * different contexts, overriding {@link MetricsReportingTask#currentStatusReference} and instantiating the test
- * subject.
- */
- @BeforeEach
- public void setUp() throws Exception {
- Map services = new HashMap<>();
- services.put(REPORTER_SERVICE_IDENTIFIER, reporterServiceStub);
- testedReportingTask = new MetricsReportingTask();
- reportingContextStub = new MockReportingContext(
- services, new MockStateManager(testedReportingTask), new MockVariableRegistry());
-
- rootGroupStatus = new ProcessGroupStatus();
- innerGroupStatus = new ProcessGroupStatus();
- when(reporterServiceStub.createReporter(any())).thenReturn(reporterMock);
- reportingContextStub.setProperty(MetricsReportingTask.REPORTER_SERVICE.getName(), REPORTER_SERVICE_IDENTIFIER);
- reportingContextStub.addControllerService(reporterServiceStub, REPORTER_SERVICE_IDENTIFIER);
-
- configurationContextStub = new MockConfigurationContext(reportingContextStub.getProperties(),
- reportingContextStub.getControllerServiceLookup());
- reportingInitContextStub = new MockReportingInitializationContext(
- TEST_INIT_CONTEXT_ID,
- TEST_INIT_CONTEXT_NAME,
- new MockComponentLog(TEST_TASK_ID, testedReportingTask));
- }
-
- /**
- * Make sure that in a single life cycle the correct metrics are registered, the correct {@link ProcessGroupStatus}
- * is used and that metrics are actually reported.
- */
- @Test
- public void testValidLifeCycleReportsCorrectly() throws Exception {
- reportingContextStub.getEventAccess().setProcessGroupStatus(rootGroupStatus);
-
- testedReportingTask.initialize(reportingInitContextStub);
- testedReportingTask.connect(configurationContextStub);
- testedReportingTask.onTrigger(reportingContextStub);
- verify(reporterMock).report();
-
- // Verify correct metrics are registered
- ArgumentCaptor registryCaptor = ArgumentCaptor.forClass(MetricRegistry.class);
- verify(reporterServiceStub).createReporter(registryCaptor.capture());
- MetricRegistry usedRegistry = registryCaptor.getValue();
- Map usedMetrics = usedRegistry.getMetrics();
- assertTrue(usedMetrics.keySet().containsAll(new MemoryUsageGaugeSet().getMetrics().keySet()));
- assertTrue(usedMetrics.keySet()
- .containsAll(new FlowMetricSet(testedReportingTask.currentStatusReference).getMetrics().keySet()));
-
- // Verify the most current ProcessGroupStatus is updated
- assertEquals(testedReportingTask.currentStatusReference.get(), rootGroupStatus);
- }
-
- /**
- * Make sure that in a single life cycle the correct metrics are registered, the correct {@link ProcessGroupStatus}
- * is used and that metrics are actually reported.
- */
- @Test
- public void testValidLifeCycleReportsCorrectlyProcessGroupSpecified() throws Exception {
- reportingContextStub.setProperty(MetricsReportingTask.PROCESS_GROUP_ID.getName(), TEST_GROUP_ID);
- reportingContextStub.getEventAccess().setProcessGroupStatus(TEST_GROUP_ID, innerGroupStatus);
-
- testedReportingTask.initialize(reportingInitContextStub);
- testedReportingTask.connect(configurationContextStub);
- testedReportingTask.onTrigger(reportingContextStub);
- verify(reporterMock).report();
-
- // Verify correct metrics are registered
- ArgumentCaptor registryCaptor = ArgumentCaptor.forClass(MetricRegistry.class);
- verify(reporterServiceStub).createReporter(registryCaptor.capture());
- MetricRegistry usedRegistry = registryCaptor.getValue();
- Map usedMetrics = usedRegistry.getMetrics();
- assertTrue(usedMetrics.keySet().containsAll(new MemoryUsageGaugeSet().getMetrics().keySet()));
- assertTrue(usedMetrics.keySet()
- .containsAll(new FlowMetricSet(testedReportingTask.currentStatusReference).getMetrics().keySet()));
-
- // Verify the most current ProcessGroupStatus is updated
- assertEquals(testedReportingTask.currentStatusReference.get(), innerGroupStatus);
- }
-
- /**
- * Make sure that in a single life cycle the correct metrics are registered, the correct {@link ProcessGroupStatus}
- * is used and that metrics are actually reported.
- */
- @Test
- public void testInvalidProcessGroupId() throws Exception {
- reportingContextStub.setProperty(MetricsReportingTask.PROCESS_GROUP_ID.getName(), TEST_GROUP_ID + "-invalid");
- reportingContextStub.getEventAccess().setProcessGroupStatus(TEST_GROUP_ID, innerGroupStatus);
-
- testedReportingTask.initialize(reportingInitContextStub);
- testedReportingTask.connect(configurationContextStub);
- testedReportingTask.onTrigger(reportingContextStub);
- verify(reporterMock, never()).report();
- assertNull(testedReportingTask.currentStatusReference.get());
- }
-
- /**
- * Make sure that {@link MetricsReportingTask#connect(ConfigurationContext)} does not create a new reporter
- * if there is already an active reporter.
- */
- @Test
- public void testConnectCreatesSingleReporter() throws Exception {
- testedReportingTask.initialize(reportingInitContextStub);
- testedReportingTask.connect(configurationContextStub);
- testedReportingTask.connect(configurationContextStub);
-
- verify(reporterServiceStub, times(1)).createReporter(any());
- }
-
- /**
- * Sanity check for registered properties.
- */
- @Test
- public void testGetSupportedPropertyDescriptorsSanity() throws Exception {
- List expected = Arrays.asList(
- MetricsReportingTask.REPORTER_SERVICE,
- MetricsReportingTask.PROCESS_GROUP_ID);
- assertEquals(expected, testedReportingTask.getSupportedPropertyDescriptors());
- }
-}
diff --git a/nifi-nar-bundles/nifi-metrics-reporting-bundle/pom.xml b/nifi-nar-bundles/nifi-metrics-reporting-bundle/pom.xml
deleted file mode 100644
index 585e3a3f7e..0000000000
--- a/nifi-nar-bundles/nifi-metrics-reporting-bundle/pom.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
- nifi-nar-bundles
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- 4.0.0
-
- nifi-metrics-reporting-bundle
- pom
-
- nifi-metrics-reporting-task
- nifi-metrics-reporting-nar
- nifi-metrics-reporter-service-api
- nifi-metrics-reporter-service-api-nar
-
-
-
-
-
- org.apache.nifi
- nifi-metrics
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-metrics-reporting-task
- 2.0.0-SNAPSHOT
-
-
-
-
-
-
- org.apache.nifi
- nifi-api
- provided
-
-
-
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml
deleted file mode 100644
index 7dacd82026..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
- 4.0.0
-
- nifi-riemann-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
-
- true
- true
-
-
- nifi-riemann-nar
- nar
-
-
- org.apache.nifi
- nifi-riemann-processors
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/src/main/resources/META-INF/NOTICE b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/src/main/resources/META-INF/NOTICE
deleted file mode 100644
index 603d4bfa33..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-nar/src/main/resources/META-INF/NOTICE
+++ /dev/null
@@ -1,19 +0,0 @@
-nifi-riemann-nar
-Copyright 2014-2023 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-===========================================
-Apache Software License v2
-===========================================
-
-The following binary components are provided under the Apache Software License v2
-
- (ASLv2) Apache Commons Lang
- The following NOTICE information applies:
- Apache Commons Lang
- Copyright 2001-2015 The Apache Software Foundation
-
- This product includes software from the Spring Framework,
- under the Apache License 2.0 (see: StringUtils.containsWhitespace())
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml
deleted file mode 100644
index b5bf2252c4..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/pom.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-riemann-bundle
- 2.0.0-SNAPSHOT
-
-
- nifi-riemann-processors
-
-
-
- io.riemann
- riemann-java-client
-
-
- org.apache.nifi
- nifi-api
-
-
- org.apache.nifi
- nifi-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-properties
-
-
- org.apache.commons
- commons-lang3
-
-
- org.apache.nifi
- nifi-mock
- 2.0.0-SNAPSHOT
- test
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/main/java/org/apache/nifi/processors/riemann/PutRiemann.java b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/main/java/org/apache/nifi/processors/riemann/PutRiemann.java
deleted file mode 100644
index d9a54d0af8..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/main/java/org/apache/nifi/processors/riemann/PutRiemann.java
+++ /dev/null
@@ -1,382 +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.processors.riemann;
-
-import io.riemann.riemann.Proto;
-import io.riemann.riemann.Proto.Event;
-import io.riemann.riemann.client.RiemannClient;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.annotation.behavior.DynamicProperty;
-import org.apache.nifi.annotation.behavior.InputRequirement;
-import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
-import org.apache.nifi.annotation.behavior.SupportsBatching;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnScheduled;
-import org.apache.nifi.annotation.lifecycle.OnStopped;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.components.Validator;
-import org.apache.nifi.expression.ExpressionLanguageScope;
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.processor.AbstractProcessor;
-import org.apache.nifi.processor.ProcessContext;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.Relationship;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.processor.util.StandardValidators;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-@Tags({"riemann", "monitoring", "metrics"})
-@DynamicProperty(name = "Custom Event Attribute", expressionLanguageScope = ExpressionLanguageScope.FLOWFILE_ATTRIBUTES,
- description = "These values will be attached to the Riemann event as a custom attribute",
- value = "Any value or expression")
-@CapabilityDescription("Send events to Riemann (http://riemann.io) when FlowFiles pass through this processor. " +
- "You can use events to notify Riemann that a FlowFile passed through, or you can attach a more " +
- "meaningful metric, such as, the time a FlowFile took to get to this processor. All attributes attached to " +
- "events support the NiFi Expression Language.")
-@SupportsBatching
-@InputRequirement(Requirement.INPUT_REQUIRED)
-public class PutRiemann extends AbstractProcessor {
- protected enum Transport {
- TCP, UDP
- }
-
- protected volatile RiemannClient riemannClient = null;
- protected volatile Transport transport;
-
- public static final Relationship REL_SUCCESS = new Relationship.Builder()
- .name("success")
- .description("Metrics successfully written to Riemann")
- .build();
-
- public static final Relationship REL_FAILURE = new Relationship.Builder()
- .name("failure")
- .description("Metrics which failed to write to Riemann")
- .build();
-
-
- public static final PropertyDescriptor RIEMANN_HOST = new PropertyDescriptor.Builder()
- .name("Riemann Address")
- .description("Hostname of Riemann server")
- .required(true)
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .build();
-
- public static final PropertyDescriptor RIEMANN_PORT = new PropertyDescriptor.Builder()
- .name("Riemann Port")
- .description("Port that Riemann is listening on")
- .required(true)
- .defaultValue("5555")
- .addValidator(StandardValidators.PORT_VALIDATOR)
- .build();
-
- public static final PropertyDescriptor TRANSPORT_PROTOCOL = new PropertyDescriptor.Builder()
- .name("Transport Protocol")
- .description("Transport protocol to speak to Riemann in")
- .required(true)
- .allowableValues(new Transport[]{Transport.TCP, Transport.UDP})
- .defaultValue("TCP")
- .build();
-
- public static final PropertyDescriptor BATCH_SIZE = new PropertyDescriptor.Builder()
- .name("Batch Size")
- .description("Batch size for incoming FlowFiles")
- .required(false)
- .defaultValue("100")
- .addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
- .build();
-
- // Attributes Mappings
- public static final PropertyDescriptor ATTR_SERVICE = new PropertyDescriptor.Builder()
- .name("Service")
- .description("Name of service associated to this event (e.g. FTP File Fetched)")
- .required(false)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .build();
-
- public static final PropertyDescriptor ATTR_STATE = new PropertyDescriptor.Builder()
- .name("State")
- .description("State of service associated to this event in string form (e.g. ok, warning, foo)")
- .required(false)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .build();
-
- public static final PropertyDescriptor ATTR_TIME = new PropertyDescriptor.Builder()
- .name("Time")
- .description("Time of event in unix epoch seconds (long), default: (current time)")
- .required(false)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .build();
-
- public static final PropertyDescriptor ATTR_HOST = new PropertyDescriptor.Builder()
- .name("Host")
- .description("A hostname associated to this event (e.g. nifi-app1)")
- .required(false)
- .defaultValue("${hostname()}")
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .build();
-
- public static final PropertyDescriptor ATTR_TTL = new PropertyDescriptor.Builder()
- .name("TTL")
- .description("Floating point value in seconds until Riemann considers this event as \"expired\"")
- .required(false)
- .addValidator(Validator.VALID)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .build();
-
- public static final PropertyDescriptor ATTR_METRIC = new PropertyDescriptor.Builder()
- .name("Metric")
- .description("Floating point number associated to this event")
- .required(false)
- .addValidator(Validator.VALID)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .build();
-
- public static final PropertyDescriptor ATTR_DESCRIPTION = new PropertyDescriptor.Builder()
- .name("Description")
- .description("Description associated to the event")
- .required(false)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .build();
-
-
- public static final PropertyDescriptor ATTR_TAGS = new PropertyDescriptor.Builder()
- .name("Tags")
- .description("Comma separated list of tags associated to the event")
- .required(false)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .build();
-
- public static final PropertyDescriptor TIMEOUT = new PropertyDescriptor.Builder()
- .name("Timeout")
- .description("Timeout in milliseconds when writing events to Riemann")
- .required(true)
- .defaultValue("1000")
- .addValidator(StandardValidators.POSITIVE_LONG_VALIDATOR)
- .build();
-
- private volatile List customAttributes = new ArrayList<>();
- private static final Set RELATIONSHIPS = new HashSet<>();
- private static final List LOCAL_PROPERTIES = new ArrayList<>();
-
- private volatile int batchSize = -1;
- private volatile long writeTimeout = 1000;
-
- static {
- RELATIONSHIPS.add(REL_SUCCESS);
- RELATIONSHIPS.add(REL_FAILURE);
- LOCAL_PROPERTIES.add(RIEMANN_HOST);
- LOCAL_PROPERTIES.add(RIEMANN_PORT);
- LOCAL_PROPERTIES.add(TRANSPORT_PROTOCOL);
- LOCAL_PROPERTIES.add(TIMEOUT);
- LOCAL_PROPERTIES.add(BATCH_SIZE);
- LOCAL_PROPERTIES.add(ATTR_DESCRIPTION);
- LOCAL_PROPERTIES.add(ATTR_SERVICE);
- LOCAL_PROPERTIES.add(ATTR_STATE);
- LOCAL_PROPERTIES.add(ATTR_METRIC);
- LOCAL_PROPERTIES.add(ATTR_TTL);
- LOCAL_PROPERTIES.add(ATTR_TAGS);
- LOCAL_PROPERTIES.add(ATTR_HOST);
- LOCAL_PROPERTIES.add(ATTR_TIME);
- }
-
-
- @Override
- public Set getRelationships() {
- return RELATIONSHIPS;
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return LOCAL_PROPERTIES;
- }
-
- @Override
- protected PropertyDescriptor getSupportedDynamicPropertyDescriptor(final String propertyDescriptorName) {
- return new PropertyDescriptor.Builder()
- .name(propertyDescriptorName)
- .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
- .addValidator(Validator.VALID)
- .required(false)
- .dynamic(true)
- .build();
- }
-
- @OnStopped
- public final void cleanUpClient() {
- if (riemannClient != null) {
- this.riemannClient.close();
- }
- this.riemannClient = null;
- this.batchSize = -1;
- this.customAttributes.clear();
- }
-
- @OnScheduled
- public void onScheduled(ProcessContext context) throws ProcessException {
- if (batchSize == -1) {
- batchSize = context.getProperty(BATCH_SIZE).asInteger();
- }
- if (riemannClient == null || !riemannClient.isConnected()) {
- transport = Transport.valueOf(context.getProperty(TRANSPORT_PROTOCOL).getValue());
- String host = context.getProperty(RIEMANN_HOST).getValue().trim();
- int port = context.getProperty(RIEMANN_PORT).asInteger();
- writeTimeout = context.getProperty(TIMEOUT).asLong();
- RiemannClient client = null;
- try {
- switch (transport) {
- case TCP:
- client = RiemannClient.tcp(host, port);
- break;
- case UDP:
- client = RiemannClient.udp(host, port);
- break;
- }
- client.connect();
- riemannClient = client;
- } catch (IOException e) {
- if (client != null) {
- client.close();
- }
- context.yield();
- throw new ProcessException(String.format("Unable to connect to Riemann [%s:%d] (%s)\n%s", host, port, transport, e.getMessage()));
- }
- }
-
- if (customAttributes.size() == 0) {
- for (Map.Entry property : context.getProperties().entrySet()) {
- // only custom defined properties
- if (!getSupportedPropertyDescriptors().contains(property.getKey())) {
- customAttributes.add(property.getKey());
- }
- }
- }
- }
-
-
- @Override
- public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
- // Check if the client is currently connected, as a previous trigger could have detected a failure
- // in the connection.
- if (riemannClient == null || !riemannClient.isConnected()) {
- // clean up the client and attempt to re-initialize the processor
- cleanUpClient();
- onScheduled(context);
- }
-
- List incomingFlowFiles = session.get(batchSize);
- List successfulFlowFiles = new ArrayList<>(incomingFlowFiles.size());
- List eventsQueue = new ArrayList<>(incomingFlowFiles.size());
- for (FlowFile flowFile : incomingFlowFiles) {
- try {
- eventsQueue.add(FlowFileToEvent.fromAttributes(context, customAttributes, flowFile));
- successfulFlowFiles.add(flowFile);
- } catch (NumberFormatException e) {
- getLogger().warn("Unable to create Riemann event.", e);
- session.transfer(flowFile, REL_FAILURE);
- }
- }
- try {
- if (transport == Transport.TCP) {
- Proto.Msg returnMessage = riemannClient.sendEvents(eventsQueue).deref(writeTimeout, TimeUnit.MILLISECONDS);
- if (returnMessage == null) {
- context.yield();
- throw new ProcessException("Timed out writing to Riemann!");
- }
- } else {
- riemannClient.sendEvents(eventsQueue);
- }
- riemannClient.flush();
- session.transfer(successfulFlowFiles, REL_SUCCESS);
- } catch (Exception e) {
- context.yield();
- session.transfer(incomingFlowFiles);
- throw new ProcessException("Failed writing to Riemann\n" + e.getMessage());
- }
- }
-
- /**
- * Converts a FlowFile into a Riemann Protobuf Event
- */
- private static class FlowFileToEvent {
- protected static Event fromAttributes(ProcessContext context, List customProperties,
- FlowFile flowFile) {
- Event.Builder builder = Event.newBuilder();
-
- PropertyValue service = context.getProperty(ATTR_SERVICE).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(service.getValue())) {
- builder.setService(service.getValue());
- }
- PropertyValue description = context.getProperty(ATTR_DESCRIPTION).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(description.getValue())) {
- builder.setDescription(description.getValue());
- }
- PropertyValue metric = context.getProperty(ATTR_METRIC).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(metric.getValue())) {
- builder.setMetricF(metric.asFloat());
- }
- PropertyValue time = context.getProperty(ATTR_TIME).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(time.getValue())) {
- builder.setTime(time.asLong());
- }
- PropertyValue state = context.getProperty(ATTR_STATE).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(state.getValue())) {
- builder.setState(state.getValue());
- }
- PropertyValue ttl = context.getProperty(ATTR_TTL).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(ttl.getValue())) {
- builder.setTtl(ttl.asFloat());
- }
- PropertyValue host = context.getProperty(ATTR_HOST).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(host.getValue())) {
- builder.setHost(host.getValue());
- }
- PropertyValue tags = context.getProperty(ATTR_TAGS).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(tags.getValue())) {
- String[] splitTags = tags.getValue().split(",");
- for (String splitTag : splitTags) {
- builder.addTags(splitTag.trim());
- }
- }
- PropertyValue customAttributeValue;
- for (PropertyDescriptor customProperty : customProperties) {
- customAttributeValue = context.getProperty(customProperty).evaluateAttributeExpressions(flowFile);
- if (StringUtils.isNotBlank(customAttributeValue.getValue())) {
- builder.addAttributes(Proto.Attribute.newBuilder()
- .setKey(customProperty.getName())
- .setValue(customAttributeValue.getValue())
- .build());
- }
- }
- return builder.build();
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
deleted file mode 100644
index c53cea64f2..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/main/resources/META-INF/services/org.apache.nifi.processor.Processor
+++ /dev/null
@@ -1,15 +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.
-org.apache.nifi.processors.riemann.PutRiemann
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/test/java/org/apache/nifi/processors/riemann/TestPutRiemann.java b/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/test/java/org/apache/nifi/processors/riemann/TestPutRiemann.java
deleted file mode 100644
index 7082b9c185..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/nifi-riemann-processors/src/test/java/org/apache/nifi/processors/riemann/TestPutRiemann.java
+++ /dev/null
@@ -1,188 +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.processors.riemann;
-
-import io.riemann.riemann.Proto;
-import io.riemann.riemann.client.IPromise;
-import io.riemann.riemann.client.RiemannClient;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.util.MockFlowFile;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyList;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class TestPutRiemann {
- // Holds incoming events to Riemann
- private Queue eventStream = new LinkedList();
-
- @BeforeEach
- public void clearEventStream() {
- eventStream.clear();
- }
-
- private TestRunner getTestRunner() {
- return getTestRunner(false);
- }
-
- private TestRunner getTestRunner(final boolean failOnWrite) {
- RiemannClient riemannClient = mock(RiemannClient.class);
- when(riemannClient.sendEvents(anyList())).thenAnswer(new Answer() {
- @Override
- public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
- List events = (List) invocationOnMock.getArguments()[0];
- for (Proto.Event event : events) {
- eventStream.add(event);
- }
- IPromise iPromise = mock(IPromise.class);
- if (!failOnWrite) {
- when(iPromise.deref(anyLong(), any(TimeUnit.class))).thenReturn(Proto.Msg.getDefaultInstance());
- } else {
- when(iPromise.deref(anyLong(), any(TimeUnit.class))).thenReturn(null);
- }
- return iPromise;
- }
- });
- when(riemannClient.isConnected()).thenReturn(true);
- PutRiemann riemannProcessor = new PutRiemann();
- riemannProcessor.riemannClient = riemannClient;
- riemannProcessor.transport = PutRiemann.Transport.TCP;
-
- TestRunner runner = TestRunners.newTestRunner(riemannProcessor);
- runner.setProperty(PutRiemann.RIEMANN_HOST, "localhost");
- runner.setProperty(PutRiemann.RIEMANN_PORT, "5555");
- runner.setProperty(PutRiemann.TRANSPORT_PROTOCOL, "TCP");
- runner.setProperty(PutRiemann.BATCH_SIZE, "100");
- runner.setProperty(PutRiemann.ATTR_SERVICE, "nifi-test-service");
- runner.setProperty(PutRiemann.ATTR_HOST, "${riemann.host}");
- runner.setProperty(PutRiemann.ATTR_TTL, "5");
- runner.setProperty(PutRiemann.ATTR_DESCRIPTION, "test");
- runner.setProperty(PutRiemann.ATTR_TAGS, "tag1, tag2, tag3");
- runner.setProperty(PutRiemann.ATTR_METRIC, "${riemann.metric}");
- runner.setProperty("custom-attribute-1", "${custom.attribute.1}");
- runner.setProperty("custom-attribute-2", "${custom.attribute.2}");
- runner.setProperty("custom-attribute-3", "${custom.attribute.3}");
- return runner;
- }
-
-
- @Test
- public void testBasicEvent() {
- TestRunner runner = getTestRunner();
- Map attributes = new HashMap<>();
- attributes.put("riemann.metric", "42");
- attributes.put("riemann.host", "basic-host");
- MockFlowFile flowFile = new MockFlowFile(1);
- flowFile.putAttributes(attributes);
- runner.enqueue(flowFile);
- runner.run();
- runner.assertAllFlowFilesTransferred(PutRiemann.REL_SUCCESS);
-
- Proto.Event event = eventStream.remove();
- assertEquals("nifi-test-service", event.getService());
- assertTrue(5.0 == event.getTtl());
- assertTrue(42.0 == event.getMetricF());
- assertEquals("basic-host", event.getHost());
- assertEquals("test", event.getDescription());
- assertEquals(3, event.getTagsCount());
- assertTrue(event.getTagsList().contains("tag1"));
- assertTrue(event.getTagsList().contains("tag2"));
- assertTrue(event.getTagsList().contains("tag3"));
- assertEquals(0, event.getAttributesCount());
- }
-
- @Test
- public void testBatchedEvents() {
- // (2 batches) + (1 remaining event)
- int iterations = Integer.parseInt(PutRiemann.BATCH_SIZE.getDefaultValue()) * 2 + 1;
- TestRunner runner = getTestRunner();
-
- for (int i = 0; i < iterations; i++) {
- Map attributes = new HashMap<>();
- attributes.put("riemann.metric", Float.toString(i));
- attributes.put("riemann.host", "batch-host");
- attributes.put("custom.attribute.1", "attr1");
- attributes.put("custom.attribute.2", "attr2");
- attributes.put("custom.attribute.3", "attr3");
- MockFlowFile flowFile = new MockFlowFile(i);
- flowFile.putAttributes(attributes);
- runner.enqueue(flowFile);
- }
- runner.run(3);
- runner.assertAllFlowFilesTransferred(PutRiemann.REL_SUCCESS);
-
- for (int i = 0; i < iterations; i++) {
- Proto.Event event = eventStream.remove();
- assertEquals("nifi-test-service", event.getService());
- assertTrue(5.0 == event.getTtl());
- assertTrue(i == event.getMetricF());
- assertEquals("batch-host", event.getHost());
- assertEquals("test", event.getDescription());
- assertEquals(3, event.getTagsCount());
- assertEquals(3, event.getAttributesCount());
- assertTrue(event.getTagsList().contains("tag1"));
- assertTrue(event.getTagsList().contains("tag2"));
- assertTrue(event.getTagsList().contains("tag3"));
- }
- }
-
- @Test
- public void testInvalidEvents() {
- TestRunner runner = getTestRunner();
- MockFlowFile flowFile = new MockFlowFile(1);
- Map attributes = new HashMap<>();
- attributes.put("riemann.metric", "NOT A NUMBER");
- flowFile.putAttributes(attributes);
- runner.enqueue(flowFile);
- runner.run();
- runner.assertAllFlowFilesTransferred(PutRiemann.REL_FAILURE);
- }
-
- @Test
- public void testFailedDeref() {
- TestRunner runner = getTestRunner(true);
- MockFlowFile flowFile = new MockFlowFile(1);
- Map attributes = new HashMap<>();
- attributes.put("riemann.metric", "5");
- flowFile.putAttributes(attributes);
- runner.enqueue(flowFile);
- try {
- assertThrows(AssertionError.class, () -> runner.run());
- } catch (ProcessException e) {
- runner.assertQueueNotEmpty();
- throw e;
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-riemann-bundle/pom.xml b/nifi-nar-bundles/nifi-riemann-bundle/pom.xml
deleted file mode 100644
index 810a66b81b..0000000000
--- a/nifi-nar-bundles/nifi-riemann-bundle/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
- 4.0.0
-
- nifi-nar-bundles
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- nifi-riemann-bundle
- pom
-
- nifi-riemann-processors
- nifi-riemann-nar
-
-
-
- clojars.org
- https://clojars.org/repo
-
-
-
-
-
- io.riemann
- riemann-java-client
- 0.5.3
-
-
- org.apache.nifi
- nifi-riemann-processors
- 2.0.0-SNAPSHOT
-
-
- com.google.protobuf
- protobuf-java
- 3.23.0
-
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/pom.xml b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/pom.xml
deleted file mode 100644
index 0157cec011..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/pom.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
- nifi-rules-action-handler-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- 4.0.0
-
- nifi-rules-action-handler-nar
- nar
-
- true
- true
-
-
-
- org.apache.nifi
- nifi-rules-action-handler-service
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-standard-services-api-nar
- 2.0.0-SNAPSHOT
- nar
-
-
-
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/src/main/resources/LICENSE b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/src/main/resources/LICENSE
deleted file mode 100644
index 1f84df0623..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/src/main/resources/LICENSE
+++ /dev/null
@@ -1,236 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed 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-rules-action-handler-nar includes subcomponents with separate copyright notices and
-license terms. Your use of these subcomponents is subject to the terms
-and conditions of the following licenses:
-
- The binary distribution of this product bundles the 'ASM' library which is available under a BSD style license.
-
- Copyright (c) 2000-2005 INRIA, France Telecom
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holders nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/src/main/resources/NOTICE b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/src/main/resources/NOTICE
deleted file mode 100644
index 1f8db995a4..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-nar/src/main/resources/NOTICE
+++ /dev/null
@@ -1,18 +0,0 @@
-nifi-rules-action-handler-nar
-Copyright 2014-2023 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-******************
-Apache Software License v2
-******************
-
-The following binary components are provided under the Apache Software License v2
-
- (ASLv2) MVEL (MVFLEX Expression Language)
-
- (ASLv2) Spring Framework (Core, Expression)
- The following NOTICE information applies:
- Spring Framework
- Copyright (c) 2002-2019 Pivotal, Inc.
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/pom.xml b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/pom.xml
deleted file mode 100644
index d7f1e5bf6e..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/pom.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
- nifi-rules-action-handler-bundle
- org.apache.nifi
- 2.0.0-SNAPSHOT
-
- 4.0.0
-
- nifi-rules-action-handler-service
- jar
-
-
- org.apache.nifi
- nifi-rules-engine-service-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-api
-
-
- org.apache.nifi
- nifi-record-sink-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-record
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-record-serialization-service-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.commons
- commons-lang3
-
-
- org.apache.nifi
- nifi-utils
- 2.0.0-SNAPSHOT
-
-
- org.mvel
- mvel2
- 2.5.0.Final
-
-
- org.springframework
- spring-expression
-
-
- org.apache.nifi
- nifi-mock
- test
-
-
-
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/AbstractActionHandlerService.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/AbstractActionHandlerService.java
deleted file mode 100644
index 4580ba07fe..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/AbstractActionHandlerService.java
+++ /dev/null
@@ -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.
- */
-package org.apache.nifi.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.controller.AbstractControllerService;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.expression.ExpressionLanguageScope;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.rules.PropertyContextActionHandler;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-public abstract class AbstractActionHandlerService extends AbstractControllerService implements PropertyContextActionHandler {
-
- protected List enforceActionTypes;
- protected EnforceActionTypeLevel enforceActionTypeLevel;
-
- public enum DebugLevels {
- trace, debug, info, warn, error
- }
-
- public enum EnforceActionTypeLevel {
- IGNORE, WARN, EXCEPTION
- }
-
- public static final PropertyDescriptor ENFORCE_ACTION_TYPE = new PropertyDescriptor.Builder()
- .name("action-handler-enforce-type")
- .displayName("Enforce Action Type")
- .required(false)
- .description("The Action Type(s) that should be supported by this handler. If provided any other type an " +
- "exception will be thrown. This can support a comma delimited list of types (e.g. ALERT,LOG)")
- .addValidator(StandardValidators.NON_BLANK_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .build();
-
- public static final PropertyDescriptor ENFORCE_ACTION_TYPE_LEVEL = new PropertyDescriptor.Builder()
- .name("action-handler-enforce-type-level")
- .displayName("Enforce Level")
- .required(false)
- .description("If specific action types are enforced, this setting specifies whether the action should be ignored," +
- " a warning should be logged or if an exception is thrown. Default is to ignore the received action.")
- .addValidator(StandardValidators.NON_BLANK_VALIDATOR)
- .allowableValues(EnforceActionTypeLevel.values())
- .defaultValue("IGNORE")
- .build();
-
- public void execute(Action action, Map facts) {
- if (actionTypeNotSupported(action)) {
- handleActionEnforcement(action);
- } else {
- executeAction(action, facts);
- }
- }
-
- public void execute(PropertyContext context, Action action, Map facts) {
- if (actionTypeNotSupported(action)) {
- handleActionEnforcement(action);
- } else {
- executeAction(context, action, facts);
- }
- }
-
- protected void executeAction(Action action, Map facts) {
- throw new UnsupportedOperationException("This method is not supported by this handler.");
- }
-
- protected void executeAction(PropertyContext propertyContext, Action action, Map facts) {
- throw new UnsupportedOperationException("This method is not supported by this handler");
- }
-
- protected boolean actionTypeNotSupported(Action action) {
- return enforceActionTypes != null && !enforceActionTypes.contains(action.getType());
- }
-
- protected void handleActionEnforcement(Action action) {
- String message = "This Action Handler does not support actions with the provided type: " + action.getType();
- if (enforceActionTypeLevel.equals(EnforceActionTypeLevel.WARN)) {
- getLogger().warn(message);
- } else if (enforceActionTypeLevel.equals(EnforceActionTypeLevel.EXCEPTION)) {
- throw new UnsupportedOperationException(message);
- } else if (getLogger().isDebugEnabled()) {
- getLogger().debug(message);
- }
- }
-
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) throws InitializationException {
- String actionTypes = context.getProperty(ENFORCE_ACTION_TYPE).evaluateAttributeExpressions().getValue();
- if(StringUtils.isNotEmpty(actionTypes)){
- enforceActionTypes = Arrays.stream(actionTypes.split(","))
- .map(String::trim)
- .filter(StringUtils::isNotEmpty)
- .collect(Collectors.toList());
- }
- String level = context.getProperty(ENFORCE_ACTION_TYPE_LEVEL).getValue();
- if(StringUtils.isNotEmpty(level)) {
- enforceActionTypeLevel = EnforceActionTypeLevel.valueOf(level);
- }
- }
-
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/ActionHandlerLookup.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/ActionHandlerLookup.java
deleted file mode 100644
index 2865193d01..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/ActionHandlerLookup.java
+++ /dev/null
@@ -1,124 +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.rules.handlers;
-
-import org.apache.nifi.annotation.behavior.DynamicProperty;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnDisabled;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.ValidationContext;
-import org.apache.nifi.components.ValidationResult;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.expression.ExpressionLanguageScope;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.rules.PropertyContextActionHandler;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Tags({"rules", "rules engine", "action", "action handler","lookup"})
-@CapabilityDescription("Provides an Action Handler that can be used to dynamically select another Action Handler. " +
-"This service will allow multiple ActionHandlers to be defined and registered by action type. When actions are provided the handlers can " +
-"be dynamically determined and executed at runtime.")
-@DynamicProperty(name = "actionType ", value = "Action Handler Service", expressionLanguageScope = ExpressionLanguageScope.NONE, description = "")
-public class ActionHandlerLookup extends AbstractActionHandlerService{
-
- private volatile Map actionHandlerMap;
-
- @Override
- protected PropertyDescriptor getSupportedDynamicPropertyDescriptor(final String propertyDescriptorName) {
- return new PropertyDescriptor.Builder()
- .name(propertyDescriptorName)
- .description("The Action handler to return when action type = '" + propertyDescriptorName + "'")
- .identifiesControllerService(PropertyContextActionHandler.class)
- .addValidator(StandardValidators.NON_BLANK_VALIDATOR)
- .build();
- }
-
- @Override
- protected Collection customValidate(ValidationContext context) {
- final List results = new ArrayList<>();
-
- int numDefinedServices = 0;
- for (final PropertyDescriptor descriptor : context.getProperties().keySet()) {
- if (descriptor.isDynamic()) {
- numDefinedServices++;
- }
-
- final String referencedId = context.getProperty(descriptor).getValue();
- if (this.getIdentifier().equals(referencedId)) {
- results.add(new ValidationResult.Builder()
- .subject(descriptor.getDisplayName())
- .explanation("the current service cannot be registered as an ActionHandler to lookup")
- .valid(false)
- .build());
- }
- }
-
- if (numDefinedServices == 0) {
- results.add(new ValidationResult.Builder()
- .subject(this.getClass().getSimpleName())
- .explanation("at least one Action Handler must be defined via dynamic properties")
- .valid(false)
- .build());
- }
-
- return results;
- }
-
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) {
- final Map serviceMap = new HashMap<>();
-
- for (final PropertyDescriptor descriptor : context.getProperties().keySet()) {
- if (descriptor.isDynamic()) {
- final PropertyContextActionHandler propertyContextActionHandler = context.getProperty(descriptor).asControllerService(PropertyContextActionHandler.class);
- serviceMap.put(descriptor.getName(), propertyContextActionHandler);
- }
- }
-
- actionHandlerMap = Collections.unmodifiableMap(serviceMap);
- }
-
- @OnDisabled
- public void onDisabled() {
- actionHandlerMap = null;
- }
-
- @Override
- public void execute(Action action, Map facts) {
- execute(null,action,facts);
- }
-
- @Override
- public void execute(PropertyContext context, Action action, Map facts) {
- PropertyContextActionHandler actionHandler = actionHandlerMap.get(action.getType());
- if (actionHandler == null) {
- throw new ProcessException("No Action Handler was found for Action Type:" + action.getType());
- }
- actionHandler.execute(context,action,facts);
- }
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/AlertHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/AlertHandler.java
deleted file mode 100644
index 1687d17fdd..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/AlertHandler.java
+++ /dev/null
@@ -1,166 +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.rules.handlers;
-
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.ControllerServiceInitializationContext;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.reporting.BulletinRepository;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.reporting.ReportingContext;
-import org.apache.nifi.reporting.Severity;
-import org.apache.nifi.rules.Action;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-@Tags({"rules", "rules engine", "action", "action handler", "logging", "alerts", "bulletins"})
-@CapabilityDescription("Creates alerts as bulletins based on a provided action (usually created by a rules engine). " +
- "Action objects executed with this Handler should contain \"category\", \"message\", and \"logLevel\" attributes.")
-public class AlertHandler extends AbstractActionHandlerService {
-
- public static final PropertyDescriptor DEFAULT_LOG_LEVEL = new PropertyDescriptor.Builder()
- .name("alert-default-log-level")
- .displayName("Default Alert Log Level")
- .required(true)
- .description("The default Log Level that will be used to log an alert message" +
- " if a log level was not provided in the received action's attributes.")
- .allowableValues(DebugLevels.values())
- .defaultValue("info")
- .build();
-
- public static final PropertyDescriptor DEFAULT_CATEGORY = new PropertyDescriptor.Builder()
- .name("alert-default-category")
- .displayName("Default Category")
- .required(true)
- .description("The default category to use when logging alert message "+
- " if a category was not provided in the received action's attributes.")
- .defaultValue("Rules Triggered Alert")
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .build();
-
- public static final PropertyDescriptor DEFAULT_MESSAGE = new PropertyDescriptor.Builder()
- .name("alert-default-message")
- .displayName("Default Message")
- .required(true)
- .description("The default message to include in alert if an alert message was " +
- "not provided in the received action's attributes")
- .defaultValue("An alert was triggered by a rules-based action.")
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .build();
-
- private static final PropertyDescriptor INCLUDE_FACTS = new PropertyDescriptor.Builder()
- .name("alert-include-facts")
- .displayName("Include Fact Data")
- .required(true)
- .description("If true, the alert message will include the facts which triggered this action. Default is false.")
- .defaultValue("true")
- .allowableValues("true", "false")
- .build();
-
- private List properties;
- private String defaultCategory;
- private String defaultLogLevel;
- private String defaultMessage;
- private Boolean includeFacts;
-
- @Override
- protected void init(ControllerServiceInitializationContext config) throws InitializationException {
- super.init(config);
- final List properties = new ArrayList<>();
- properties.add(DEFAULT_LOG_LEVEL);
- properties.add(DEFAULT_CATEGORY);
- properties.add(DEFAULT_MESSAGE);
- properties.add(INCLUDE_FACTS);
- properties.add(ENFORCE_ACTION_TYPE);
- properties.add(ENFORCE_ACTION_TYPE_LEVEL);
- this.properties = Collections.unmodifiableList(properties);
- }
-
- @Override
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) throws InitializationException {
- super.onEnabled(context);
- defaultLogLevel = context.getProperty(DEFAULT_LOG_LEVEL).getValue().toUpperCase();
- defaultCategory = context.getProperty(DEFAULT_CATEGORY).getValue();
- defaultMessage = context.getProperty(DEFAULT_MESSAGE).getValue();
- includeFacts = context.getProperty(INCLUDE_FACTS).asBoolean();
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return properties;
- }
-
- @Override
- protected void executeAction(PropertyContext propertyContext, Action action, Map facts) {
- ComponentLog logger = getLogger();
- if (propertyContext instanceof ReportingContext) {
-
- ReportingContext context = (ReportingContext) propertyContext;
- Map attributes = action.getAttributes();
- if (context.getBulletinRepository() != null) {
- final String category = attributes.getOrDefault("category", defaultCategory);
- final String message = getMessage(attributes.getOrDefault("message", defaultMessage), facts);
- final String level = attributes.getOrDefault("severity", attributes.getOrDefault("logLevel", defaultLogLevel));
- Severity severity;
- try {
- severity = Severity.valueOf(level.toUpperCase());
- } catch (IllegalArgumentException iae) {
- severity = Severity.INFO;
- }
- BulletinRepository bulletinRepository = context.getBulletinRepository();
- bulletinRepository.addBulletin(context.createBulletin(category, severity, message));
-
- } else {
- logger.warn("Bulletin Repository is not available which is unusual. Cannot send a bulletin.");
- }
-
- } else {
- logger.warn("Reporting context was not provided to create bulletins.");
- }
- }
-
- protected String getMessage(String alertMessage, Map facts){
- if (includeFacts) {
- final StringBuilder message = new StringBuilder(alertMessage);
- final Set fields = facts.keySet();
- message.append("\n");
- message.append("Alert Facts:\n");
- fields.forEach(field -> {
- message.append("Field: ");
- message.append(field);
- message.append(", Value: ");
- message.append(facts.get(field));
- message.append("\n");
- });
- return message.toString();
- }else{
- return alertMessage;
- }
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/ExpressionHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/ExpressionHandler.java
deleted file mode 100644
index 6a69d5eb24..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/ExpressionHandler.java
+++ /dev/null
@@ -1,131 +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.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.ControllerServiceInitializationContext;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.mvel2.MVEL;
-import org.springframework.expression.Expression;
-import org.springframework.expression.ExpressionParser;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.expression.spel.support.StandardEvaluationContext;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-
-@Tags({"rules", "rules engine", "action", "action handler", "expression language","MVEL","SpEL"})
-@CapabilityDescription("Executes an action containing an expression written in MVEL or SpEL. The action " +
-"is usually created by a rules engine. Action objects executed with this Handler should contain \"command\" and \"type\" attributes.")
-public class ExpressionHandler extends AbstractActionHandlerService {
-
- enum ExpresssionType {
- MVEL, SPEL;
- }
-
- public static final PropertyDescriptor DEFAULT_EXPRESSION_LANGUAGE_TYPE = new PropertyDescriptor.Builder()
- .name("default-expression-language-type")
- .displayName("Default Expression Language Type")
- .required(true)
- .description("If an expression language type is not provided as an attribute within an Action, the default expression language that " +
- "should be used to compile and execute action. Supported languages are MVEL and Spring Expression Language (SpEL).")
- .allowableValues(ExpresssionType.values())
- .defaultValue("MVEL")
- .build();
-
- private List properties;
- private ExpresssionType type;
-
- @Override
- protected void init(ControllerServiceInitializationContext config) throws InitializationException {
- super.init(config);
- final List properties = new ArrayList<>();
- properties.add(DEFAULT_EXPRESSION_LANGUAGE_TYPE);
- properties.add(ENFORCE_ACTION_TYPE);
- properties.add(ENFORCE_ACTION_TYPE_LEVEL);
- this.properties = Collections.unmodifiableList(properties);
- }
-
- @Override
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) throws InitializationException {
- super.onEnabled(context);
- type = ExpresssionType.valueOf(context.getProperty(DEFAULT_EXPRESSION_LANGUAGE_TYPE).getValue());
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return properties;
- }
-
- @Override
- protected void executeAction(PropertyContext propertyContext, Action action, Map facts) {
- executeAction(action, facts);
- }
-
- @Override
- protected void executeAction(Action action, Map facts) {
- Map attributes = action.getAttributes();
- final String command = attributes.get("command");
- if(StringUtils.isNotEmpty(command)) {
- try {
- final String type = attributes.getOrDefault("type",this.type.toString());
- ExpresssionType expresssionType = ExpresssionType.valueOf(type);
- if (expresssionType.equals(ExpresssionType.MVEL)) {
- executeMVEL(command, facts);
- } else {
- executeSPEL(command, facts);
- }
- } catch (Exception ex) {
- getLogger().warn("Error occurred when attempting to execute expression. Action: {}, Facts - {}", action, facts, ex);
- }
- }else{
- getLogger().warn("Command attribute was not provided. Action: {}, Facts - {}",
- new Object[]{action, facts});
- }
- }
-
- private void executeMVEL(String command, Map facts) {
- MVEL.executeExpression(MVEL.compileExpression(command), facts);
- if(getLogger().isDebugEnabled()) {
- getLogger().debug("Expression was executed successfully: {}: {}", new Object[]{type, command});
- }
- }
-
- private void executeSPEL(String command, Map facts) {
- final ExpressionParser parser = new SpelExpressionParser();
- StandardEvaluationContext context = new StandardEvaluationContext();
- context.setRootObject(facts);
- context.setVariables(facts);
- Expression expression = parser.parseExpression(command);
- Object value = expression.getValue(context);
- if(getLogger().isDebugEnabled()) {
- getLogger().debug("Expression was executed successfully with result: {}. {}: {}", new Object[]{value, type, command});
- }
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/LogHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/LogHandler.java
deleted file mode 100644
index b59bcbe3c2..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/LogHandler.java
+++ /dev/null
@@ -1,186 +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.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.ControllerServiceInitializationContext;
-import org.apache.nifi.expression.ExpressionLanguageScope;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.logging.LogLevel;
-import org.apache.nifi.processor.util.StandardValidators;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-@Tags({"rules", "rules engine", "action", "action handler", "logging"})
-@CapabilityDescription("Logs messages and fact information based on a provided action (usually created by a rules engine). " +
- " Action objects executed with this Handler should contain \"logLevel\" and \"message\" attributes.")
-public class LogHandler extends AbstractActionHandlerService {
-
- public static final PropertyDescriptor DEFAULT_LOG_LEVEL = new PropertyDescriptor.Builder()
- .name("logger-default-log-level")
- .displayName("Default Log Level")
- .required(true)
- .description("If a log level is not provided as an attribute within an Action, the default log level will be used.")
- .allowableValues(DebugLevels.values())
- .defaultValue("info")
- .build();
-
- public static final PropertyDescriptor DEFAULT_LOG_MESSAGE = new PropertyDescriptor.Builder()
- .name("logger-default-log-message")
- .displayName("Default Log Message")
- .required(true)
- .description("If a log message is not provided as an attribute within an Action, the default log message will be used.")
- .defaultValue("Rules Action Triggered Log.")
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .build();
-
- private static final PropertyDescriptor LOG_FACTS = new PropertyDescriptor.Builder()
- .name("log-facts")
- .displayName("Log Facts")
- .required(true)
- .description("If true, the log message will include the facts which triggered this log action.")
- .defaultValue("true")
- .allowableValues("true", "false")
- .build();
-
- private static final PropertyDescriptor LOG_PREFIX = new PropertyDescriptor.Builder()
- .name("log-prefix")
- .displayName("Log Prefix")
- .required(false)
- .description("Log prefix appended to the log lines. It helps to distinguish the output of multiple LogAttribute processors.")
- .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
- .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
- .build();
-
- private List properties;
- private String logPrefix;
- private Boolean logFacts;
- private String defaultLogLevel;
- private String defaultLogMessage;
-
- @Override
- protected void init(ControllerServiceInitializationContext config) throws InitializationException {
- super.init(config);
- final List properties = new ArrayList<>();
- properties.add(LOG_PREFIX);
- properties.add(LOG_FACTS);
- properties.add(DEFAULT_LOG_LEVEL);
- properties.add(DEFAULT_LOG_MESSAGE);
- properties.add(ENFORCE_ACTION_TYPE);
- properties.add(ENFORCE_ACTION_TYPE_LEVEL);
- this.properties = Collections.unmodifiableList(properties);
- }
-
- @Override
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) throws InitializationException {
- super.onEnabled(context);
- logPrefix = context.getProperty(LOG_PREFIX).evaluateAttributeExpressions().getValue();
- logFacts = context.getProperty(LOG_FACTS).asBoolean();
- defaultLogLevel = context.getProperty(DEFAULT_LOG_LEVEL).getValue().toUpperCase();
- defaultLogMessage = context.getProperty(DEFAULT_LOG_MESSAGE).evaluateAttributeExpressions().getValue();
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return properties;
- }
-
- @Override
- protected void executeAction(PropertyContext propertyContext, Action action, Map facts) {
- executeAction(action, facts);
- }
-
- @Override
- protected void executeAction(Action action, Map facts) {
- ComponentLog logger = getLogger();
- Map attributes = action.getAttributes();
- final String logLevel = attributes.get("logLevel");
- final LogLevel level = getLogLevel(logLevel, LogLevel.valueOf(defaultLogLevel));
- final String eventMessage = StringUtils.isNotEmpty(attributes.get("message")) ? attributes.get("message") : defaultLogMessage;
- final String factsMessage = createFactsLogMessage(facts, eventMessage);
- logger.log(level, factsMessage);
- }
-
- private LogLevel getLogLevel(String logLevel, LogLevel defaultLevel) {
- LogLevel level;
- if (StringUtils.isNotEmpty(logLevel)) {
- try {
- level = LogLevel.valueOf(logLevel.toUpperCase());
- } catch (IllegalArgumentException iea) {
- level = defaultLevel;
- }
- } else {
- level = defaultLevel;
- }
- return level;
- }
-
- protected String createFactsLogMessage(Map facts, String eventMessage) {
-
- final Set fields = facts.keySet();
- final StringBuilder message = new StringBuilder();
- String dashedLine;
-
- if (StringUtils.isBlank(logPrefix)) {
- dashedLine = StringUtils.repeat('-', 50);
- } else {
- // abbreviate long lines
- logPrefix = StringUtils.abbreviate(logPrefix, 40);
- // center the logPrefix and pad with dashes
- logPrefix = StringUtils.center(logPrefix, 40, '-');
- // five dashes on the left and right side, plus the dashed logPrefix
- dashedLine = StringUtils.repeat('-', 5) + logPrefix + StringUtils.repeat('-', 5);
- }
-
- message.append("\n");
- message.append(dashedLine);
- message.append("\n");
- message.append("Log Message: ");
- message.append(eventMessage);
- message.append("\n");
-
- if (logFacts) {
- message.append("Log Facts:\n");
- fields.forEach(field -> {
- message.append("Field: ");
- message.append(field);
- message.append(", Value: ");
- message.append(facts.get(field));
- message.append("\n");
- });
- }
-
- return message.toString().trim();
-
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/RecordSinkHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/RecordSinkHandler.java
deleted file mode 100644
index 55c0de4127..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/java/org/apache/nifi/rules/handlers/RecordSinkHandler.java
+++ /dev/null
@@ -1,160 +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.rules.handlers;
-
-import org.apache.commons.lang3.math.NumberUtils;
-import org.apache.nifi.annotation.documentation.CapabilityDescription;
-import org.apache.nifi.annotation.documentation.Tags;
-import org.apache.nifi.annotation.lifecycle.OnEnabled;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.controller.ConfigurationContext;
-import org.apache.nifi.controller.ControllerServiceInitializationContext;
-import org.apache.nifi.record.sink.RecordSinkService;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.serialization.SimpleRecordSchema;
-import org.apache.nifi.serialization.WriteResult;
-import org.apache.nifi.serialization.record.DataType;
-import org.apache.nifi.serialization.record.ListRecordSet;
-import org.apache.nifi.serialization.record.MapRecord;
-import org.apache.nifi.serialization.record.RecordField;
-import org.apache.nifi.serialization.record.RecordFieldType;
-import org.apache.nifi.serialization.record.RecordSchema;
-import org.apache.nifi.serialization.record.RecordSet;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@Tags({"rules", "rules engine", "action", "action handler", "record", "record sink"})
-@CapabilityDescription("Sends fact information to sink based on a provided action (usually created by a rules engine)." +
- " Action objects executed with this Handler should contain \"sendZeroResult\" attribute.")
-public class RecordSinkHandler extends AbstractActionHandlerService{
-
- static final PropertyDescriptor RECORD_SINK_SERVICE = new PropertyDescriptor.Builder()
- .name("record-sink-service")
- .displayName("Record Sink Service")
- .description("Specifies the Controller Service used to support the SEND event action. If not set SEND events will be ignored.")
- .identifiesControllerService(RecordSinkService.class)
- .required(true)
- .build();
-
- private RecordSinkService recordSinkService;
- private List properties;
-
- @Override
- protected void init(ControllerServiceInitializationContext config) throws InitializationException {
- super.init(config);
- final List properties = new ArrayList<>();
- properties.add(RECORD_SINK_SERVICE);
- properties.add(ENFORCE_ACTION_TYPE);
- properties.add(ENFORCE_ACTION_TYPE_LEVEL);
- this.properties = Collections.unmodifiableList(properties);
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return properties;
- }
-
- @Override
- @OnEnabled
- public void onEnabled(final ConfigurationContext context) throws InitializationException {
- super.onEnabled(context);
- if(context.getProperty(RECORD_SINK_SERVICE).isSet()) {
- recordSinkService = context.getProperty(RECORD_SINK_SERVICE).asControllerService(RecordSinkService.class);
- }
- }
-
- @Override
- protected void executeAction(PropertyContext propertyContext, Action action, Map facts) {
- executeAction(action, facts);
- }
-
- @Override
- protected void executeAction(Action action, Map facts) {
- Map attributes = action.getAttributes();
- boolean sendZeroResults = attributes.containsKey("sentZeroResults") && Boolean.parseBoolean(attributes.get("sendZeroResults"));
- final RecordSet recordSet = getRecordSet(facts);
-
- try {
- WriteResult result = recordSinkService.sendData(recordSet, attributes, sendZeroResults);
- if (getLogger().isDebugEnabled() && result != null) {
- getLogger().debug("Records written to sink service: {}", new Object[]{result.getRecordCount()});
- }
- } catch (Exception ex) {
- getLogger().warn("Exception encountered when attempting to send metrics", ex);
- }
- }
-
- private RecordSet getRecordSet(Map metrics){
- List recordFields = metrics.entrySet().stream().map(entry ->
- new RecordField(entry.getKey(),getDataType(String.valueOf(entry.getValue())))
- ).collect(Collectors.toList());
- final RecordSchema recordSchema = new SimpleRecordSchema(recordFields);
- return new ListRecordSet(recordSchema, Arrays.asList( new MapRecord(recordSchema,metrics)));
- }
-
- private DataType getDataType(final String value) {
- if (value == null || value.isEmpty()) {
- return null;
- }
-
- if (NumberUtils.isParsable(value)) {
- if (value.contains(".")) {
- try {
- final double doubleValue = Double.parseDouble(value);
-
- if (doubleValue == Double.POSITIVE_INFINITY || doubleValue == Double.NEGATIVE_INFINITY) {
- return RecordFieldType.DECIMAL.getDecimalDataType(value.length() - 1, value.length() - 1 - value.indexOf("."));
- }
-
- if (doubleValue > Float.MAX_VALUE || doubleValue < Float.MIN_VALUE) {
- return RecordFieldType.DOUBLE.getDataType();
- }
-
- return RecordFieldType.FLOAT.getDataType();
- } catch (final NumberFormatException nfe) {
- return RecordFieldType.STRING.getDataType();
- }
- }
-
- try {
- final long longValue = Long.parseLong(value);
- if (longValue > Integer.MAX_VALUE || longValue < Integer.MIN_VALUE) {
- return RecordFieldType.LONG.getDataType();
- }
-
- return RecordFieldType.INT.getDataType();
- } catch (final NumberFormatException nfe) {
- return RecordFieldType.STRING.getDataType();
- }
- }
-
- if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
- return RecordFieldType.BOOLEAN.getDataType();
- }
-
- return RecordFieldType.STRING.getDataType();
-
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
deleted file mode 100644
index 461f818f3c..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/META-INF/services/org.apache.nifi.controller.ControllerService
+++ /dev/null
@@ -1,19 +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.
-org.apache.nifi.rules.handlers.ActionHandlerLookup
-org.apache.nifi.rules.handlers.ExpressionHandler
-org.apache.nifi.rules.handlers.LogHandler
-org.apache.nifi.rules.handlers.RecordSinkHandler
-org.apache.nifi.rules.handlers.AlertHandler
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.AlertHandler/additionalDetails.html b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.AlertHandler/additionalDetails.html
deleted file mode 100644
index ea1a49851a..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.AlertHandler/additionalDetails.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
- AlertHandler
-
-
-
-
-
-
Summary
-
- The AlertHandler is used to broadcast alerts (bulletins) as dictated by the action object. Action objects can include attributes to configure
- the handler otherwise default values will be used. Possible attribute values are listed below.
-
-
ExpressionHandler Service Attributes
-
-
Attribute
Description
-
category
The category the alert should be grouped under.
-
logLevel
Log Level for the alert. Possible values are trace, debug, info, warn, error.
-
message
Message for the alert.
-
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.ExpressionHandler/additionalDetails.html b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.ExpressionHandler/additionalDetails.html
deleted file mode 100644
index 8dff1bc188..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.ExpressionHandler/additionalDetails.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
- ExpressionHandler
-
-
-
-
-
-
Summary
-
- The ExpressionHandler is used to execute dynamic commands writtin in MVEL or SpEL expression language. Action objects must include attributes to configure
- the handler otherwise an exception will be thrown. Possible attribute values are listed below.
-
-
ExpressionHandler Service Attributes
-
-
Attribute
Description
-
type
The expression language type of the command to be executed. Possible values are MVEL and SpEl (MVEL will be applied by default if type is not provided).
-
command
The expression language command that should be executed
-
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.LogHandler/additionalDetails.html b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.LogHandler/additionalDetails.html
deleted file mode 100644
index b9b487da23..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.LogHandler/additionalDetails.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
- LogHandler
-
-
-
-
-
-
Summary
-
- The LogHandler is used to execute actions that dictate to log a message and/or metrics. LogHandler can be invoked with any Action object.
- Action objects can include attributes to configure the LogHandler or rely on the handler's default settings. Possible attribute values are listed below.
-
-
LogHandler Service Attributes
-
-
Attribute
Description
-
logLevel
Log Level for logged message. Possible values are trace, debug, info, warn, error.
-
message
Message for log.
-
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.RecordSinkHandler/additionalDetails.html b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.RecordSinkHandler/additionalDetails.html
deleted file mode 100644
index 4633f37a40..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/main/resources/docs/org.apache.nifi.rules.handlers.RecordSinkHandler/additionalDetails.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
- RecordSinkHandler
-
-
-
-
-
-
Summary
-
- The RecordSinkHandler is used to execute actions that send metrics information to a configured sink. RecordSinkHandler can be invoked with any Action object.
- Action objects can include attributes to configure the handler. Possible attribute values are listed below.
-
-
RecordSinkHandler Service Attributes
-
-
Attribute
Description
-
sendZeroResults
Allow empty results to be sent to sink. Possible values are true and false (default is false).
-
-
-
-
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/MockComponentLog.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/MockComponentLog.java
deleted file mode 100644
index 827ca3a0e9..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/MockComponentLog.java
+++ /dev/null
@@ -1,200 +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.rules.handlers;
-
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.logging.LogLevel;
-import org.apache.nifi.logging.LogMessage;
-
-public class MockComponentLog implements ComponentLog {
-
- String infoMessage;
- String warnMessage;
- String debugMessage;
- String traceMessage;
- String errorMessage;
-
- protected String convertMessage(String msg, Object[] os){
- String replaceMsg = msg;
- for (Object o : os) {
- replaceMsg = replaceMsg.replaceFirst("\\{\\}", os.toString());
- }
- return replaceMsg;
- }
-
- @Override
- public void warn(String msg, Throwable t) {
- warn(msg);
- }
-
- @Override
- public void warn(String msg, Object... os) {
- warn(msg);
- }
-
- @Override
- public void warn(String msg) {
- warnMessage = msg;
- }
-
- @Override
- public void warn(LogMessage logMessage) {
- warnMessage = logMessage.getMessage();
- }
-
- @Override
- public void trace(String msg, Throwable t) {
- trace(msg);
- }
-
- @Override
- public void trace(String msg, Object... os) {
- trace(msg);
- }
-
- @Override
- public void trace(String msg) {
- traceMessage = msg;
- }
-
- @Override
- public void trace(LogMessage logMessage) {
- traceMessage = logMessage.getMessage();
- }
-
- @Override
- public boolean isWarnEnabled() {
- return true;
- }
-
- @Override
- public boolean isTraceEnabled() {
- return false;
- }
-
- @Override
- public boolean isInfoEnabled() {
- return false;
- }
-
- @Override
- public boolean isErrorEnabled() {
- return false;
- }
-
- @Override
- public boolean isDebugEnabled() {
- return true;
- }
-
- @Override
- public void info(String msg, Throwable t) {
- info(msg);
- }
-
- @Override
- public void info(String msg, Object... os) {
- info(msg);
- }
-
- @Override
- public void info(String msg) {
- infoMessage = msg;
- }
-
- @Override
- public void info(LogMessage message) {
- infoMessage = message.getMessage();
- }
-
- @Override
- public String getName() {
- return null;
- }
-
- @Override
- public void error(String msg, Throwable t) {
- error(msg);
- }
-
- @Override
- public void error(String msg, Object... os) {
- error(convertMessage(msg, os));
- }
-
- @Override
- public void error(String msg) {
- errorMessage = msg;
- }
-
- @Override
- public void error(LogMessage message) {
- errorMessage = message.getMessage();
- }
-
- @Override
- public void debug(String msg, Throwable t) {
- debug(msg);
- }
-
- @Override
- public void debug(String msg, Object... os) {
- debug(convertMessage(msg, os));
- }
-
- @Override
- public void debug(String msg) {
- debugMessage = msg;
- }
-
- @Override
- public void debug(LogMessage message) {
- debugMessage = message.getMessage();
- }
-
- @Override
- public void log(LogLevel level, String msg, Throwable t) {
-
- }
-
- @Override
- public void log(LogLevel level, String msg, Object... os) {
-
- }
-
- public String getInfoMessage() {
- return infoMessage;
- }
-
- public String getWarnMessage() {
- return warnMessage;
- }
-
- public String getDebugMessage() {
- return debugMessage;
- }
-
- public String getTraceMessage() {
- return traceMessage;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestActionHandlerLookup.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestActionHandlerLookup.java
deleted file mode 100644
index a015427e57..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestActionHandlerLookup.java
+++ /dev/null
@@ -1,135 +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.rules.handlers;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class TestActionHandlerLookup {
-
- private MockPropertyActionHandler alertHandler;
- private MockPropertyActionHandler logHandler;
- private ActionHandlerLookup actionHandlerLookup;
- private TestRunner runner;
-
- @BeforeEach
- public void setup() throws InitializationException {
- alertHandler = new MockPropertyActionHandler();
- logHandler = new MockPropertyActionHandler();
- actionHandlerLookup = new ActionHandlerLookup();
-
- runner = TestRunners.newTestRunner(TestProcessor.class);
-
- final String alertIdentifier = "alert-handler";
- runner.addControllerService(alertIdentifier, alertHandler);
-
- final String logIdentifier = "log-handler";
- runner.addControllerService(logIdentifier, logHandler);
-
- runner.addControllerService("action-handler-lookup", actionHandlerLookup);
- runner.setProperty(actionHandlerLookup, "ALERT", alertIdentifier);
- runner.setProperty(actionHandlerLookup, "LOG", logIdentifier);
-
- runner.enableControllerService(alertHandler);
- runner.enableControllerService(logHandler);
- runner.enableControllerService(actionHandlerLookup);
-
- }
-
- @Test
- public void testLookupAlert() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("logLevel", "INFO");
- attributes.put("message", "This should be not sent as an alert!");
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- actionHandlerLookup.execute(null, action, metrics);
- assertTrue(alertHandler.getExecuteContextCalled());
- }
-
- @Test
- public void testLookupLog() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("logLevel", "INFO");
- attributes.put("message", "This should be not sent as an alert!");
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
- final Action action = new Action();
- action.setType("LOG");
- action.setAttributes(attributes);
- actionHandlerLookup.execute(null, action, metrics);
- assertTrue(logHandler.getExecuteContextCalled());
- }
-
- @Test
- public void testLookupInvalidActionType() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("logLevel", "INFO");
- attributes.put("message", "This should be not sent as an alert!");
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
- final Action action = new Action();
- action.setType("FAKE");
- assertThrows(ProcessException.class, () -> actionHandlerLookup.execute(null,action,metrics));
- }
-
- private static class MockPropertyActionHandler extends AbstractActionHandlerService {
-
- Boolean executeContextCalled = false;
-
- @Override
- public void execute(Action action, Map facts) {
- execute(null,action,facts);
- }
-
- @Override
- public void execute(PropertyContext context, Action action, Map facts) {
- executeContextCalled = true;
- }
-
- public Boolean getExecuteContextCalled() {
- return executeContextCalled;
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- return Arrays.asList(ENFORCE_ACTION_TYPE, ENFORCE_ACTION_TYPE_LEVEL);
- }
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestAlertHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestAlertHandler.java
deleted file mode 100644
index 3688940a0b..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestAlertHandler.java
+++ /dev/null
@@ -1,366 +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.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.context.PropertyContext;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.reporting.Bulletin;
-import org.apache.nifi.reporting.BulletinFactory;
-import org.apache.nifi.reporting.BulletinRepository;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.reporting.ReportingContext;
-import org.apache.nifi.reporting.Severity;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.util.MockBulletinRepository;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
-
-public class TestAlertHandler {
-
- private TestRunner runner;
- private MockComponentLog mockComponentLog;
- private ReportingContext reportingContext;
- private AlertHandler alertHandler;
- private MockAlertBulletinRepository mockAlertBulletinRepository;
-
- @BeforeEach
- public void setup() throws InitializationException {
- runner = TestRunners.newTestRunner(TestProcessor.class);
- mockComponentLog = new MockComponentLog();
- AlertHandler handler = new MockAlertHandler(mockComponentLog);
- mockAlertBulletinRepository = new MockAlertBulletinRepository();
- runner.addControllerService("MockAlertHandler", handler);
- runner.enableControllerService(handler);
- alertHandler = (AlertHandler) runner.getProcessContext()
- .getControllerServiceLookup()
- .getControllerService("MockAlertHandler");
- reportingContext = Mockito.mock(ReportingContext.class);
- Mockito.when(reportingContext.getBulletinRepository()).thenReturn(mockAlertBulletinRepository);
- Mockito.when(reportingContext.createBulletin(anyString(), Mockito.any(Severity.class), anyString()))
- .thenAnswer(invocation ->
- BulletinFactory.createBulletin(invocation.getArgument(0), invocation.getArgument(1).toString(), invocation.getArgument(2)));
- }
-
- @Test
- public void testValidService() {
- runner.assertValid(alertHandler);
- assertThat(alertHandler, instanceOf(AlertHandler.class));
- }
-
- @Test
- public void testAlertNoReportingContext() {
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- attributes.put("logLevel", "INFO");
- attributes.put("message", "This should be not sent as an alert!");
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- assertThrows(UnsupportedOperationException.class, () -> alertHandler.execute(action, metrics));
- }
-
- @Test
- public void testAlertWithBulletinLevel() {
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final String expectedOutput = "This should be sent as an alert!\n" +
- "Alert Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000\n";
-
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- alertHandler.execute(reportingContext, action, metrics);
- BulletinRepository bulletinRepository = reportingContext.getBulletinRepository();
- List bulletins = bulletinRepository.findBulletinsForController();
- assertFalse(bulletins.isEmpty());
- Bulletin bulletin = bulletins.get(0);
- assertEquals(bulletin.getCategory(), category);
- assertEquals(bulletin.getMessage(), expectedOutput);
- assertEquals(bulletin.getLevel(), severity);
- }
-
- @Test
- public void testAlertWithDefaultValues() {
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Triggered Alert";
- final String message = "An alert was triggered by a rules based action.";
- final String severity = "INFO";
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final String expectedOutput = "An alert was triggered by a rules-based action.\n" +
- "Alert Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000\n";
-
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- alertHandler.execute(reportingContext, action, metrics);
- BulletinRepository bulletinRepository = reportingContext.getBulletinRepository();
- List bulletins = bulletinRepository.findBulletinsForController();
- assertFalse(bulletins.isEmpty());
- Bulletin bulletin = bulletins.get(0);
- assertEquals(bulletin.getCategory(), category);
- assertEquals(bulletin.getMessage(), expectedOutput);
- assertEquals(bulletin.getLevel(), severity);
- }
-
- @Test
- public void testInvalidContext(){
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- PropertyContext fakeContext = new PropertyContext() {
- @Override
- public PropertyValue getProperty(PropertyDescriptor descriptor) {
- return null;
- }
-
- @Override
- public Map getAllProperties() {
- return null;
- }
- };
- alertHandler.execute(fakeContext, action, metrics);
- final String debugMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(debugMessage));
- assertEquals(debugMessage,"Reporting context was not provided to create bulletins.");
- }
-
- @Test
- public void testEmptyBulletinRepository(){
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- ReportingContext fakeContext = Mockito.mock(ReportingContext.class);
- Mockito.when(reportingContext.getBulletinRepository()).thenReturn(null);
- alertHandler.execute(fakeContext, action, metrics);
- final String warnMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(warnMessage));
- assertEquals(warnMessage,"Bulletin Repository is not available which is unusual. Cannot send a bulletin.");
- }
-
- @Test
- public void testInvalidActionTypeException(){
-
- runner.disableControllerService(alertHandler);
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE, "ALERT");
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "EXCEPTION");
- runner.enableControllerService(alertHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
- assertThrows(UnsupportedOperationException.class, () -> alertHandler.execute(reportingContext, action, metrics));
- }
-
- @Test
- public void testInvalidActionTypeWarn(){
-
- runner.disableControllerService(alertHandler);
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE, "ALERT");
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "WARN");
- runner.enableControllerService(alertHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
-
- assertDoesNotThrow(() -> alertHandler.execute(reportingContext,action, metrics));
-
- final String warnMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(warnMessage));
- assertEquals("This Action Handler does not support actions with the provided type: FAKE",warnMessage);
- }
-
- @Test
- public void testInvalidActionTypeIgnore(){
-
- runner.disableControllerService(alertHandler);
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE, "ALERT");
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "IGNORE");
- runner.enableControllerService(alertHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
- assertDoesNotThrow(() -> alertHandler.execute(reportingContext,action, metrics));
-
- final String debugMessage = mockComponentLog.getDebugMessage();
- assertTrue(StringUtils.isNotEmpty(debugMessage));
- assertEquals("This Action Handler does not support actions with the provided type: FAKE",debugMessage);
- }
-
- @Test
- public void testValidActionType(){
- runner.disableControllerService(alertHandler);
- runner.setProperty(alertHandler, AlertHandler.ENFORCE_ACTION_TYPE, "ALERT, LOG, ");
- runner.enableControllerService(alertHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String category = "Rules Alert";
- final String message = "This should be sent as an alert!";
- final String severity = "INFO";
- attributes.put("category", category);
- attributes.put("message", message);
- attributes.put("severity", severity);
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("ALERT");
- action.setAttributes(attributes);
- assertDoesNotThrow(() -> alertHandler.execute(reportingContext,action, metrics));
- }
-
- private static class MockAlertHandler extends AlertHandler {
-
- private ComponentLog testLogger;
-
- public MockAlertHandler(ComponentLog testLogger) {
- this.testLogger = testLogger;
- }
-
- @Override
- protected ComponentLog getLogger() {
- return testLogger;
- }
-
- }
-
- private static class MockAlertBulletinRepository extends MockBulletinRepository {
-
- List bulletinList;
-
-
- public MockAlertBulletinRepository() {
- bulletinList = new ArrayList<>();
- }
-
- @Override
- public void addBulletin(Bulletin bulletin) {
- bulletinList.add(bulletin);
- }
-
- @Override
- public List findBulletinsForController() {
- return bulletinList;
- }
-
- }
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestExpressionHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestExpressionHandler.java
deleted file mode 100644
index e65e17469c..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestExpressionHandler.java
+++ /dev/null
@@ -1,236 +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.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class TestExpressionHandler {
-
- private TestRunner runner;
- private MockComponentLog mockComponentLog;
- private ExpressionHandler expressionHandler;
-
- @BeforeEach
- public void setup() throws InitializationException {
- runner = TestRunners.newTestRunner(TestProcessor.class);
- mockComponentLog = new MockComponentLog();
- ExpressionHandler handler = new MockExpressionHandler(mockComponentLog);
- runner.addControllerService("MockExpressionHandler", handler);
- runner.enableControllerService(handler);
- expressionHandler = (ExpressionHandler) runner.getProcessContext()
- .getControllerServiceLookup()
- .getControllerService("MockExpressionHandler");
- }
-
- @Test
- public void testValidService() {
- runner.assertValid(expressionHandler);
- assertThat(expressionHandler, instanceOf(ExpressionHandler.class));
- }
-
- @Test
- public void testMvelExpression(){
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- final String expectedMessage = "Expression was executed successfully:";
-
- attributes.put("command","System.out.println(jvmHeap)");
- attributes.put("type","MVEL");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("EXPRESSION");
- action.setAttributes(attributes);
- expressionHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getDebugMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertTrue(logMessage.startsWith(expectedMessage));
- }
-
- @Test
- public void testSpelExpression(){
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- final String expectedMessage = "Expression was executed successfully with result:";
-
- attributes.put("command","#jvmHeap + ' is large'");
- attributes.put("type","SPEL");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("EXPRESSION");
- action.setAttributes(attributes);
- expressionHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getDebugMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertTrue(logMessage.startsWith(expectedMessage));
- }
-
- @Test
- public void testInvalidType() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- final String expectedMessage = "Error occurred when attempting to execute expression.";
-
- attributes.put("command","#jvmHeap + ' is large'");
- attributes.put("type","FAKE");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("EXPRESSION");
- action.setAttributes(attributes);
- expressionHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertTrue(logMessage.startsWith(expectedMessage));
- }
-
- @Test
- public void testNoCommandProvided() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- final String expectedMessage = "Command attribute was not provided.";
- attributes.put("type","FAKE");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("EXPRESSION");
- action.setAttributes(attributes);
- expressionHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertTrue(logMessage.startsWith(expectedMessage));
- }
-
- @Test
- public void testInvalidActionTypeException() {
- runner.disableControllerService(expressionHandler);
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE, "EXPRESSION");
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "EXCEPTION");
- runner.enableControllerService(expressionHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("type","FAKE");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
-
- assertThrows(UnsupportedOperationException.class, () -> expressionHandler.execute(action, metrics));
- }
-
- @Test
- public void testInvalidActionTypeWarning() {
- runner.disableControllerService(expressionHandler);
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE, "EXPRESSION");
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "WARN");
- runner.enableControllerService(expressionHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("type","FAKE");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
-
- assertDoesNotThrow(() -> expressionHandler.execute(action, metrics));
-
- final String warnMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(warnMessage));
- assertEquals("This Action Handler does not support actions with the provided type: FAKE",warnMessage);
- }
-
- @Test
- public void testInvalidActionTypeIgnore() {
- runner.disableControllerService(expressionHandler);
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE, "EXPRESSION");
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "IGNORE");
- runner.enableControllerService(expressionHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("type","FAKE");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
-
- assertDoesNotThrow(() -> expressionHandler.execute(action, metrics));
-
- final String debugMessage = mockComponentLog.getDebugMessage();
- assertTrue(StringUtils.isNotEmpty(debugMessage));
- assertEquals("This Action Handler does not support actions with the provided type: FAKE",debugMessage);
-
- }
- @Test
- public void testValidActionType() {
- runner.disableControllerService(expressionHandler);
- runner.setProperty(expressionHandler, AlertHandler.ENFORCE_ACTION_TYPE, "EXPRESSION");
- runner.enableControllerService(expressionHandler);
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- attributes.put("type","FAKE");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
-
- final Action action = new Action();
- action.setType("EXPRESSION");
- action.setAttributes(attributes);
- assertDoesNotThrow(() -> expressionHandler.execute(action, metrics));
- }
-
-
- private static class MockExpressionHandler extends ExpressionHandler{
- private ComponentLog testLogger;
-
- public MockExpressionHandler(ComponentLog testLogger) {
- this.testLogger = testLogger;
- }
-
- @Override
- protected ComponentLog getLogger() {
- return testLogger;
- }
- }
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestLogHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestLogHandler.java
deleted file mode 100644
index 671e485042..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestLogHandler.java
+++ /dev/null
@@ -1,269 +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.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class TestLogHandler {
-
- TestRunner runner;
- MockComponentLog mockComponentLog;
- LogHandler logHandler;
-
- @BeforeEach
- public void setup() throws InitializationException {
- runner = TestRunners.newTestRunner(TestProcessor.class);
- mockComponentLog = new MockComponentLog();
- LogHandler handler = new MockLogHandler(mockComponentLog);
- runner.addControllerService("MockLogHandler", handler);
- runner.enableControllerService(handler);
- logHandler = (LogHandler) runner.getProcessContext()
- .getControllerServiceLookup()
- .getControllerService("MockLogHandler");
-
- }
-
- @Test
- public void testValidService() {
- runner.assertValid(logHandler);
- assertThat(logHandler, instanceOf(LogHandler.class));
- }
-
- @Test
- public void testWarningLogged() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: This is a warning\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
-
- attributes.put("logLevel", "warn");
- attributes.put("message", "This is a warning");
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
- final Action action = new Action();
- action.setType("LOG");
- action.setAttributes(attributes);
- logHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertEquals(expectedMessage, logMessage);
- }
-
- @Test
- public void testNoLogAttributesProvided() {
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: Rules Action Triggered Log.\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("LOG");
- action.setAttributes(attributes);
- logHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getInfoMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertEquals(expectedMessage, logMessage);
-
- }
-
- @Test
- public void testInvalidLogLevelProvided() {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- attributes.put("logLevel", "FAKE");
-
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: Rules Action Triggered Log.\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("LOG");
- action.setAttributes(attributes);
- logHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getInfoMessage();
- assertTrue(StringUtils.isNotEmpty(logMessage));
- assertEquals(expectedMessage, logMessage);
-
- }
-
- @Test
- public void testInvalidActionTypeException() {
- runner.disableControllerService(logHandler);
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE, "LOG");
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "EXCEPTION");
- runner.enableControllerService(logHandler);
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- attributes.put("logLevel", "FAKE");
-
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: Rules Action Triggered Log.\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
- assertThrows(UnsupportedOperationException.class, () -> logHandler.execute(action, metrics));
- }
-
- @Test
- public void testInvalidActionTypeWarning() {
- runner.disableControllerService(logHandler);
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE, "LOG");
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "WARN");
- runner.enableControllerService(logHandler);
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- attributes.put("logLevel", "FAKE");
-
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: Rules Action Triggered Log.\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
- assertDoesNotThrow(() -> logHandler.execute(action, metrics));
-
- final String warnMessage = mockComponentLog.getWarnMessage();
- assertTrue(StringUtils.isNotEmpty(warnMessage));
- assertEquals("This Action Handler does not support actions with the provided type: FAKE",warnMessage);
- }
-
- @Test
- public void testInvalidActionTypeDebug() {
- runner.disableControllerService(logHandler);
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE, "LOG");
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE_LEVEL, "IGNORE");
- runner.enableControllerService(logHandler);
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- attributes.put("logLevel", "FAKE");
-
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: Rules Action Triggered Log.\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("FAKE");
- action.setAttributes(attributes);
-
- assertDoesNotThrow(() -> logHandler.execute(action, metrics));
-
- final String debugMessage = mockComponentLog.getDebugMessage();
- assertTrue(StringUtils.isNotEmpty(debugMessage));
- assertEquals("This Action Handler does not support actions with the provided type: FAKE",debugMessage);
- }
-
- @Test
- public void testValidActionType() {
- runner.disableControllerService(logHandler);
- runner.setProperty(logHandler, AlertHandler.ENFORCE_ACTION_TYPE, "LOG");
- runner.enableControllerService(logHandler);
-
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
-
- attributes.put("logLevel", "FAKE");
-
- final String expectedMessage = "--------------------------------------------------\n" +
- "Log Message: Rules Action Triggered Log.\n" +
- "Log Facts:\n" +
- "Field: cpu, Value: 90\n" +
- "Field: jvmHeap, Value: 1000000";
-
- metrics.put("jvmHeap", "1000000");
- metrics.put("cpu", "90");
-
- final Action action = new Action();
- action.setType("LOG");
- action.setAttributes(attributes);
-
- assertDoesNotThrow(() -> logHandler.execute(action, metrics));
- }
-
- private static class MockLogHandler extends LogHandler {
- private ComponentLog testLogger;
-
- public MockLogHandler(ComponentLog testLogger) {
- this.testLogger = testLogger;
- }
-
- @Override
- protected ComponentLog getLogger() {
- return testLogger;
- }
- }
-
-
-}
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestProcessor.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestProcessor.java
deleted file mode 100644
index 43ad6fff00..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestProcessor.java
+++ /dev/null
@@ -1,46 +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.rules.handlers;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.processor.AbstractProcessor;
-import org.apache.nifi.processor.ProcessContext;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.exception.ProcessException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TestProcessor extends AbstractProcessor {
-
- @Override
- public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
- }
-
- @Override
- protected List getSupportedPropertyDescriptors() {
- List properties = new ArrayList<>();
- properties.add(new PropertyDescriptor.Builder()
- .name("log-action-handler-test")
- .description("Logging Action Handler")
- .identifiesControllerService(LogHandler.class)
- .required(true)
- .build());
- return properties;
- }
-
-}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestRecordSinkHandler.java b/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestRecordSinkHandler.java
deleted file mode 100644
index fb5f342200..0000000000
--- a/nifi-nar-bundles/nifi-rules-action-handler-bundle/nifi-rules-action-handler-service/src/test/java/org/apache/nifi/rules/handlers/TestRecordSinkHandler.java
+++ /dev/null
@@ -1,152 +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.rules.handlers;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.components.AbstractConfigurableComponent;
-import org.apache.nifi.controller.ControllerServiceInitializationContext;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.record.sink.RecordSinkService;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.rules.Action;
-import org.apache.nifi.serialization.WriteResult;
-import org.apache.nifi.serialization.record.Record;
-import org.apache.nifi.serialization.record.RecordSchema;
-import org.apache.nifi.serialization.record.RecordSet;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class TestRecordSinkHandler {
- private TestRunner runner;
- private MockComponentLog mockComponentLog;
- private RecordSinkHandler recordSinkHandler;
- private MockRecordSinkService recordSinkService;
-
- @BeforeEach
- public void setup() throws InitializationException {
- runner = TestRunners.newTestRunner(TestProcessor.class);
- mockComponentLog = new MockComponentLog();
- RecordSinkHandler handler = new MockRecordSinkHandler(mockComponentLog);
- recordSinkService = new MockRecordSinkService();
- runner.addControllerService("MockRecordSinkService", recordSinkService);
- runner.enableControllerService(recordSinkService);
- runner.addControllerService("MockRecordSinkHandler", handler);
- runner.setProperty(handler, MockRecordSinkHandler.RECORD_SINK_SERVICE,"MockRecordSinkService");
- runner.enableControllerService(handler);
- recordSinkHandler = (RecordSinkHandler) runner.getProcessContext()
- .getControllerServiceLookup()
- .getControllerService("MockRecordSinkHandler");
- }
-
- @Test
- public void testValidService() {
- runner.assertValid(recordSinkHandler);
- assertThat(recordSinkHandler, instanceOf(RecordSinkHandler.class));
- }
-
- @Test
- public void testRecordSendViaSink() throws InitializationException, IOException {
- final Map attributes = new HashMap<>();
- final Map metrics = new HashMap<>();
- final String expectedMessage = "Records written to sink service:";
- final BigDecimal bigDecimalValue = new BigDecimal(String.join("", Collections.nCopies(400, "1")) + ".2");
-
- attributes.put("sendZeroResults","false");
- metrics.put("jvmHeap","1000000");
- metrics.put("cpu","90");
- metrics.put("custom", bigDecimalValue);
-
- final Action action = new Action();
- action.setType("SEND");
- action.setAttributes(attributes);
- recordSinkHandler.execute(action, metrics);
- String logMessage = mockComponentLog.getDebugMessage();
- List