use of org.apache.nifi.processor.Processor in project nifi by apache.
the class StandardProcessorNode method yield.
/**
* Causes the processor not to be scheduled for some period of time. This
* duration can be obtained and set via the
* {@link #getYieldPeriod(TimeUnit)} and
* {@link #setYieldPeriod(long, TimeUnit)} methods.
*/
@Override
public void yield() {
final Processor processor = processorRef.get().getProcessor();
final long yieldMillis = getYieldPeriod(TimeUnit.MILLISECONDS);
yield(yieldMillis, TimeUnit.MILLISECONDS);
final String yieldDuration = (yieldMillis > 1000) ? (yieldMillis / 1000) + " seconds" : yieldMillis + " milliseconds";
LoggerFactory.getLogger(processor.getClass()).debug("{} has chosen to yield its resources; will not be scheduled to run again for {}", processor, yieldDuration);
}
use of org.apache.nifi.processor.Processor in project nifi by apache.
the class StandardProcessorNode method onTrigger.
@Override
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) {
final Processor processor = processorRef.get().getProcessor();
activateThread();
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(processor.getClass(), processor.getIdentifier())) {
processor.onTrigger(context, sessionFactory);
} finally {
deactivateThread();
}
}
use of org.apache.nifi.processor.Processor in project nifi by apache.
the class StandardProcessorNode method start.
/**
* Will idempotently start the processor using the following sequence: <i>
* <ul>
* <li>Validate Processor's state (e.g., PropertyDescriptors,
* ControllerServices etc.)</li>
* <li>Transition (atomically) Processor's scheduled state form STOPPED to
* STARTING. If the above state transition succeeds, then execute the start
* task (asynchronously) which will be re-tried until @OnScheduled is
* executed successfully and "schedulingAgentCallback' is invoked, or until
* STOP operation is initiated on this processor. If state transition fails
* it means processor is already being started and WARN message will be
* logged explaining it.</li>
* </ul>
* </i>
* <p>
* Any exception thrown while invoking operations annotated with @OnSchedule
* will be caught and logged after which @OnUnscheduled operation will be
* invoked (quietly) and the start sequence will be repeated (re-try) after
* delay provided by 'administrativeYieldMillis'.
* </p>
* <p>
* Upon successful completion of start sequence (@OnScheduled ->
* 'schedulingAgentCallback') the attempt will be made to transition
* processor's scheduling state to RUNNING at which point processor is
* considered to be fully started and functioning. If upon successful
* invocation of @OnScheduled operation the processor can not be
* transitioned to RUNNING state (e.g., STOP operation was invoked on the
* processor while it's @OnScheduled operation was executing), the
* processor's @OnUnscheduled operation will be invoked and its scheduling
* state will be set to STOPPED at which point the processor is considered
* to be fully stopped.
* </p>
*/
@Override
public void start(final ScheduledExecutorService taskScheduler, final long administrativeYieldMillis, final ProcessContext processContext, final SchedulingAgentCallback schedulingAgentCallback, final boolean failIfStopping) {
if (!this.isValid()) {
throw new IllegalStateException("Processor " + this.getName() + " is not in a valid state due to " + this.getValidationErrors());
}
final Processor processor = processorRef.get().getProcessor();
final ComponentLog procLog = new SimpleProcessLogger(StandardProcessorNode.this.getIdentifier(), processor);
ScheduledState currentState;
boolean starting;
synchronized (this) {
currentState = this.scheduledState.get();
if (currentState == ScheduledState.STOPPED) {
starting = this.scheduledState.compareAndSet(ScheduledState.STOPPED, ScheduledState.STARTING);
if (starting) {
desiredState = ScheduledState.RUNNING;
}
} else if (currentState == ScheduledState.STOPPING && !failIfStopping) {
desiredState = ScheduledState.RUNNING;
return;
} else {
starting = false;
}
}
if (starting) {
// will ensure that the Processor represented by this node can only be started once
initiateStart(taskScheduler, administrativeYieldMillis, processContext, schedulingAgentCallback);
} else {
final String procName = processorRef.get().toString();
LOG.warn("Cannot start {} because it is not currently stopped. Current state is {}", procName, currentState);
procLog.warn("Cannot start {} because it is not currently stopped. Current state is {}", new Object[] { procName, currentState });
}
}
use of org.apache.nifi.processor.Processor in project nifi by apache.
the class StandardProcessorNode method getProcessorDescription.
/**
* @return the value of the processor's {@link CapabilityDescription}
* annotation, if one exists, else <code>null</code>.
*/
public String getProcessorDescription() {
final Processor processor = processorRef.get().getProcessor();
final CapabilityDescription capDesc = processor.getClass().getAnnotation(CapabilityDescription.class);
String description = null;
if (capDesc != null) {
description = capDesc.value();
}
return description;
}
use of org.apache.nifi.processor.Processor in project nifi by apache.
the class FlowController method createProcessor.
/**
* <p>
* Creates a new ProcessorNode with the given type and identifier and
* optionally initializes it.
* </p>
*
* @param type the fully qualified Processor class name
* @param id the unique ID of the Processor
* @param coordinate the bundle coordinate for this processor
* @param firstTimeAdded whether or not this is the first time this
* Processor is added to the graph. If {@code true}, will invoke methods
* annotated with the {@link OnAdded} annotation.
* @return new processor node
* @throws NullPointerException if either arg is null
* @throws ProcessorInstantiationException if the processor cannot be
* instantiated for any reason
*/
public ProcessorNode createProcessor(final String type, String id, final BundleCoordinate coordinate, final Set<URL> additionalUrls, final boolean firstTimeAdded, final boolean registerLogObserver) throws ProcessorInstantiationException {
id = id.intern();
boolean creationSuccessful;
LoggableComponent<Processor> processor;
try {
processor = instantiateProcessor(type, id, coordinate, additionalUrls);
creationSuccessful = true;
} catch (final ProcessorInstantiationException pie) {
LOG.error("Could not create Processor of type " + type + " for ID " + id + "; creating \"Ghost\" implementation", pie);
final GhostProcessor ghostProc = new GhostProcessor();
ghostProc.setIdentifier(id);
ghostProc.setCanonicalClassName(type);
processor = new LoggableComponent<>(ghostProc, coordinate, null);
creationSuccessful = false;
}
final ComponentVariableRegistry componentVarRegistry = new StandardComponentVariableRegistry(this.variableRegistry);
final ValidationContextFactory validationContextFactory = new StandardValidationContextFactory(controllerServiceProvider, componentVarRegistry);
final ProcessorNode procNode;
if (creationSuccessful) {
procNode = new StandardProcessorNode(processor, id, validationContextFactory, processScheduler, controllerServiceProvider, nifiProperties, componentVarRegistry, this);
} else {
final String simpleClassName = type.contains(".") ? StringUtils.substringAfterLast(type, ".") : type;
final String componentType = "(Missing) " + simpleClassName;
procNode = new StandardProcessorNode(processor, id, validationContextFactory, processScheduler, controllerServiceProvider, componentType, type, nifiProperties, componentVarRegistry, this, true);
}
final LogRepository logRepository = LogRepositoryFactory.getRepository(id);
if (registerLogObserver) {
logRepository.addObserver(StandardProcessorNode.BULLETIN_OBSERVER_ID, LogLevel.WARN, new ProcessorLogObserver(getBulletinRepository(), procNode));
}
try {
final Class<?> procClass = procNode.getProcessor().getClass();
if (procClass.isAnnotationPresent(DefaultSettings.class)) {
DefaultSettings ds = procClass.getAnnotation(DefaultSettings.class);
try {
procNode.setYieldPeriod(ds.yieldDuration());
} catch (Throwable ex) {
LOG.error(String.format("Error while setting yield period from DefaultSettings annotation:%s", ex.getMessage()), ex);
}
try {
procNode.setPenalizationPeriod(ds.penaltyDuration());
} catch (Throwable ex) {
LOG.error(String.format("Error while setting penalty duration from DefaultSettings annotation:%s", ex.getMessage()), ex);
}
// the caller said to register the log observer, otherwise we could be changing the level when we didn't mean to
if (registerLogObserver) {
try {
procNode.setBulletinLevel(ds.bulletinLevel());
} catch (Throwable ex) {
LOG.error(String.format("Error while setting bulletin level from DefaultSettings annotation:%s", ex.getMessage()), ex);
}
}
}
} catch (Throwable ex) {
LOG.error(String.format("Error while setting default settings from DefaultSettings annotation: %s", ex.getMessage()), ex);
}
if (firstTimeAdded) {
try (final NarCloseable x = NarCloseable.withComponentNarLoader(procNode.getProcessor().getClass(), procNode.getProcessor().getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnAdded.class, procNode.getProcessor());
} catch (final Exception e) {
if (registerLogObserver) {
logRepository.removeObserver(StandardProcessorNode.BULLETIN_OBSERVER_ID);
}
throw new ComponentLifeCycleException("Failed to invoke @OnAdded methods of " + procNode.getProcessor(), e);
}
if (firstTimeAdded) {
try (final NarCloseable nc = NarCloseable.withComponentNarLoader(procNode.getProcessor().getClass(), procNode.getProcessor().getIdentifier())) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnConfigurationRestored.class, procNode.getProcessor());
}
}
}
return procNode;
}
Aggregations