mirror of https://github.com/apache/nifi.git
NIFI-13757 Improve handling when a NAR contains an extension that produces an Error (#9274)
Signed-off-by: David Handermann <exceptionfactory@apache.org>
This commit is contained in:
parent
9b7b246dcc
commit
44abe39983
|
@ -114,13 +114,15 @@ public class DocGenerator {
|
|||
}
|
||||
}
|
||||
case JAVA -> {
|
||||
final Class<?> extensionClass = extensionManager.getClass(extensionDefinition);
|
||||
final Class<? extends ConfigurableComponent> componentClass = extensionClass.asSubclass(ConfigurableComponent.class);
|
||||
// Catch Throwable here to protect against an extension that may have been registered, but throws an Error when attempting to access the Class,
|
||||
// this method is called during start-up, and we don't want to fail starting just because one bad extension class can't be loaded
|
||||
try {
|
||||
final Class<?> extensionClass = extensionManager.getClass(extensionDefinition);
|
||||
final Class<? extends ConfigurableComponent> componentClass = extensionClass.asSubclass(ConfigurableComponent.class);
|
||||
logger.debug("Documentation generation started: Component Class [{}]", componentClass);
|
||||
document(extensionManager, componentDirectory, componentClass, coordinate);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Documentation generation failed: Component Class [{}]", componentClass, e);
|
||||
} catch (Throwable t) {
|
||||
logger.warn("Documentation generation failed: Component Class [{}]", extensionDefinition.getImplementationClassName(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,13 @@ public class NarInstallTask implements Runnable {
|
|||
final BundleCoordinate loadedCoordinate = loadedBundle.getBundleDetails().getCoordinate();
|
||||
LOGGER.info("NAR [{}] was installed", loadedCoordinate);
|
||||
if (loadedCoordinate.equals(coordinate)) {
|
||||
// If the NAR that was just uploaded was successfully loaded, attempt to access the class of each extension to prove that each
|
||||
// class can load successfully, if not then we want to bounce out to the catch block and set the state as FAILED
|
||||
final Set<ExtensionDefinition> loadedExtensionDefinitions = extensionManager.getTypes(coordinate);
|
||||
for (final ExtensionDefinition loadedExtensionDefinition : loadedExtensionDefinitions) {
|
||||
final Class<?> extensionClass = extensionManager.getClass(loadedExtensionDefinition);
|
||||
LOGGER.debug("Loaded [{}] from bundle [{}]", extensionClass.getCanonicalName(), coordinate);
|
||||
}
|
||||
narNode.setState(NarState.INSTALLED);
|
||||
} else {
|
||||
try {
|
||||
|
@ -133,10 +140,10 @@ public class NarInstallTask implements Runnable {
|
|||
// Notify the NAR Manager that the install task complete for the current NAR
|
||||
narManager.completeInstall(narNode.getIdentifier());
|
||||
|
||||
} catch (final Exception e) {
|
||||
LOGGER.error("Failed to install NAR [{}]", coordinate, e);
|
||||
} catch (final Throwable t) {
|
||||
LOGGER.error("Failed to install NAR [{}]", coordinate, t);
|
||||
narNode.setState(NarState.FAILED);
|
||||
narNode.setFailureMessage(e.getMessage());
|
||||
narNode.setFailureMessage(t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -257,6 +257,8 @@ import org.apache.nifi.web.controller.ControllerFacade;
|
|||
import org.apache.nifi.web.revision.RevisionManager;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.Collator;
|
||||
|
@ -288,20 +290,17 @@ import java.util.stream.Collectors;
|
|||
|
||||
public final class DtoFactory {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final static Comparator<Class> CLASS_NAME_COMPARATOR = new Comparator<Class>() {
|
||||
@Override
|
||||
public int compare(final Class class1, final Class class2) {
|
||||
return Collator.getInstance(Locale.US).compare(class1.getSimpleName(), class2.getSimpleName());
|
||||
}
|
||||
};
|
||||
public static final String SENSITIVE_VALUE_MASK = "********";
|
||||
private static final Logger logger = LoggerFactory.getLogger(DtoFactory.class);
|
||||
|
||||
private BulletinRepository bulletinRepository;
|
||||
private ControllerServiceProvider controllerServiceProvider;
|
||||
private EntityFactory entityFactory;
|
||||
private Authorizer authorizer;
|
||||
private ExtensionManager extensionManager;
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final static Comparator<Class> CLASS_NAME_COMPARATOR = (class1, class2) -> Collator.getInstance(Locale.US).compare(class1.getSimpleName(), class2.getSimpleName());
|
||||
public static final String SENSITIVE_VALUE_MASK = "********";
|
||||
|
||||
private BulletinRepository bulletinRepository;
|
||||
private ControllerServiceProvider controllerServiceProvider;
|
||||
private EntityFactory entityFactory;
|
||||
private Authorizer authorizer;
|
||||
private ExtensionManager extensionManager;
|
||||
|
||||
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade) {
|
||||
final ControllerConfigurationDTO dto = new ControllerConfigurationDTO();
|
||||
|
@ -3291,9 +3290,15 @@ public final class DtoFactory {
|
|||
continue;
|
||||
}
|
||||
|
||||
final Class cls = extensionManager.getClass(extensionDefinition);
|
||||
if (cls != null) {
|
||||
classBundles.put(cls, extensionDefinition.getBundle());
|
||||
// Catch Throwable here to protect against an extension that may have been registered, but throws an Error when attempting to access the Class,
|
||||
// we don't need to fail the overall request since we can still return all the other components that are still usable
|
||||
try {
|
||||
final Class cls = extensionManager.getClass(extensionDefinition);
|
||||
if (cls != null) {
|
||||
classBundles.put(cls, extensionDefinition.getBundle());
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
logger.warn("Unable to get extension class for [{}]", extensionDefinition.getImplementationClassName(), t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue