in catalogs/catalog-hadoop/src/main/java/org/apache/gravitino/catalog/hadoop/HadoopCatalogOperations.java [555:648]
public String getFileLocation(NameIdentifier ident, String subPath, String locationName)
throws NoSuchFilesetException, NoSuchLocationNameException {
Preconditions.checkArgument(subPath != null, "subPath must not be null");
String processedSubPath;
if (!subPath.trim().isEmpty() && !subPath.trim().startsWith(SLASH)) {
processedSubPath = SLASH + subPath.trim();
} else {
processedSubPath = subPath.trim();
}
Fileset fileset = loadFileset(ident);
String targetLocationName;
if (locationName == null) {
targetLocationName =
fileset.storageLocations().size() == 1
// to be compatible with the old version, the fileset in old version only has one
// location and does not have the default-location-name property
? fileset.storageLocations().keySet().iterator().next()
: fileset.properties().get(PROPERTY_DEFAULT_LOCATION_NAME);
} else {
targetLocationName = locationName;
}
if (!fileset.storageLocations().containsKey(targetLocationName)) {
throw new NoSuchLocationNameException(
"Location name %s does not exist in fileset %s", targetLocationName, ident);
}
boolean isSingleFile = false;
if (disableFSOps) {
LOG.warn(
"Filesystem operations are disabled in the server side, we cannot check if the "
+ "storage location mounts to a directory or single file, we assume it is a directory"
+ "(in most of the cases). If it happens to be a single file, then the generated "
+ "file location may be a wrong path. Please avoid using Fileset to manage a single"
+ " file path.");
} else {
isSingleFile = checkSingleFile(fileset, targetLocationName);
}
// if the storage location is a single file, it cannot have sub path to access.
if (isSingleFile && StringUtils.isNotBlank(processedSubPath)) {
throw new GravitinoRuntimeException(
"Sub path should always be blank, because the fileset only mounts a single file.");
}
// do checks for some data operations.
if (hasCallerContext()) {
Map<String, String> contextMap = CallerContext.CallerContextHolder.get().context();
String operation =
contextMap.getOrDefault(
FilesetAuditConstants.HTTP_HEADER_FILESET_DATA_OPERATION,
FilesetDataOperation.UNKNOWN.name());
if (!FilesetDataOperation.checkValid(operation)) {
LOG.warn(
"The data operation: {} is not valid, we cannot do some checks for this operation.",
operation);
} else {
FilesetDataOperation dataOperation = FilesetDataOperation.valueOf(operation);
switch (dataOperation) {
case RENAME:
// Fileset only mounts a single file, the storage location of the fileset cannot be
// renamed; Otherwise the metadata in the Gravitino server may be inconsistent.
if (isSingleFile) {
throw new GravitinoRuntimeException(
"Cannot rename the fileset: %s which only mounts to a single file.", ident);
}
// if the sub path is blank, it cannot be renamed,
// otherwise the metadata in the Gravitino server may be inconsistent.
if (StringUtils.isBlank(processedSubPath)
|| (processedSubPath.startsWith(SLASH) && processedSubPath.length() == 1)) {
throw new GravitinoRuntimeException(
"subPath cannot be blank when need to rename a file or a directory.");
}
break;
default:
break;
}
}
}
String fileLocation;
// 1. if the storage location is a single file, we pass the storage location directly
// 2. if the processed sub path is blank, we pass the storage location directly
if (isSingleFile || StringUtils.isBlank(processedSubPath)) {
fileLocation = fileset.storageLocations().get(targetLocationName);
} else {
// the processed sub path always starts with "/" if it is not blank,
// so we can safely remove the tailing slash if storage location ends with "/".
String storageLocation =
removeTrailingSlash(fileset.storageLocations().get(targetLocationName));
fileLocation = String.format("%s%s", storageLocation, processedSubPath);
}
return fileLocation;
}