use of org.apache.nifi.remote.RemoteSiteListener in project nifi by apache.
the class FlowController method setRootGroup.
/**
* Sets the root group to the given group
*
* @param group the ProcessGroup that is to become the new Root Group
*
* @throws IllegalArgumentException if the ProcessGroup has a parent
* @throws IllegalStateException if the FlowController does not know about
* the given process group
*/
void setRootGroup(final ProcessGroup group) {
if (requireNonNull(group).getParent() != null) {
throw new IllegalArgumentException("A ProcessGroup that has a parent cannot be the Root Group");
}
writeLock.lock();
try {
rootGroupRef.set(group);
for (final RemoteSiteListener listener : externalSiteListeners) {
listener.setRootGroup(group);
}
// update the heartbeat bean
this.heartbeatBeanRef.set(new HeartbeatBean(group, isPrimary()));
allProcessGroups.put(group.getIdentifier(), group);
allProcessGroups.put(ROOT_GROUP_ID_ALIAS, group);
} finally {
writeLock.unlock();
}
}
use of org.apache.nifi.remote.RemoteSiteListener in project nifi by apache.
the class FlowController method initializeFlow.
public void initializeFlow() throws IOException {
writeLock.lock();
try {
// get all connections/queues and recover from swap files.
final List<Connection> connections = getGroup(getRootGroupId()).findAllConnections();
long maxIdFromSwapFiles = -1L;
if (flowFileRepository.isVolatile()) {
for (final Connection connection : connections) {
final FlowFileQueue queue = connection.getFlowFileQueue();
queue.purgeSwapFiles();
}
} else {
for (final Connection connection : connections) {
final FlowFileQueue queue = connection.getFlowFileQueue();
final SwapSummary swapSummary = queue.recoverSwappedFlowFiles();
if (swapSummary != null) {
final Long maxFlowFileId = swapSummary.getMaxFlowFileId();
if (maxFlowFileId != null && maxFlowFileId > maxIdFromSwapFiles) {
maxIdFromSwapFiles = maxFlowFileId;
}
for (final ResourceClaim resourceClaim : swapSummary.getResourceClaims()) {
resourceClaimManager.incrementClaimantCount(resourceClaim);
}
}
}
}
flowFileRepository.loadFlowFiles(this, maxIdFromSwapFiles + 1);
// Begin expiring FlowFiles that are old
final RepositoryContextFactory contextFactory = new RepositoryContextFactory(contentRepository, flowFileRepository, flowFileEventRepository, counterRepositoryRef.get(), provenanceRepository);
processScheduler.scheduleFrameworkTask(new ExpireFlowFiles(this, contextFactory), "Expire FlowFiles", 30L, 30L, TimeUnit.SECONDS);
// now that we've loaded the FlowFiles, this has restored our ContentClaims' states, so we can tell the
// ContentRepository to purge superfluous files
contentRepository.cleanup();
for (final RemoteSiteListener listener : externalSiteListeners) {
listener.start();
}
notifyComponentsConfigurationRestored();
timerDrivenEngineRef.get().scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
updateRemoteProcessGroups();
} catch (final Throwable t) {
LOG.warn("Unable to update Remote Process Groups due to " + t);
if (LOG.isDebugEnabled()) {
LOG.warn("", t);
}
}
}
}, 0L, 30L, TimeUnit.SECONDS);
timerDrivenEngineRef.get().scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
final ProcessGroup rootGroup = getRootGroup();
final List<ProcessGroup> allGroups = rootGroup.findAllProcessGroups();
allGroups.add(rootGroup);
for (final ProcessGroup group : allGroups) {
try {
group.synchronizeWithFlowRegistry(flowRegistryClient);
} catch (final Exception e) {
LOG.error("Failed to synchronize {} with Flow Registry", group, e);
}
}
}
}, 5, 60, TimeUnit.SECONDS);
initialized.set(true);
} finally {
writeLock.unlock();
}
}
use of org.apache.nifi.remote.RemoteSiteListener in project nifi by apache.
the class FlowController method shutdown.
/**
* Triggers the controller to begin shutdown, stopping all processors and
* terminating the scheduling engine. After calling this method, the
* {@link #isTerminated()} method will indicate whether or not the shutdown
* has finished.
*
* @param kill if <code>true</code>, attempts to stop all active threads,
* but makes no guarantee that this will happen
*
* @throws IllegalStateException if the controller is already stopped or
* currently in the processor of stopping
*/
public void shutdown(final boolean kill) {
this.shutdown = true;
stopAllProcessors();
readLock.lock();
try {
if (isTerminated() || timerDrivenEngineRef.get().isTerminating()) {
throw new IllegalStateException("Controller already stopped or still stopping...");
}
if (leaderElectionManager != null) {
leaderElectionManager.stop();
}
if (heartbeatMonitor != null) {
heartbeatMonitor.stop();
}
if (kill) {
this.timerDrivenEngineRef.get().shutdownNow();
this.eventDrivenEngineRef.get().shutdownNow();
LOG.info("Initiated immediate shutdown of flow controller...");
} else {
this.timerDrivenEngineRef.get().shutdown();
this.eventDrivenEngineRef.get().shutdown();
LOG.info("Initiated graceful shutdown of flow controller...waiting up to " + gracefulShutdownSeconds + " seconds");
}
clusterTaskExecutor.shutdownNow();
if (zooKeeperStateServer != null) {
zooKeeperStateServer.shutdown();
}
// Trigger any processors' methods marked with @OnShutdown to be called
getRootGroup().shutdown();
stateManagerProvider.shutdown();
// invoke any methods annotated with @OnShutdown on Controller Services
for (final ControllerServiceNode serviceNode : getAllControllerServices()) {
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(serviceNode.getControllerServiceImplementation().getClass(), serviceNode.getIdentifier())) {
final ConfigurationContext configContext = new StandardConfigurationContext(serviceNode, controllerServiceProvider, null, variableRegistry);
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnShutdown.class, serviceNode.getControllerServiceImplementation(), configContext);
}
}
// invoke any methods annotated with @OnShutdown on Reporting Tasks
for (final ReportingTaskNode taskNode : getAllReportingTasks()) {
final ConfigurationContext configContext = taskNode.getConfigurationContext();
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(taskNode.getReportingTask().getClass(), taskNode.getIdentifier())) {
ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnShutdown.class, taskNode.getReportingTask(), configContext);
}
}
try {
this.timerDrivenEngineRef.get().awaitTermination(gracefulShutdownSeconds / 2, TimeUnit.SECONDS);
this.eventDrivenEngineRef.get().awaitTermination(gracefulShutdownSeconds / 2, TimeUnit.SECONDS);
} catch (final InterruptedException ie) {
LOG.info("Interrupted while waiting for controller termination.");
}
try {
flowFileRepository.close();
} catch (final Throwable t) {
LOG.warn("Unable to shut down FlowFileRepository due to {}", new Object[] { t });
}
if (this.timerDrivenEngineRef.get().isTerminated() && eventDrivenEngineRef.get().isTerminated()) {
LOG.info("Controller has been terminated successfully.");
} else {
LOG.warn("Controller hasn't terminated properly. There exists an uninterruptable thread that " + "will take an indeterminate amount of time to stop. Might need to kill the program manually.");
}
for (final RemoteSiteListener listener : externalSiteListeners) {
listener.stop();
}
if (processScheduler != null) {
processScheduler.shutdown();
}
if (contentRepository != null) {
contentRepository.shutdown();
}
if (provenanceRepository != null) {
try {
provenanceRepository.close();
} catch (final IOException ioe) {
LOG.warn("There was a problem shutting down the Provenance Repository: " + ioe.toString());
if (LOG.isDebugEnabled()) {
LOG.warn("", ioe);
}
}
}
} finally {
readLock.unlock();
}
}
Aggregations