blob: c527d0c13542ce247f16c7fd36458166d50f1930 [file] [log] [blame]
/*
* 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.tests.system;
import org.apache.nifi.components.ConfigVerificationResult;
import org.apache.nifi.components.ConfigVerificationResult.Outcome;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyDescriptor.Builder;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSession;
import org.apache.nifi.processor.VerifiableProcessor;
import org.apache.nifi.processor.exception.ProcessException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static org.apache.nifi.expression.ExpressionLanguageScope.FLOWFILE_ATTRIBUTES;
import static org.apache.nifi.processor.util.StandardValidators.POSITIVE_INTEGER_VALIDATOR;
public class EnsureProcessorConfigurationCorrect extends AbstractProcessor implements VerifiableProcessor {
static final PropertyDescriptor SUCCESSFUL_VERIFICATION = new Builder()
.name("Successful Verification")
.displayName("Successful Verification")
.description("Whether or not Verification should succeed")
.required(true)
.allowableValues("true", "false")
.build();
static final PropertyDescriptor VERIFICATION_STEPS = new Builder()
.name("Verification Steps")
.displayName("Verification Steps")
.description("The number of steps to use in the Verification")
.required(true)
.addValidator(POSITIVE_INTEGER_VALIDATOR)
.expressionLanguageSupported(FLOWFILE_ATTRIBUTES)
.defaultValue("1")
.build();
static final PropertyDescriptor EXCEPTION_ON_VERIFICATION = new Builder()
.name("Exception on Verification")
.displayName("Exception on Verification")
.description("If true, attempting to perform verification will throw a RuntimeException")
.required(true)
.allowableValues("true", "false")
.defaultValue("false")
.build();
static final PropertyDescriptor FAILURE_NODE_NUMBER = new Builder()
.name("Failure Node Number")
.displayName("Failure Node Number")
.description("The Node Number to Fail On")
.required(false)
.addValidator(POSITIVE_INTEGER_VALIDATOR)
.build();
@Override
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
return Arrays.asList(SUCCESSFUL_VERIFICATION, VERIFICATION_STEPS, EXCEPTION_ON_VERIFICATION, FAILURE_NODE_NUMBER);
}
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
}
@Override
public List<ConfigVerificationResult> verify(final ProcessContext context, final ComponentLog verificationLogger, final Map<String, String> attributes) {
final boolean exception = context.getProperty(EXCEPTION_ON_VERIFICATION).asBoolean();
if (exception) {
throw new RuntimeException("Intentional Exception - Processor was configured to throw an Exception when performing config verification");
}
final List<ConfigVerificationResult> results = new ArrayList<>();
final int iterations;
try {
iterations = context.getProperty(VERIFICATION_STEPS).evaluateAttributeExpressions(attributes).asInteger();
} catch (final NumberFormatException nfe) {
results.add(new ConfigVerificationResult.Builder()
.verificationStepName("Determine Number of Verification Steps")
.outcome(Outcome.FAILED)
.explanation("Invalid value for the number of Verification Steps")
.build());
return results;
}
final boolean success = context.getProperty(SUCCESSFUL_VERIFICATION).asBoolean();
final Outcome outcome = success ? Outcome.SUCCESSFUL : Outcome.FAILED;
for (int i=0; i < iterations; i++) {
results.add(new ConfigVerificationResult.Builder()
.verificationStepName("Verification Step #" + i)
.outcome(outcome)
.explanation("Verification Step #" + i)
.build());
}
// Consider the 'Failure Node Number' Property. This makes it easy to get different results from different nodes for testing purposes
final Integer failureNodeNum = context.getProperty(FAILURE_NODE_NUMBER).asInteger();
if (failureNodeNum == null) {
results.add(new ConfigVerificationResult.Builder()
.verificationStepName("Fail Based on Node Number")
.outcome(Outcome.SKIPPED)
.explanation("Not configured to Fail based on node number")
.build());
} else {
final String currentNodeNumberString = System.getProperty("nodeNumber");
final Integer currentNodeNumber = currentNodeNumberString == null ? null : Integer.parseInt(currentNodeNumberString);
final boolean shouldFail = Objects.equals(failureNodeNum, currentNodeNumber);
if (shouldFail) {
results.add(new ConfigVerificationResult.Builder()
.verificationStepName("Fail Based on Node Number")
.outcome(Outcome.FAILED)
.explanation("This node is Node Number " + currentNodeNumberString + " and configured to fail on this Node Number")
.build());
} else {
results.add(new ConfigVerificationResult.Builder()
.verificationStepName("Fail Based on Node Number")
.outcome(Outcome.SUCCESSFUL)
.explanation("This node is Node Number " + currentNodeNumberString + " and configured not to fail on this Node Number")
.build());
}
}
return results;
}
}