NIFI-2184 JettyServer should confirm "docs" path exists before using it in .createDocsWebApp().

Refactored the createDocsWebApp method of the JettyServer.java class. Previously NiFi would fail to
start up and instead throw an IllegalStatException if the 'docs' directory did not exist in the
installation directory. With the update, if the 'docs' directory is missing, an attempt to create
the missing directory will be made and if successful will enable NIFI to startup successfully, barring
any other startup errors of course. The side effect of this change is that the help documentation
under the 'General' heading of the help page will be missing.

Three small helper methods were extracted from the original method.  Each related to a section of the
original code that could throw an exception. In each case if an exception is now thrown a more helpful
log message will be output and the process will be closed via the startUpfailure method rather than
throwing an exception.

This closes #2164.

Signed-off-by: Andy LoPresto <alopresto@apache.org>
This commit is contained in:
Mark Owens 2017-09-20 10:14:08 -04:00 committed by Andy LoPresto
parent bdab3cda0a
commit feaf44b623
No known key found for this signature in database
GPG Key ID: 6EC293152D90B61D
1 changed files with 61 additions and 12 deletions

View File

@ -492,23 +492,15 @@ public class JettyServer implements NiFiServer {
final ResourceHandler resourceHandler = new ResourceHandler(); final ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setDirectoriesListed(false); resourceHandler.setDirectoriesListed(false);
// load the docs directory final File docsDir = getDocsDir("docs");
final File docsDir = Paths.get("docs").toRealPath().toFile();
final Resource docsResource = Resource.newResource(docsDir); final Resource docsResource = Resource.newResource(docsDir);
// load the component documentation working directory // load the component documentation working directory
final File componentDocsDirPath = props.getComponentDocumentationWorkingDirectory(); final File componentDocsDirPath = props.getComponentDocumentationWorkingDirectory();
final File workingDocsDirectory = componentDocsDirPath.toPath().toRealPath().getParent().toFile(); final File workingDocsDirectory = getWorkingDocsDirectory(componentDocsDirPath);
final Resource workingDocsResource = Resource.newResource(workingDocsDirectory); final Resource workingDocsResource = Resource.newResource(workingDocsDirectory);
// load the rest documentation final File webApiDocsDir = getWebApiDocsDir();
final File webApiDocsDir = new File(webApiContext.getTempDirectory(), "webapp/docs");
if (!webApiDocsDir.exists()) {
final boolean made = webApiDocsDir.mkdirs();
if (!made) {
throw new RuntimeException(webApiDocsDir.getAbsolutePath() + " could not be created");
}
}
final Resource webApiDocsResource = Resource.newResource(webApiDocsDir); final Resource webApiDocsResource = Resource.newResource(webApiDocsDir);
// create resources for both docs locations // create resources for both docs locations
@ -522,10 +514,67 @@ public class JettyServer implements NiFiServer {
logger.info("Loading documents web app with context path set to " + contextPath); logger.info("Loading documents web app with context path set to " + contextPath);
return handler; return handler;
} catch (Exception ex) { } catch (Exception ex) {
throw new IllegalStateException("Resource directory paths are malformed: " + ex.getMessage()); logger.error("Unhandled Exception in createDocsWebApp: " + ex.getMessage());
startUpFailure(ex);
return null; // required by compiler, though never be executed.
} }
} }
/**
* Returns a File object for the directory containing NIFI documentation.
*
* Formerly, if the docsDirectory did not exist NIFI would fail to start
* with an IllegalStateException and a rather unhelpful log message.
* NIFI-2184 updates the process such that if the docsDirectory does not
* exist an attempt will be made to create the directory. If that is
* successful NIFI will no longer fail and will start successfully barring
* any other errors. The side effect of the docsDirectory not being present
* is that the documentation links under the 'General' portion of the help
* page will not be accessible, but at least the process will be running.
*
* @param docsDirectory Name of documentation directory in installation directory.
* @return A File object to the documentation directory; else startUpFailure called.
*/
private File getDocsDir(final String docsDirectory) {
File docsDir;
try {
docsDir = Paths.get(docsDirectory).toRealPath().toFile();
} catch (IOException ex) {
logger.info("Directory '" + docsDirectory + "' is missing. Some documentation will be unavailable.");
docsDir = new File(docsDirectory).getAbsoluteFile();
final boolean made = docsDir.mkdirs();
if (!made) {
logger.error("Failed to create 'docs' directory!");
startUpFailure(new IOException(docsDir.getAbsolutePath() + " could not be created"));
}
}
return docsDir;
}
private File getWorkingDocsDirectory(final File componentDocsDirPath) {
File workingDocsDirectory = null;
try {
workingDocsDirectory = componentDocsDirPath.toPath().toRealPath().getParent().toFile();
} catch (IOException ex) {
logger.error("Failed to load :" + componentDocsDirPath.getAbsolutePath());
startUpFailure(ex);
}
return workingDocsDirectory;
}
private File getWebApiDocsDir() {
// load the rest documentation
final File webApiDocsDir = new File(webApiContext.getTempDirectory(), "webapp/docs");
if (!webApiDocsDir.exists()) {
final boolean made = webApiDocsDir.mkdirs();
if (!made) {
logger.error("Failed to create " + webApiDocsDir.getAbsolutePath());
startUpFailure(new IOException(webApiDocsDir.getAbsolutePath() + " could not be created"));
}
}
return webApiDocsDir;
}
private void configureConnectors(final Server server) throws ServerConfigurationException { private void configureConnectors(final Server server) throws ServerConfigurationException {
// create the http configuration // create the http configuration
final HttpConfiguration httpConfiguration = new HttpConfiguration(); final HttpConfiguration httpConfiguration = new HttpConfiguration();