use of org.apache.nifi.logging.ComponentLog in project nifi by apache.
the class InvokeScriptedProcessor method getSupportedPropertyDescriptors.
/**
* Returns a list of property descriptors supported by this processor. The
* list always includes properties such as script engine name, script file
* name, script body name, script arguments, and an external module path. If
* the scripted processor also defines supported properties, those are added
* to the list as well.
*
* @return a List of PropertyDescriptor objects supported by this processor
*/
@Override
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
synchronized (scriptingComponentHelper.isInitialized) {
if (!scriptingComponentHelper.isInitialized.get()) {
scriptingComponentHelper.createResources();
}
}
List<PropertyDescriptor> supportedPropertyDescriptors = new ArrayList<>();
supportedPropertyDescriptors.addAll(scriptingComponentHelper.getDescriptors());
final Processor instance = processor.get();
if (instance != null) {
try {
final List<PropertyDescriptor> instanceDescriptors = instance.getPropertyDescriptors();
if (instanceDescriptors != null) {
supportedPropertyDescriptors.addAll(instanceDescriptors);
}
} catch (final Throwable t) {
final ComponentLog logger = getLogger();
final String message = "Unable to get property descriptors from Processor: " + t;
logger.error(message);
if (logger.isDebugEnabled()) {
logger.error(message, t);
}
}
}
return Collections.unmodifiableList(supportedPropertyDescriptors);
}
use of org.apache.nifi.logging.ComponentLog in project nifi by apache.
the class InvokeScriptedProcessor method reloadScript.
/**
* Reloads the script Processor. This must be called within the lock.
*
* @param scriptBody An input stream associated with the script content
* @return Whether the script was successfully reloaded
*/
private boolean reloadScript(final String scriptBody) {
// note we are starting here with a fresh listing of validation
// results since we are (re)loading a new/updated script. any
// existing validation results are not relevant
final Collection<ValidationResult> results = new HashSet<>();
try {
// get the engine and ensure its invocable
if (scriptEngine instanceof Invocable) {
final Invocable invocable = (Invocable) scriptEngine;
// Find a custom configurator and invoke their eval() method
ScriptEngineConfigurator configurator = scriptingComponentHelper.scriptEngineConfiguratorMap.get(scriptingComponentHelper.getScriptEngineName().toLowerCase());
if (configurator != null) {
configurator.eval(scriptEngine, scriptBody, scriptingComponentHelper.getModules());
} else {
// evaluate the script
scriptEngine.eval(scriptBody);
}
// get configured processor from the script (if it exists)
final Object obj = scriptEngine.get("processor");
if (obj != null) {
final ComponentLog logger = getLogger();
try {
// set the logger if the processor wants it
invocable.invokeMethod(obj, "setLogger", logger);
} catch (final NoSuchMethodException nsme) {
if (logger.isDebugEnabled()) {
logger.debug("Configured script Processor does not contain a setLogger method.");
}
}
// record the processor for use later
final Processor scriptProcessor = invocable.getInterface(obj, Processor.class);
processor.set(scriptProcessor);
if (scriptProcessor != null) {
try {
scriptProcessor.initialize(new ProcessorInitializationContext() {
@Override
public String getIdentifier() {
return InvokeScriptedProcessor.this.getIdentifier();
}
@Override
public ComponentLog getLogger() {
return logger;
}
@Override
public ControllerServiceLookup getControllerServiceLookup() {
return InvokeScriptedProcessor.super.getControllerServiceLookup();
}
@Override
public NodeTypeProvider getNodeTypeProvider() {
return InvokeScriptedProcessor.super.getNodeTypeProvider();
}
@Override
public String getKerberosServicePrincipal() {
return InvokeScriptedProcessor.this.kerberosServicePrincipal;
}
@Override
public File getKerberosServiceKeytab() {
return InvokeScriptedProcessor.this.kerberosServiceKeytab;
}
@Override
public File getKerberosConfigurationFile() {
return InvokeScriptedProcessor.this.kerberosConfigFile;
}
});
} catch (final Exception e) {
logger.error("Unable to initialize scripted Processor: " + e.getLocalizedMessage(), e);
throw new ProcessException(e);
}
}
} else {
throw new ScriptException("No processor was defined by the script.");
}
}
} catch (final Exception ex) {
final ComponentLog logger = getLogger();
final String message = "Unable to load script: " + ex.getLocalizedMessage();
logger.error(message, ex);
results.add(new ValidationResult.Builder().subject("ScriptValidation").valid(false).explanation("Unable to load script due to " + ex.getLocalizedMessage()).input(scriptingComponentHelper.getScriptPath()).build());
}
// store the updated validation results
validationResults.set(results);
// return whether there was any issues loading the configured script
return results.isEmpty();
}
use of org.apache.nifi.logging.ComponentLog in project nifi by apache.
the class InvokeScriptedProcessor method customValidate.
/**
* Invokes the validate() routine provided by the script, allowing for
* custom validation code. This method assumes there is a valid Processor
* defined in the script and it has been loaded by the
* InvokeScriptedProcessor processor
*
* @param context The validation context to be passed into the custom
* validate method
* @return A collection of ValidationResults returned by the custom validate
* method
*/
@Override
protected Collection<ValidationResult> customValidate(final ValidationContext context) {
Collection<ValidationResult> commonValidationResults = super.customValidate(context);
if (!commonValidationResults.isEmpty()) {
return commonValidationResults;
}
// and don't print anything into log.
if (validationResults.get() != null) {
return validationResults.get();
}
scriptingComponentHelper.setScriptEngineName(context.getProperty(scriptingComponentHelper.SCRIPT_ENGINE).getValue());
scriptingComponentHelper.setScriptPath(context.getProperty(ScriptingComponentUtils.SCRIPT_FILE).evaluateAttributeExpressions().getValue());
scriptingComponentHelper.setScriptBody(context.getProperty(ScriptingComponentUtils.SCRIPT_BODY).getValue());
String modulePath = context.getProperty(ScriptingComponentUtils.MODULES).evaluateAttributeExpressions().getValue();
if (!StringUtils.isEmpty(modulePath)) {
scriptingComponentHelper.setModules(modulePath.split(","));
} else {
scriptingComponentHelper.setModules(new String[0]);
}
setup();
// Now that InvokeScriptedProcessor is validated, we can call validate on the scripted processor
final Processor instance = processor.get();
final Collection<ValidationResult> currentValidationResults = validationResults.get();
// if there was existing validation errors and the processor loaded successfully
if (currentValidationResults.isEmpty() && instance != null) {
try {
// defer to the underlying processor for validation
final Collection<ValidationResult> instanceResults = instance.validate(context);
if (instanceResults != null && instanceResults.size() > 0) {
// return the validation results from the underlying instance
return instanceResults;
}
} catch (final Exception e) {
final ComponentLog logger = getLogger();
final String message = "Unable to validate the script Processor: " + e;
logger.error(message, e);
// return a new validation message
final Collection<ValidationResult> results = new HashSet<>();
results.add(new ValidationResult.Builder().subject("Validation").valid(false).explanation("An error occurred calling validate in the configured script Processor.").input(context.getProperty(ScriptingComponentUtils.SCRIPT_FILE).getValue()).build());
return results;
}
}
return currentValidationResults;
}
use of org.apache.nifi.logging.ComponentLog in project nifi by apache.
the class InvokeScriptedProcessor method reloadScriptFile.
/**
* Reloads the script located at the given path
*
* @param scriptPath the path to the script file to be loaded
* @return true if the script was loaded successfully; false otherwise
*/
private boolean reloadScriptFile(final String scriptPath) {
final Collection<ValidationResult> results = new HashSet<>();
try (final FileInputStream scriptStream = new FileInputStream(scriptPath)) {
return reloadScript(IOUtils.toString(scriptStream, Charset.defaultCharset()));
} catch (final Exception e) {
final ComponentLog logger = getLogger();
final String message = "Unable to load script: " + e;
logger.error(message, e);
results.add(new ValidationResult.Builder().subject("ScriptValidation").valid(false).explanation("Unable to load script due to " + e).input(scriptPath).build());
}
// store the updated validation results
validationResults.set(results);
// return whether there was any issues loading the configured script
return results.isEmpty();
}
use of org.apache.nifi.logging.ComponentLog in project nifi by apache.
the class InvokeScriptedProcessor method onTrigger.
/**
* Invokes the onTrigger() method of the scripted processor. If the script
* failed to reload, the processor yields until the script can be reloaded
* successfully. If the scripted processor's onTrigger() method throws an
* exception, a ProcessException will be thrown. If no processor is defined
* by the script, an error is logged with the system.
*
* @param context provides access to convenience methods for obtaining
* property values, delaying the scheduling of the processor, provides
* access to Controller Services, etc.
* @param sessionFactory provides access to a {@link ProcessSessionFactory},
* which can be used for accessing FlowFiles, etc.
* @throws ProcessException if the scripted processor's onTrigger() method
* throws an exception
*/
@Override
public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
// Initialize the rest of the processor resources if we have not already done so
synchronized (scriptingComponentHelper.isInitialized) {
if (!scriptingComponentHelper.isInitialized.get()) {
scriptingComponentHelper.createResources();
}
}
ComponentLog log = getLogger();
// ensure the processor (if it exists) is loaded
final Processor instance = processor.get();
// ensure the processor did not fail to reload at some point
final Collection<ValidationResult> results = validationResults.get();
if (!results.isEmpty()) {
log.error(String.format("Unable to run because the Processor is not valid: [%s]", StringUtils.join(results, ", ")));
context.yield();
return;
}
if (instance != null) {
try {
// run the processor
instance.onTrigger(context, sessionFactory);
} catch (final ProcessException e) {
final String message = String.format("An error occurred executing the configured Processor [%s]: %s", context.getProperty(ScriptingComponentUtils.SCRIPT_FILE).getValue(), e);
log.error(message);
throw e;
}
} else {
log.error("There is no processor defined by the script");
}
}
Aggregations