use of org.apache.nifi.components.ValidationContext in project nifi by apache.
the class AvroSchemaRegistry method customValidate.
@Override
protected Collection<ValidationResult> customValidate(ValidationContext validationContext) {
Set<ValidationResult> results = new HashSet<>();
boolean strict = validationContext.getProperty(VALIDATE_FIELD_NAMES).asBoolean();
// Iterate over dynamic properties, validating the schemas, and adding results
validationContext.getProperties().entrySet().stream().filter(entry -> entry.getKey().isDynamic()).forEach(entry -> {
String subject = entry.getKey().getDisplayName();
String input = entry.getValue();
try {
final Schema avroSchema = new Schema.Parser().setValidate(strict).parse(input);
AvroTypeUtil.createSchema(avroSchema, input, SchemaIdentifier.EMPTY);
} catch (final Exception e) {
results.add(new ValidationResult.Builder().input(input).subject(subject).valid(false).explanation("Not a valid Avro Schema: " + e.getMessage()).build());
}
});
return results;
}
use of org.apache.nifi.components.ValidationContext in project nifi by apache.
the class NotificationServiceManager method loadNotificationServices.
/**
* Loads the Notification Services from the given XML configuration file.
*
* File is expected to have the following format:
*
* <pre>
* <services>
* <service>
* <id>service-identifier</id>
* <class>org.apache.nifi.MyNotificationService</class>
* <property name="My First Property">Property Value</property>
* </service>
* <service>
* <id>other-service</id>
* <class>org.apache.nifi.MyOtherNotificationService</class>
* <property name="Another Property">Property Value 2</property>
* </service>
* ...
* <service>
* <id>service-identifier-2</id>
* <class>org.apache.nifi.FinalNotificationService</class>
* <property name="Yet Another Property">3rd Prop Value</property>
* </service>
* </services>
* </pre>
*
* Note that as long as the file can be interpreted properly, a misconfigured service will result in a warning
* or error being logged and the service will be unavailable but will not prevent the rest of the services from loading.
*
* @param servicesFile the XML file to load services from.
* @throws IOException if unable to read from the given file
* @throws ParserConfigurationException if unable to parse the given file as XML properly
* @throws SAXException if unable to parse the given file properly
*/
public void loadNotificationServices(final File servicesFile) throws IOException, ParserConfigurationException, SAXException {
final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(false);
final DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
final Map<String, ConfiguredNotificationService> serviceMap = new HashMap<>();
try (final InputStream fis = new FileInputStream(servicesFile);
final InputStream in = new BufferedInputStream(fis)) {
final Document doc = docBuilder.parse(new InputSource(in));
final List<Element> serviceElements = getChildElementsByTagName(doc.getDocumentElement(), "service");
logger.debug("Found {} service elements", serviceElements.size());
for (final Element serviceElement : serviceElements) {
final ConfiguredNotificationService config = createService(serviceElement);
final NotificationService service = config.getService();
if (service == null) {
// reason will have already been logged, so just move on.
continue;
}
final String id = service.getIdentifier();
if (serviceMap.containsKey(id)) {
logger.error("Found two different Notification Services configured with the same ID: '{}'. Loaded the first service.", id);
continue;
}
// Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications
final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config), variableRegistry);
final Collection<ValidationResult> validationResults = service.validate(validationContext);
final List<String> invalidReasons = new ArrayList<>();
for (final ValidationResult result : validationResults) {
if (!result.isValid()) {
invalidReasons.add(result.toString());
}
}
if (!invalidReasons.isEmpty()) {
logger.warn("Configured Notification Service {} is not valid for the following reasons: {}", service, invalidReasons);
}
serviceMap.put(id, config);
}
}
logger.info("Successfully loaded the following {} services: {}", serviceMap.size(), serviceMap.keySet());
servicesById.clear();
servicesById.putAll(serviceMap);
}
use of org.apache.nifi.components.ValidationContext in project nifi by apache.
the class StandardProcessorTestRunner method assertValid.
@Override
public void assertValid(final ControllerService service) {
final StateManager serviceStateManager = controllerServiceStateManagers.get(service.getIdentifier());
if (serviceStateManager == null) {
throw new IllegalStateException("Controller Service has not been added to this TestRunner via the #addControllerService method");
}
final ValidationContext validationContext = new MockValidationContext(context, serviceStateManager, variableRegistry).getControllerServiceValidationContext(service);
final Collection<ValidationResult> results = context.getControllerService(service.getIdentifier()).validate(validationContext);
for (final ValidationResult result : results) {
if (!result.isValid()) {
Assert.fail("Expected Controller Service to be valid but it is invalid due to: " + result.toString());
}
}
}
use of org.apache.nifi.components.ValidationContext in project nifi by apache.
the class ITReportLineageToAtlas method test.
private void test(TestConfiguration tc) throws InitializationException, IOException {
final ReportLineageToAtlas reportingTask = new ReportLineageToAtlas();
final MockComponentLog logger = new MockComponentLog("reporting-task-id", reportingTask);
final ReportingInitializationContext initializationContext = mock(ReportingInitializationContext.class);
when(initializationContext.getLogger()).thenReturn(logger);
final ConfigurationContext configurationContext = new MockConfigurationContext(tc.properties, null);
final ValidationContext validationContext = mock(ValidationContext.class);
when(validationContext.getProperty(any())).then(invocation -> new MockPropertyValue(tc.properties.get(invocation.getArguments()[0])));
final ReportingContext reportingContext = mock(ReportingContext.class);
final MockStateManager stateManager = new MockStateManager(reportingTask);
final EventAccess eventAccess = mock(EventAccess.class);
when(reportingContext.getProperties()).thenReturn(tc.properties);
when(reportingContext.getProperty(any())).then(invocation -> new MockPropertyValue(tc.properties.get(invocation.getArguments()[0])));
when(reportingContext.getStateManager()).thenReturn(stateManager);
when(reportingContext.getEventAccess()).thenReturn(eventAccess);
when(eventAccess.getGroupStatus(eq("root"))).thenReturn(tc.rootPgStatus);
final ProvenanceRepository provenanceRepository = mock(ProvenanceRepository.class);
when(eventAccess.getControllerStatus()).thenReturn(tc.rootPgStatus);
when(eventAccess.getProvenanceRepository()).thenReturn(provenanceRepository);
when(eventAccess.getProvenanceEvents(eq(-1L), anyInt())).thenReturn(tc.provenanceRecords);
when(provenanceRepository.getMaxEventId()).thenReturn((long) tc.provenanceRecords.size() - 1);
when(provenanceRepository.getEvent(anyLong())).then(invocation -> tc.provenanceRecords.get(((Long) invocation.getArguments()[0]).intValue()));
// To mock this async method invocations, keep the requested event ids in a stack.
final ComputeLineageSubmission lineageComputationSubmission = mock(ComputeLineageSubmission.class);
when(provenanceRepository.submitLineageComputation(anyLong(), any())).thenAnswer(invocation -> {
requestedLineageComputationIds.push((Long) invocation.getArguments()[0]);
return lineageComputationSubmission;
});
when(lineageComputationSubmission.getResult()).then(invocation -> tc.lineageResults.get(requestedLineageComputationIds.pop()));
final ComputeLineageSubmission expandParentsSubmission = mock(ComputeLineageSubmission.class);
when(provenanceRepository.submitExpandParents(anyLong(), any())).thenAnswer(invocation -> {
requestedExpandParentsIds.push(((Long) invocation.getArguments()[0]));
return expandParentsSubmission;
});
when(expandParentsSubmission.getResult()).then(invocation -> tc.parentLineageResults.get(requestedExpandParentsIds.pop()));
tc.properties.put(ATLAS_NIFI_URL, "http://localhost:8080/nifi");
tc.properties.put(ATLAS_URLS, TARGET_ATLAS_URL);
tc.properties.put(ATLAS_USER, "admin");
tc.properties.put(ATLAS_PASSWORD, "admin");
tc.properties.put(new PropertyDescriptor.Builder().name("hostnamePattern.example").dynamic(true).build(), ".*");
reportingTask.initialize(initializationContext);
reportingTask.validate(validationContext);
reportingTask.setup(configurationContext);
reportingTask.onTrigger(reportingContext);
reportingTask.onUnscheduled();
reportingTask.onStopped();
}
use of org.apache.nifi.components.ValidationContext in project nifi by apache.
the class StandardValidators method createDataSizeBoundsValidator.
public static Validator createDataSizeBoundsValidator(final long minBytesInclusive, final long maxBytesInclusive) {
return new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(input)) {
return new ValidationResult.Builder().subject(subject).input(input).explanation("Expression Language Present").valid(true).build();
}
final ValidationResult vr = DATA_SIZE_VALIDATOR.validate(subject, input, context);
if (!vr.isValid()) {
return vr;
}
final long dataSizeBytes = DataUnit.parseDataSize(input, DataUnit.B).longValue();
if (dataSizeBytes < minBytesInclusive) {
return new ValidationResult.Builder().subject(subject).input(input).valid(false).explanation("Cannot be smaller than " + minBytesInclusive + " bytes").build();
}
if (dataSizeBytes > maxBytesInclusive) {
return new ValidationResult.Builder().subject(subject).input(input).valid(false).explanation("Cannot be larger than " + maxBytesInclusive + " bytes").build();
}
return new ValidationResult.Builder().subject(subject).input(input).valid(true).build();
}
};
}
Aggregations