in genie-web/src/main/java/com/netflix/genie/web/services/impl/JobDirectoryServerServiceImpl.java [248:333]
private void handleRequest(
final URI baseUri,
final String relativePath,
final HttpServletRequest request,
final HttpServletResponse response,
final DirectoryManifest manifest,
final URI jobDirectoryRoot
) throws IOException, GenieNotFoundException, GenieServerException {
log.debug(
"Handle request, baseUri: '{}', relpath: '{}', jobRootUri: '{}'",
baseUri,
relativePath,
jobDirectoryRoot
);
final DirectoryManifest.ManifestEntry entry = manifest.getEntry(relativePath).orElseThrow(
() -> new GenieNotFoundException("No such entry in job manifest: " + relativePath)
);
if (entry.isDirectory()) {
// For now maintain the V3 structure
// TODO: Once we determine what we want for V4 use v3/v4 flags or some way to differentiate
// TODO: there's no unit test covering this section
final DefaultDirectoryWriter.Directory directory = new DefaultDirectoryWriter.Directory();
final List<DefaultDirectoryWriter.Entry> files = Lists.newArrayList();
final List<DefaultDirectoryWriter.Entry> directories = Lists.newArrayList();
try {
entry.getParent().ifPresent(
parentPath -> {
final DirectoryManifest.ManifestEntry parentEntry = manifest
.getEntry(parentPath)
.orElseThrow(IllegalArgumentException::new);
directory.setParent(createEntry(parentEntry, baseUri));
}
);
for (final String childPath : entry.getChildren()) {
final DirectoryManifest.ManifestEntry childEntry = manifest
.getEntry(childPath)
.orElseThrow(IllegalArgumentException::new);
if (childEntry.isDirectory()) {
directories.add(this.createEntry(childEntry, baseUri));
} else {
files.add(this.createEntry(childEntry, baseUri));
}
}
} catch (final IllegalArgumentException iae) {
throw new GenieServerException("Error while traversing files manifest: " + iae.getMessage(), iae);
}
directories.sort(Comparator.comparing(DefaultDirectoryWriter.Entry::getName));
files.sort(Comparator.comparing(DefaultDirectoryWriter.Entry::getName));
directory.setDirectories(directories);
directory.setFiles(files);
final String accept = request.getHeader(HttpHeaders.ACCEPT);
if (accept != null && accept.contains(MediaType.TEXT_HTML_VALUE)) {
response.setContentType(MediaType.TEXT_HTML_VALUE);
response
.getOutputStream()
.write(
DefaultDirectoryWriter
.directoryToHTML(entry.getName(), directory)
.getBytes(StandardCharsets.UTF_8)
);
} else {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
GenieObjectMapper.getMapper().writeValue(response.getOutputStream(), directory);
}
} else {
final URI location = jobDirectoryRoot.resolve(entry.getPath());
final String locationString = location.toString()
+ (jobDirectoryRoot.getFragment() != null ? ("#" + jobDirectoryRoot.getFragment()) : "");
log.debug("Get resource: {}", locationString);
final Resource jobResource = this.resourceLoader.getResource(locationString);
// Every file really should have a media type but if not use text/plain
final String mediaType = entry.getMimeType().orElse(MediaType.TEXT_PLAIN_VALUE);
final ResourceHttpRequestHandler handler = this.genieResourceHandlerFactory.get(mediaType, jobResource);
try {
handler.handleRequest(request, response);
} catch (ServletException e) {
throw new GenieServerException("Servlet exception: " + e.getMessage(), e);
}
}
}