Search in sources :

Example 1 with ScriptEngineConfigurator

use of org.apache.nifi.processors.script.ScriptEngineConfigurator in project nifi by apache.

the class ScriptedLookupService method reloadScript.

/**
 * Reloads the script RecordReaderFactory. This must be called within the lock.
 *
 * @param scriptBody An input stream associated with the script content
 * @return Whether the script was successfully reloaded
 */
@Override
protected 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 LookupService from the script (if it exists)
            final Object obj = scriptEngine.get("lookupService");
            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("Scripted LookupService does not contain a setLogger method.");
                    }
                }
                // record the processor for use later
                final LookupService<Object> scriptedLookupService = invocable.getInterface(obj, LookupService.class);
                lookupService.set(scriptedLookupService);
                if (scriptedLookupService != null) {
                    try {
                        scriptedLookupService.initialize(new ControllerServiceInitializationContext() {

                            @Override
                            public String getIdentifier() {
                                return ScriptedLookupService.this.getIdentifier();
                            }

                            @Override
                            public ComponentLog getLogger() {
                                return logger;
                            }

                            @Override
                            public StateManager getStateManager() {
                                return ScriptedLookupService.this.getStateManager();
                            }

                            @Override
                            public ControllerServiceLookup getControllerServiceLookup() {
                                return ScriptedLookupService.super.getControllerServiceLookup();
                            }

                            @Override
                            public String getKerberosServicePrincipal() {
                                return ScriptedLookupService.this.kerberosServicePrincipal;
                            }

                            @Override
                            public File getKerberosServiceKeytab() {
                                return ScriptedLookupService.this.kerberosServiceKeytab;
                            }

                            @Override
                            public File getKerberosConfigurationFile() {
                                return ScriptedLookupService.this.kerberosConfigFile;
                            }
                        });
                    } catch (final Exception e) {
                        logger.error("Unable to initialize scripted LookupService: " + e.getLocalizedMessage(), e);
                        throw new ProcessException(e);
                    }
                }
            } else {
                throw new ScriptException("No LookupService was defined by the script.");
            }
        } else {
            throw new ScriptException("Script engine is not Invocable, cannot be used for ScriptedLookupService");
        }
    } 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("ScriptedLookupServiceValidation").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();
}
Also used : ControllerServiceInitializationContext(org.apache.nifi.controller.ControllerServiceInitializationContext) ScriptEngineConfigurator(org.apache.nifi.processors.script.ScriptEngineConfigurator) ValidationResult(org.apache.nifi.components.ValidationResult) ComponentLog(org.apache.nifi.logging.ComponentLog) LookupFailureException(org.apache.nifi.lookup.LookupFailureException) ProcessException(org.apache.nifi.processor.exception.ProcessException) ScriptException(javax.script.ScriptException) Invocable(javax.script.Invocable) ScriptException(javax.script.ScriptException) ProcessException(org.apache.nifi.processor.exception.ProcessException) StateManager(org.apache.nifi.components.state.StateManager) File(java.io.File) ControllerServiceLookup(org.apache.nifi.controller.ControllerServiceLookup) HashSet(java.util.HashSet)

Example 2 with ScriptEngineConfigurator

use of org.apache.nifi.processors.script.ScriptEngineConfigurator in project nifi by apache.

the class ScriptedReader method reloadScript.

/**
 * Reloads the script RecordReaderFactory. This must be called within the lock.
 *
 * @param scriptBody An input stream associated with the script content
 * @return Whether the script was successfully reloaded
 */
protected 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("reader");
            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 RecordReaderFactory does not contain a setLogger method.");
                    }
                }
                if (configurationContext != null) {
                    try {
                        // set the logger if the processor wants it
                        invocable.invokeMethod(obj, "setConfigurationContext", configurationContext);
                    } catch (final NoSuchMethodException nsme) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Configured script RecordReaderFactory does not contain a setConfigurationContext method.");
                        }
                    }
                }
                // record the processor for use later
                final RecordReaderFactory scriptedReader = invocable.getInterface(obj, RecordReaderFactory.class);
                recordFactory.set(scriptedReader);
            } else {
                throw new ScriptException("No RecordReader 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();
}
Also used : ScriptEngineConfigurator(org.apache.nifi.processors.script.ScriptEngineConfigurator) ValidationResult(org.apache.nifi.components.ValidationResult) ComponentLog(org.apache.nifi.logging.ComponentLog) MalformedRecordException(org.apache.nifi.serialization.MalformedRecordException) IOException(java.io.IOException) SchemaNotFoundException(org.apache.nifi.schema.access.SchemaNotFoundException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) ScriptException(javax.script.ScriptException) RecordReaderFactory(org.apache.nifi.serialization.RecordReaderFactory) Invocable(javax.script.Invocable) ScriptException(javax.script.ScriptException) HashSet(java.util.HashSet)

Example 3 with ScriptEngineConfigurator

use of org.apache.nifi.processors.script.ScriptEngineConfigurator in project nifi by apache.

the class ScriptingComponentHelper method setupEngines.

/**
 * Configures the specified script engine. First, the engine is loaded and instantiated using the JSR-223
 * javax.script APIs. Then, if any script configurators have been defined for this engine, their init() method is
 * called, and the configurator is saved for future calls.
 *
 * @param numberOfScriptEngines number of engines to setup
 * @see org.apache.nifi.processors.script.ScriptEngineConfigurator
 */
protected void setupEngines(int numberOfScriptEngines, ComponentLog log) {
    engineQ = new LinkedBlockingQueue<>(numberOfScriptEngines);
    ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        if (StringUtils.isBlank(scriptEngineName)) {
            throw new IllegalArgumentException("The script engine name cannot be null");
        }
        ScriptEngineConfigurator configurator = scriptEngineConfiguratorMap.get(scriptEngineName.toLowerCase());
        // Get a list of URLs from the configurator (if present), or just convert modules from Strings to URLs
        URL[] additionalClasspathURLs = null;
        if (configurator != null) {
            additionalClasspathURLs = configurator.getModuleURLsForClasspath(modules, log);
        } else {
            if (modules != null) {
                List<URL> urls = new LinkedList<>();
                for (String modulePathString : modules) {
                    try {
                        urls.add(new File(modulePathString).toURI().toURL());
                    } catch (MalformedURLException mue) {
                        log.error("{} is not a valid file, ignoring", new Object[] { modulePathString }, mue);
                    }
                }
                additionalClasspathURLs = urls.toArray(new URL[urls.size()]);
            }
        }
        // Need the right classloader when the engine is created. This ensures the NAR's execution class loader
        // (plus the module path) becomes the parent for the script engine
        ClassLoader scriptEngineModuleClassLoader = additionalClasspathURLs != null ? new URLClassLoader(additionalClasspathURLs, originalContextClassLoader) : originalContextClassLoader;
        if (scriptEngineModuleClassLoader != null) {
            Thread.currentThread().setContextClassLoader(scriptEngineModuleClassLoader);
        }
        for (int i = 0; i < numberOfScriptEngines; i++) {
            ScriptEngine scriptEngine = createScriptEngine();
            try {
                if (configurator != null) {
                    configurator.init(scriptEngine, modules);
                }
                if (!engineQ.offer(scriptEngine)) {
                    log.error("Error adding script engine {}", new Object[] { scriptEngine.getFactory().getEngineName() });
                }
            } catch (ScriptException se) {
                log.error("Error initializing script engine configurator {}", new Object[] { scriptEngineName });
                if (log.isDebugEnabled()) {
                    log.error("Error initializing script engine configurator", se);
                }
            }
        }
    } finally {
        // Restore original context class loader
        Thread.currentThread().setContextClassLoader(originalContextClassLoader);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) ScriptEngineConfigurator(org.apache.nifi.processors.script.ScriptEngineConfigurator) URL(java.net.URL) LinkedList(java.util.LinkedList) ScriptEngine(javax.script.ScriptEngine) ScriptException(javax.script.ScriptException) URLClassLoader(java.net.URLClassLoader) URLClassLoader(java.net.URLClassLoader) File(java.io.File)

Example 4 with ScriptEngineConfigurator

use of org.apache.nifi.processors.script.ScriptEngineConfigurator in project nifi by apache.

the class ScriptedRecordSetWriter method reloadScript.

/**
 * Reloads the script RecordSetWriterFactory. This must be called within the lock.
 *
 * @param scriptBody An input stream associated with the script content
 * @return Whether the script was successfully reloaded
 */
@Override
protected 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("writer");
            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 RecordSetWriterFactory does not contain a setLogger method.");
                    }
                }
                if (configurationContext != null) {
                    try {
                        // set the logger if the processor wants it
                        invocable.invokeMethod(obj, "setConfigurationContext", configurationContext);
                    } catch (final NoSuchMethodException nsme) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Configured script RecordSetWriterFactory does not contain a setConfigurationContext method.");
                        }
                    }
                }
                // record the processor for use later
                final RecordSetWriterFactory scriptedWriter = invocable.getInterface(obj, RecordSetWriterFactory.class);
                recordFactory.set(scriptedWriter);
            } else {
                throw new ScriptException("No RecordSetWriterFactory 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();
}
Also used : ScriptEngineConfigurator(org.apache.nifi.processors.script.ScriptEngineConfigurator) ValidationResult(org.apache.nifi.components.ValidationResult) ComponentLog(org.apache.nifi.logging.ComponentLog) IOException(java.io.IOException) SchemaNotFoundException(org.apache.nifi.schema.access.SchemaNotFoundException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) ScriptException(javax.script.ScriptException) Invocable(javax.script.Invocable) ScriptException(javax.script.ScriptException) RecordSetWriterFactory(org.apache.nifi.serialization.RecordSetWriterFactory) HashSet(java.util.HashSet)

Example 5 with ScriptEngineConfigurator

use of org.apache.nifi.processors.script.ScriptEngineConfigurator in project nifi by apache.

the class ScriptedReportingTask method onTrigger.

@Override
public void onTrigger(final ReportingContext context) {
    synchronized (scriptingComponentHelper.isInitialized) {
        if (!scriptingComponentHelper.isInitialized.get()) {
            scriptingComponentHelper.createResources();
        }
    }
    ScriptEngine scriptEngine = scriptingComponentHelper.engineQ.poll();
    ComponentLog log = getLogger();
    if (scriptEngine == null) {
        // No engine available so nothing more to do here
        return;
    }
    try {
        try {
            Bindings bindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
            if (bindings == null) {
                bindings = new SimpleBindings();
            }
            bindings.put("context", context);
            bindings.put("log", log);
            bindings.put("vmMetrics", vmMetrics);
            // Find the user-added properties and set them on the script
            for (Map.Entry<PropertyDescriptor, String> property : context.getProperties().entrySet()) {
                if (property.getKey().isDynamic()) {
                    // Add the dynamic property bound to its full PropertyValue to the script engine
                    if (property.getValue() != null) {
                        bindings.put(property.getKey().getName(), context.getProperty(property.getKey()));
                    }
                }
            }
            scriptEngine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
            // Execute any engine-specific configuration before the script is evaluated
            ScriptEngineConfigurator configurator = scriptingComponentHelper.scriptEngineConfiguratorMap.get(scriptingComponentHelper.getScriptEngineName().toLowerCase());
            // Evaluate the script with the configurator (if it exists) or the engine
            if (configurator != null) {
                configurator.eval(scriptEngine, scriptToRun, scriptingComponentHelper.getModules());
            } else {
                scriptEngine.eval(scriptToRun);
            }
        } catch (ScriptException e) {
            throw new ProcessException(e);
        }
    } catch (final Throwable t) {
        // Mimic AbstractProcessor behavior here
        getLogger().error("{} failed to process due to {}; rolling back session", new Object[] { this, t });
        throw t;
    } finally {
        scriptingComponentHelper.engineQ.offer(scriptEngine);
    }
}
Also used : PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) ScriptEngineConfigurator(org.apache.nifi.processors.script.ScriptEngineConfigurator) ComponentLog(org.apache.nifi.logging.ComponentLog) Bindings(javax.script.Bindings) SimpleBindings(javax.script.SimpleBindings) ScriptEngine(javax.script.ScriptEngine) ScriptException(javax.script.ScriptException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SimpleBindings(javax.script.SimpleBindings) Map(java.util.Map)

Aggregations

ScriptException (javax.script.ScriptException)5 ScriptEngineConfigurator (org.apache.nifi.processors.script.ScriptEngineConfigurator)5 ComponentLog (org.apache.nifi.logging.ComponentLog)4 HashSet (java.util.HashSet)3 Invocable (javax.script.Invocable)3 ValidationResult (org.apache.nifi.components.ValidationResult)3 File (java.io.File)2 IOException (java.io.IOException)2 UndeclaredThrowableException (java.lang.reflect.UndeclaredThrowableException)2 ScriptEngine (javax.script.ScriptEngine)2 ProcessException (org.apache.nifi.processor.exception.ProcessException)2 SchemaNotFoundException (org.apache.nifi.schema.access.SchemaNotFoundException)2 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 URLClassLoader (java.net.URLClassLoader)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 Bindings (javax.script.Bindings)1 SimpleBindings (javax.script.SimpleBindings)1 PropertyDescriptor (org.apache.nifi.components.PropertyDescriptor)1