You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ex...@apache.org on 2022/07/23 15:56:28 UTC

[nifi] branch main updated: NIFI-9817 Added Unit Validator to PutCloudWatchMetric

This is an automated email from the ASF dual-hosted git repository.

exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 0cd438d9e9 NIFI-9817 Added Unit Validator to PutCloudWatchMetric
0cd438d9e9 is described below

commit 0cd438d9e9b6826a4166200e2efeda0b8db0de92
Author: patalwell <pa...@gmail.com>
AuthorDate: Sat Mar 26 17:08:44 2022 -0700

    NIFI-9817 Added Unit Validator to PutCloudWatchMetric
    
    This closes #5905
    
    Signed-off-by: David Handermann <ex...@apache.org>
---
 .../aws/cloudwatch/PutCloudWatchMetric.java        |  23 ++++-
 .../aws/cloudwatch/ITPutCloudWatchMetric.java      |  19 ++--
 .../aws/cloudwatch/TestPutCloudWatchMetric.java    | 111 +++++++++++++++------
 3 files changed, 114 insertions(+), 39 deletions(-)

diff --git a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/main/java/org/apache/nifi/processors/aws/cloudwatch/PutCloudWatchMetric.java b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/main/java/org/apache/nifi/processors/aws/cloudwatch/PutCloudWatchMetric.java
index f0273e5178..5c6fd706f7 100644
--- a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/main/java/org/apache/nifi/processors/aws/cloudwatch/PutCloudWatchMetric.java
+++ b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/main/java/org/apache/nifi/processors/aws/cloudwatch/PutCloudWatchMetric.java
@@ -24,6 +24,7 @@ import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.annotation.behavior.DynamicProperty;
@@ -56,6 +57,7 @@ import com.amazonaws.services.cloudwatch.model.MetricDatum;
 import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest;
 import com.amazonaws.services.cloudwatch.model.PutMetricDataResult;
 import com.amazonaws.services.cloudwatch.model.StatisticSet;
+import com.amazonaws.services.cloudwatch.model.StandardUnit;
 
 @SupportsBatching
 @InputRequirement(Requirement.INPUT_REQUIRED)
@@ -70,6 +72,25 @@ public class PutCloudWatchMetric extends AbstractAWSCredentialsProviderProcessor
     public static final Set<Relationship> relationships = Collections.unmodifiableSet(
             new HashSet<>(Arrays.asList(REL_SUCCESS, REL_FAILURE)));
 
+    public static final Set<String> units = Arrays.stream(StandardUnit.values())
+            .map(StandardUnit::toString).collect(Collectors.toSet());
+
+    private static final Validator UNIT_VALIDATOR = new Validator() {
+        @Override
+        public ValidationResult validate(String subject, String input, ValidationContext context) {
+            if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input)) {
+                return (new ValidationResult.Builder()).subject(subject).input(input).explanation("Expression Language Present").valid(true).build();
+            } else {
+                String reason = null;
+
+                if (!units.contains(input)) {
+                    reason = "not a valid Unit";
+                }
+                return (new ValidationResult.Builder()).subject(subject).input(input).explanation(reason).valid(reason == null).build();
+            }
+        }
+    };
+
     private static final Validator DOUBLE_VALIDATOR = new Validator() {
         @Override
         public ValidationResult validate(String subject, String input, ValidationContext context) {
@@ -131,7 +152,7 @@ public class PutCloudWatchMetric extends AbstractAWSCredentialsProviderProcessor
             .description("The unit of the metric. (e.g Seconds, Bytes, Megabytes, Percent, Count,  Kilobytes/Second, Terabits/Second, Count/Second) For details see http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html")
             .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
             .required(false)
-            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .addValidator(UNIT_VALIDATOR)
             .build();
 
     public static final PropertyDescriptor MAXIMUM = new PropertyDescriptor.Builder()
diff --git a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/ITPutCloudWatchMetric.java b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/ITPutCloudWatchMetric.java
index a0610e8ee5..2717a18d10 100644
--- a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/ITPutCloudWatchMetric.java
+++ b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/ITPutCloudWatchMetric.java
@@ -16,25 +16,30 @@
  */
 package org.apache.nifi.processors.aws.cloudwatch;
 
+import java.io.File;
+import java.io.IOException;
+
 import org.apache.nifi.processors.aws.AbstractAWSCredentialsProviderProcessor;
 import org.apache.nifi.processors.aws.credentials.provider.service.AWSCredentialsProviderControllerService;
 import org.apache.nifi.processors.aws.sns.PutSNS;
 import org.apache.nifi.util.TestRunner;
 import org.apache.nifi.util.TestRunners;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
 import org.junit.jupiter.api.Test;
 
-import java.io.IOException;
-
 /**
- * Provides integration level testing with actual AWS CloudWatch resources for {@link PutCloudWatchMetric} and requires additional configuration and resources to work.
+ * Provides integration level testing with actual AWS CloudWatch resources for
+ * {@link PutCloudWatchMetric} and requires additional configuration and resources to work.
  */
 public class ITPutCloudWatchMetric {
 
     private final String CREDENTIALS_FILE = System.getProperty("user.home") + "/aws-credentials.properties";
 
     @Test
-    public void testPublish() throws IOException {
+    public void ifCredentialsThenTestPublish() throws IOException {
         final TestRunner runner = TestRunners.newTestRunner(new PutCloudWatchMetric());
+        File credsFile = new File(CREDENTIALS_FILE);
+        assumeTrue(credsFile.exists());
 
         runner.setProperty(PutCloudWatchMetric.NAMESPACE, "Test");
         runner.setProperty(PutCloudWatchMetric.METRIC_NAME, "Test");
@@ -48,8 +53,10 @@ public class ITPutCloudWatchMetric {
     }
 
     @Test
-    public void testPublishWithCredentialsProviderService() throws Throwable {
+    public void ifCredentialsThenTestPublishWithCredentialsProviderService() throws Throwable {
         final TestRunner runner = TestRunners.newTestRunner(new PutCloudWatchMetric());
+        File credsFile = new File(CREDENTIALS_FILE);
+        assumeTrue(credsFile.exists());
 
         final AWSCredentialsProviderControllerService serviceImpl = new AWSCredentialsProviderControllerService();
         runner.addControllerService("awsCredentialsProvider", serviceImpl);
@@ -69,4 +76,4 @@ public class ITPutCloudWatchMetric {
 
         runner.assertAllFlowFilesTransferred(PutCloudWatchMetric.REL_SUCCESS, 1);
     }
-}
+}
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/TestPutCloudWatchMetric.java b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/TestPutCloudWatchMetric.java
index 868b0d59da..a0cfcd518c 100644
--- a/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/TestPutCloudWatchMetric.java
+++ b/nifi-nar-bundles/nifi-aws-bundle/nifi-aws-processors/src/test/java/org/apache/nifi/processors/aws/cloudwatch/TestPutCloudWatchMetric.java
@@ -16,20 +16,24 @@
  */
 package org.apache.nifi.processors.aws.cloudwatch;
 
-import com.amazonaws.services.cloudwatch.model.Dimension;
-import com.amazonaws.services.cloudwatch.model.InvalidParameterValueException;
-import com.amazonaws.services.cloudwatch.model.MetricDatum;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.util.TestRunner;
-import org.apache.nifi.util.TestRunners;
-import org.junit.jupiter.api.Test;
-
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.HashMap;
+import java.util.stream.Stream;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.util.TestRunner;
+import org.apache.nifi.util.TestRunners;
 
+import com.amazonaws.services.cloudwatch.model.Dimension;
+import com.amazonaws.services.cloudwatch.model.MetricDatum;
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Unit tests for {@link PutCloudWatchMetric}.
@@ -37,7 +41,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 public class TestPutCloudWatchMetric {
 
     @Test
-    public void testPutSimpleMetric() throws Exception {
+    public void testPutSimpleMetric() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -60,7 +64,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testValueLiteralDoubleInvalid() throws Exception {
+    public void testValueLiteralDoubleInvalid() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -71,7 +75,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testMissingBothValueAndStatisticSetInvalid() throws Exception {
+    public void testMissingBothValueAndStatisticSetInvalid() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -81,7 +85,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testContainsBothValueAndStatisticSetInvalid() throws Exception {
+    public void testContainsBothValueAndStatisticSetInvalid() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -98,7 +102,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testContainsIncompleteStatisticSetInvalid() throws Exception {
+    public void testContainsIncompleteStatisticSetInvalid() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -114,7 +118,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testContainsBothValueAndIncompleteStatisticSetInvalid() throws Exception {
+    public void testContainsBothValueAndIncompleteStatisticSetInvalid() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -128,7 +132,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testMetricExpressionValid() throws Exception {
+    public void testMetricExpressionValid() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -151,7 +155,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testStatisticSet() throws Exception {
+    public void testStatisticSet() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -183,7 +187,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testDimensions() throws Exception {
+    public void testDimensions() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -218,7 +222,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testMaximumDimensions() throws Exception {
+    public void testMaximumDimensions() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -234,7 +238,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testTooManyDimensions() throws Exception {
+    public void testTooManyDimensions() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -250,7 +254,7 @@ public class TestPutCloudWatchMetric {
     }
 
     @Test
-    public void testMetricExpressionInvalidRoutesToFailure() throws Exception {
+    public void testMetricExpressionInvalidRoutesToFailure() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -268,27 +272,38 @@ public class TestPutCloudWatchMetric {
         runner.assertAllFlowFilesTransferred(PutCloudWatchMetric.REL_FAILURE, 1);
     }
 
-    @Test
-    public void testInvalidUnitRoutesToFailure() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"nan","percent","count"})
+    public void testInvalidUnit(String unit) {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
-        mockPutCloudWatchMetric.throwException = new InvalidParameterValueException("Unit error message");
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
         runner.setProperty(PutCloudWatchMetric.NAMESPACE, "TestNamespace");
         runner.setProperty(PutCloudWatchMetric.METRIC_NAME, "TestMetric");
-        runner.setProperty(PutCloudWatchMetric.UNIT, "BogusUnit");
-        runner.setProperty(PutCloudWatchMetric.VALUE, "1");
-        runner.assertValid();
+        runner.setProperty(PutCloudWatchMetric.UNIT, unit);
+        runner.setProperty(PutCloudWatchMetric.VALUE, "1.0");
+        runner.assertNotValid();
+    }
 
-        runner.enqueue(new byte[] {});
-        runner.run();
+    private static Stream<Arguments> data() {
+        return PutCloudWatchMetric.units.stream().map(Arguments::of);
+    }
 
-        assertEquals(1, mockPutCloudWatchMetric.putMetricDataCallCount);
-        runner.assertAllFlowFilesTransferred(PutCloudWatchMetric.REL_FAILURE, 1);
+    @ParameterizedTest
+    @MethodSource("data")
+    public void testValidUnit(String unit) {
+        MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
+        final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
+
+        runner.setProperty(PutCloudWatchMetric.NAMESPACE, "TestNamespace");
+        runner.setProperty(PutCloudWatchMetric.METRIC_NAME, "TestMetric");
+        runner.setProperty(PutCloudWatchMetric.UNIT, unit);
+        runner.setProperty(PutCloudWatchMetric.VALUE, "1");
+        runner.assertValid();
     }
 
     @Test
-    public void testTimestampExpressionInvalidRoutesToFailure() throws Exception {
+    public void testTimestampExpressionInvalidRoutesToFailure() {
         MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
         final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
 
@@ -308,4 +323,36 @@ public class TestPutCloudWatchMetric {
         runner.assertAllFlowFilesTransferred(PutCloudWatchMetric.REL_FAILURE, 1);
     }
 
+
+    @ParameterizedTest
+    @CsvSource({"null","us-west-100","us-east-a"})
+    public void testInvalidRegion(String region) {
+        MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
+        final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
+
+        runner.setProperty(PutCloudWatchMetric.NAMESPACE, "Test");
+        runner.setProperty(PutCloudWatchMetric.METRIC_NAME, "Test");
+        runner.setProperty(PutCloudWatchMetric.VALUE, "6");
+        runner.setProperty(PutCloudWatchMetric.REGION, region);
+        runner.assertNotValid();
+    }
+
+    @ParameterizedTest
+    @CsvSource({"us-east-1","us-west-1","us-east-2"})
+    public void testValidRegionRoutesToSuccess(String region) {
+        MockPutCloudWatchMetric mockPutCloudWatchMetric = new MockPutCloudWatchMetric();
+        final TestRunner runner = TestRunners.newTestRunner(mockPutCloudWatchMetric);
+
+        runner.setProperty(PutCloudWatchMetric.NAMESPACE, "Test");
+        runner.setProperty(PutCloudWatchMetric.METRIC_NAME, "Test");
+        runner.setProperty(PutCloudWatchMetric.VALUE, "6");
+        runner.setProperty(PutCloudWatchMetric.REGION, region);
+        runner.assertValid();
+
+        runner.enqueue(new byte[] {});
+        runner.run();
+
+        assertEquals(1, mockPutCloudWatchMetric.putMetricDataCallCount);
+        runner.assertAllFlowFilesTransferred(PutCloudWatchMetric.REL_SUCCESS, 1);
+    }
 }
\ No newline at end of file