use of org.apache.nifi.processor.SimpleProcessLogger 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.SimpleProcessLogger in project nifi by apache.
the class StandardProcessScheduler method unschedule.
@Override
public void unschedule(final ReportingTaskNode taskNode) {
final LifecycleState lifecycleState = getLifecycleState(requireNonNull(taskNode), false);
if (!lifecycleState.isScheduled()) {
return;
}
taskNode.verifyCanStop();
final SchedulingAgent agent = getSchedulingAgent(taskNode.getSchedulingStrategy());
final ReportingTask reportingTask = taskNode.getReportingTask();
taskNode.setScheduledState(ScheduledState.STOPPED);
final Runnable unscheduleReportingTaskRunnable = new Runnable() {
@Override
public void run() {
final ConfigurationContext configurationContext = taskNode.getConfigurationContext();
synchronized (lifecycleState) {
lifecycleState.setScheduled(false);
try {
try (final NarCloseable x = NarCloseable.withComponentNarLoader(reportingTask.getClass(), reportingTask.getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnUnscheduled.class, reportingTask, configurationContext);
}
} catch (final Exception e) {
final Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e;
final ComponentLog componentLog = new SimpleProcessLogger(reportingTask.getIdentifier(), reportingTask);
componentLog.error("Failed to invoke @OnUnscheduled method due to {}", cause);
LOG.error("Failed to invoke the @OnUnscheduled methods of {} due to {}; administratively yielding this ReportingTask and will attempt to schedule it again after {}", reportingTask, cause.toString(), administrativeYieldDuration);
LOG.error("", cause);
try {
Thread.sleep(administrativeYieldMillis);
} catch (final InterruptedException ie) {
}
}
agent.unschedule(taskNode, lifecycleState);
if (lifecycleState.getActiveThreadCount() == 0 && lifecycleState.mustCallOnStoppedMethods()) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnStopped.class, reportingTask, configurationContext);
}
}
}
};
componentLifeCycleThreadPool.execute(unscheduleReportingTaskRunnable);
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class StandardControllerServiceProvider method createControllerService.
@Override
public ControllerServiceNode createControllerService(final String type, final String id, final BundleCoordinate bundleCoordinate, final Set<URL> additionalUrls, final boolean firstTimeAdded) {
if (type == null || id == null || bundleCoordinate == null) {
throw new NullPointerException();
}
ClassLoader cl = null;
final ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
try {
final Class<?> rawClass;
try {
final Bundle csBundle = ExtensionManager.getBundle(bundleCoordinate);
if (csBundle == null) {
throw new ControllerServiceInstantiationException("Unable to find bundle for coordinate " + bundleCoordinate.getCoordinate());
}
cl = ExtensionManager.createInstanceClassLoader(type, id, csBundle, additionalUrls);
Thread.currentThread().setContextClassLoader(cl);
rawClass = Class.forName(type, false, cl);
} catch (final Exception e) {
logger.error("Could not create Controller Service of type " + type + " for ID " + id + "; creating \"Ghost\" implementation", e);
Thread.currentThread().setContextClassLoader(currentContextClassLoader);
return createGhostControllerService(type, id, bundleCoordinate);
}
final Class<? extends ControllerService> controllerServiceClass = rawClass.asSubclass(ControllerService.class);
final ControllerService originalService = controllerServiceClass.newInstance();
final StandardControllerServiceInvocationHandler invocationHandler = new StandardControllerServiceInvocationHandler(originalService);
// extract all interfaces... controllerServiceClass is non null so getAllInterfaces is non null
final List<Class<?>> interfaceList = ClassUtils.getAllInterfaces(controllerServiceClass);
final Class<?>[] interfaces = interfaceList.toArray(new Class<?>[interfaceList.size()]);
final ControllerService proxiedService;
if (cl == null) {
proxiedService = (ControllerService) Proxy.newProxyInstance(getClass().getClassLoader(), interfaces, invocationHandler);
} else {
proxiedService = (ControllerService) Proxy.newProxyInstance(cl, interfaces, invocationHandler);
}
logger.info("Created Controller Service of type {} with identifier {}", type, id);
final ComponentLog serviceLogger = new SimpleProcessLogger(id, originalService);
final TerminationAwareLogger terminationAwareLogger = new TerminationAwareLogger(serviceLogger);
originalService.initialize(new StandardControllerServiceInitializationContext(id, terminationAwareLogger, this, getStateManager(id), nifiProperties));
final ValidationContextFactory validationContextFactory = new StandardValidationContextFactory(this, variableRegistry);
final LoggableComponent<ControllerService> originalLoggableComponent = new LoggableComponent<>(originalService, bundleCoordinate, terminationAwareLogger);
final LoggableComponent<ControllerService> proxiedLoggableComponent = new LoggableComponent<>(proxiedService, bundleCoordinate, terminationAwareLogger);
final ComponentVariableRegistry componentVarRegistry = new StandardComponentVariableRegistry(this.variableRegistry);
final ControllerServiceNode serviceNode = new StandardControllerServiceNode(originalLoggableComponent, proxiedLoggableComponent, invocationHandler, id, validationContextFactory, this, componentVarRegistry, flowController);
serviceNode.setName(rawClass.getSimpleName());
invocationHandler.setServiceNode(serviceNode);
if (firstTimeAdded) {
try (final NarCloseable x = NarCloseable.withComponentNarLoader(originalService.getClass(), originalService.getIdentifier())) {
ReflectionUtils.invokeMethodsWithAnnotation(OnAdded.class, originalService);
} catch (final Exception e) {
throw new ComponentLifeCycleException("Failed to invoke On-Added Lifecycle methods of " + originalService, e);
}
}
serviceCache.putIfAbsent(id, serviceNode);
return serviceNode;
} catch (final Throwable t) {
throw new ControllerServiceInstantiationException(t);
} finally {
if (currentContextClassLoader != null) {
Thread.currentThread().setContextClassLoader(currentContextClassLoader);
}
}
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class StandardStateManager method getLogger.
private ComponentLog getLogger(final String componentId) {
final LogRepository repo = LogRepositoryFactory.getRepository(componentId);
final ComponentLog logger = (repo == null) ? null : repo.getLogger();
if (repo == null || logger == null) {
return new SimpleProcessLogger(componentId, this);
}
return logger;
}
use of org.apache.nifi.processor.SimpleProcessLogger in project nifi by apache.
the class StandardStateManagerProvider method createStateProvider.
private static StateProvider createStateProvider(final File configFile, final Scope scope, final NiFiProperties properties, final VariableRegistry variableRegistry) throws ConfigParseException, IOException {
final String providerId;
final String providerIdPropertyName;
final String providerDescription;
final String providerXmlElementName;
final String oppositeScopeXmlElementName;
switch(scope) {
case CLUSTER:
providerId = properties.getClusterStateProviderId();
providerIdPropertyName = NiFiProperties.STATE_MANAGEMENT_CLUSTER_PROVIDER_ID;
providerDescription = "Cluster State Provider";
providerXmlElementName = "cluster-provider";
oppositeScopeXmlElementName = "local-provider";
break;
case LOCAL:
providerId = properties.getLocalStateProviderId();
providerIdPropertyName = NiFiProperties.STATE_MANAGEMENT_LOCAL_PROVIDER_ID;
providerDescription = "Local State Provider";
providerXmlElementName = "local-provider";
oppositeScopeXmlElementName = "cluster-provider";
break;
default:
throw new AssertionError("Attempted to create State Provider for unknown Scope: " + scope);
}
if (!configFile.exists()) {
throw new IllegalStateException("Cannot create " + providerDescription + " because the State Management Configuration File " + configFile + " does not exist");
}
if (!configFile.canRead()) {
throw new IllegalStateException("Cannot create " + providerDescription + " because the State Management Configuration File " + configFile + " cannot be read");
}
if (providerId == null) {
if (scope == Scope.CLUSTER) {
throw new IllegalStateException("Cannot create Cluster State Provider because the '" + providerIdPropertyName + "' property is missing from the NiFi Properties file. In order to run NiFi in a cluster, the " + providerIdPropertyName + " property must be configured in nifi.properties");
}
throw new IllegalStateException("Cannot create " + providerDescription + " because the '" + providerIdPropertyName + "' property is missing from the NiFi Properties file");
}
if (providerId.trim().isEmpty()) {
throw new IllegalStateException("Cannot create " + providerDescription + " because the '" + providerIdPropertyName + "' property in the NiFi Properties file has no value set. This is a required property and must reference the identifier of one of the " + providerXmlElementName + " elements in the State Management Configuration File (" + configFile + ")");
}
final StateManagerConfiguration config = StateManagerConfiguration.parse(configFile);
final StateProviderConfiguration providerConfig = config.getStateProviderConfiguration(providerId);
if (providerConfig == null) {
throw new IllegalStateException("Cannot create " + providerDescription + " because the '" + providerIdPropertyName + "' property in the NiFi Properties file is set to '" + providerId + "', but there is no " + providerXmlElementName + " entry in the State Management Configuration File (" + configFile + ") with this id");
}
if (providerConfig.getScope() != scope) {
throw new IllegalStateException("Cannot create " + providerDescription + " because the '" + providerIdPropertyName + "' property in the NiFi Properties file is set to '" + providerId + "', but this id is assigned to a " + oppositeScopeXmlElementName + " entry in the State Management Configuration File (" + configFile + "), rather than a " + providerXmlElementName + " entry");
}
final String providerClassName = providerConfig.getClassName();
final StateProvider provider;
try {
provider = instantiateStateProvider(providerClassName);
} catch (final Exception e) {
throw new RuntimeException("Cannot create " + providerDescription + " of type " + providerClassName, e);
}
if (!ArrayUtils.contains(provider.getSupportedScopes(), scope)) {
throw new RuntimeException("Cannot use " + providerDescription + " (" + providerClassName + ") as it only supports scope(s) " + ArrayUtils.toString(provider.getSupportedScopes()) + " but " + "instance" + " is configured to use scope " + scope);
}
// create variable registry
final Map<PropertyDescriptor, PropertyValue> propertyMap = new HashMap<>();
final Map<PropertyDescriptor, String> propertyStringMap = new HashMap<>();
for (final PropertyDescriptor descriptor : provider.getPropertyDescriptors()) {
propertyMap.put(descriptor, new StandardPropertyValue(descriptor.getDefaultValue(), null, variableRegistry));
propertyStringMap.put(descriptor, descriptor.getDefaultValue());
}
for (final Map.Entry<String, String> entry : providerConfig.getProperties().entrySet()) {
final PropertyDescriptor descriptor = provider.getPropertyDescriptor(entry.getKey());
propertyStringMap.put(descriptor, entry.getValue());
propertyMap.put(descriptor, new StandardPropertyValue(entry.getValue(), null, variableRegistry));
}
final SSLContext sslContext = SslContextFactory.createSslContext(properties, false);
final ComponentLog logger = new SimpleProcessLogger(providerId, provider);
final StateProviderInitializationContext initContext = new StandardStateProviderInitializationContext(providerId, propertyMap, sslContext, logger);
synchronized (provider) {
provider.initialize(initContext);
}
final ValidationContext validationContext = new StandardValidationContext(null, propertyStringMap, null, null, null, variableRegistry);
final Collection<ValidationResult> results = provider.validate(validationContext);
final StringBuilder validationFailures = new StringBuilder();
int invalidCount = 0;
for (final ValidationResult result : results) {
if (!result.isValid()) {
validationFailures.append(result.toString()).append("\n");
invalidCount++;
}
}
if (invalidCount > 0) {
throw new IllegalStateException("Could not initialize State Providers because the " + providerDescription + " is not valid. The following " + invalidCount + " Validation Errors occurred:\n" + validationFailures.toString() + "\nPlease check the configuration of the " + providerDescription + " with ID [" + providerId.trim() + "] in the file " + configFile.getAbsolutePath());
}
return provider;
}
Aggregations