Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,17 @@ public OzoneInputStream readFile(String volumeName, String bucketName,
.setSortDatanodesInPipeline(topologyAwareReadEnabled)
.setLatestVersionLocation(getLatestVersionLocation)
.build();
OmKeyInfo keyInfo = ozoneManagerClient.lookupFile(keyArgs);
final OmKeyInfo keyInfo;
if (omVersion.compareTo(OzoneManagerVersion.OPTIMIZED_GET_KEY_INFO) >= 0) {
keyInfo = ozoneManagerClient.getKeyInfo(keyArgs, false)
.getKeyInfo();
if (!keyInfo.isFile()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to reuse getKeyInfo and check isFile if there was no exception (client used lookup and it failed)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible.

However, if we just reused getKeyInfo, then in turn it would call lookupKey for older OM and that would not result in either isFile attribute or NOT_A_FILE exception. (For older OM, clients have to call lookupFile).

Yet, to make things right, we can make getKeyInfo looks like the following to make it reusable across object storage and OFS use cases.

private OmKeyInfo getKeyInfo(String volumeName, String bucketName, String keyName,
      boolean forceUpdateContainerCache, boolean lookupFile) {
  if (newOM) { call getKeyInfo }
  else if (lookupFile) { call lookupFile }
  else { call lookupKey }
}

I feel that would just move complexity from one place to another.

throw new OMException(keyName + " is not a file.",
OMException.ResultCodes.NOT_A_FILE);
}
} else {
keyInfo = ozoneManagerClient.lookupFile(keyArgs);
}
return getInputStreamWithRetryFunction(keyInfo);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ public final class OmKeyInfo extends WithParentObjectId {
private ReplicationConfig replicationConfig;
private FileEncryptionInfo encInfo;
private FileChecksum fileChecksum;
/**
* Support OFS use-case to identify if the key is a file or a directory.
*/
private boolean isFile;

/**
* Represents leaf node name. This also will be used when the keyName is
Expand Down Expand Up @@ -106,12 +110,13 @@ public final class OmKeyInfo extends WithParentObjectId {
Map<String, String> metadata,
FileEncryptionInfo encInfo, List<OzoneAcl> acls,
long parentObjectID, long objectID, long updateID,
FileChecksum fileChecksum) {
FileChecksum fileChecksum, boolean isFile) {
this(volumeName, bucketName, keyName, versions, dataSize,
creationTime, modificationTime, replicationConfig, metadata,
encInfo, acls, objectID, updateID, fileChecksum);
this.fileName = fileName;
this.parentObjectID = parentObjectID;
this.isFile = isFile;
}

public String getVolumeName() {
Expand Down Expand Up @@ -177,6 +182,14 @@ public void updateModifcationTime() {
this.modificationTime = Time.monotonicNow();
}

public void setFile(boolean file) {
isFile = file;
}

public boolean isFile() {
return isFile;
}

/**
* updates the length of the each block in the list given.
* This will be called when the key is being committed to OzoneManager.
Expand Down Expand Up @@ -409,6 +422,8 @@ public static class Builder {
private long parentObjectID;
private FileChecksum fileChecksum;

private boolean isFile;

public Builder() {
this.metadata = new HashMap<>();
omKeyLocationInfoGroups = new ArrayList<>();
Expand Down Expand Up @@ -520,12 +535,17 @@ public Builder setFileChecksum(FileChecksum checksum) {
return this;
}

public Builder setFile(boolean isAFile) {
this.isFile = isAFile;
return this;
}

public OmKeyInfo build() {
return new OmKeyInfo(
volumeName, bucketName, keyName, fileName,
omKeyLocationInfoGroups, dataSize, creationTime,
modificationTime, replicationConfig, metadata, encInfo, acls,
parentObjectID, objectID, updateID, fileChecksum);
parentObjectID, objectID, updateID, fileChecksum, isFile);
}
}

Expand Down Expand Up @@ -627,6 +647,7 @@ private KeyInfo getProtobuf(boolean ignorePipeline, String fullKeyName,
if (encInfo != null) {
kb.setFileEncryptionInfo(OMPBHelper.convert(encInfo));
}
kb.setIsFile(isFile);
return kb.build();
}

Expand Down Expand Up @@ -669,6 +690,11 @@ public static OmKeyInfo getFromProtobuf(KeyInfo keyInfo) throws IOException {
FileChecksum fileChecksum = OMPBHelper.convert(keyInfo.getFileChecksum());
builder.setFileChecksum(fileChecksum);
}

if (keyInfo.hasIsFile()) {
builder.setFile(keyInfo.getIsFile());
}

// not persisted to DB. FileName will be filtered out from keyName
builder.setFileName(OzoneFSUtils.getFileName(keyInfo.getKeyName()));
return builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,9 @@ default OpenKeySession createFile(OmKeyArgs keyArgs, boolean overWrite,
* if bucket does not exist
* @throws IOException if there is error in the db
* invalid arguments
* @deprecated use {@link OzoneManagerProtocol#getKeyInfo} instead.
*/
@Deprecated
OmKeyInfo lookupFile(OmKeyArgs keyArgs) throws IOException;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1005,10 +1005,10 @@ public void testSeekOnFileLength() throws IOException {
Path fileNotExists = new Path("/file_notexist");
try {
fs.open(fileNotExists);
Assert.fail("Should throw FILE_NOT_FOUND error as file doesn't exist!");
Assert.fail("Should throw FileNotFoundException as file doesn't exist!");
} catch (FileNotFoundException fnfe) {
Assert.assertTrue("Expected FILE_NOT_FOUND error",
fnfe.getMessage().contains("FILE_NOT_FOUND"));
Assert.assertTrue("Expected KEY_NOT_FOUND error",
fnfe.getMessage().contains("KEY_NOT_FOUND"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,7 @@ message KeyInfo {
optional uint64 parentID = 16;
optional hadoop.hdds.ECReplicationConfig ecReplicationConfig = 17;
optional FileChecksumProto fileChecksum = 18;
optional bool isFile = 19;
}

message DirectoryInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ private OmKeyInfo readKeyInfo(OmKeyArgs args) throws IOException {
if (bucketLayout.isFileSystemOptimized()) {
value = getOmKeyInfoFSO(volumeName, bucketName, keyName);
} else {
value = getOmKeyInfo(volumeName, bucketName, keyName);
value = getOmKeyInfoDirectoryAware(volumeName, bucketName, keyName);
}
} catch (IOException ex) {
if (ex instanceof OMException) {
Expand Down Expand Up @@ -396,8 +396,26 @@ private OmKeyInfo readKeyInfo(OmKeyArgs args) throws IOException {
return value;
}

private OmKeyInfo getOmKeyInfoDirectoryAware(String volumeName,
String bucketName, String keyName) throws IOException {
OmKeyInfo keyInfo = getOmKeyInfo(volumeName, bucketName, keyName);

// Check if the key is a directory.
if (keyInfo != null) {
keyInfo.setFile(true);
return keyInfo;
}

String dirKey = OzoneFSUtils.addTrailingSlashIfNeeded(keyName);
OmKeyInfo dirKeyInfo = getOmKeyInfo(volumeName, bucketName, dirKey);
if (dirKeyInfo != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about adding an assertion here that dirKeyInfo.isFile() is false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That also works, just like the lookupFile does today. Yet, I think getKeyInfo should be a generic API that provide key information, like its name.

The decision of how to use that information should be in the hands of OM's clients. E.g. RpcClient should know it's looking for a file instead of relying on OM to decide.

dirKeyInfo.setFile(false);
}
return dirKeyInfo;
}

private OmKeyInfo getOmKeyInfo(String volumeName, String bucketName,
String keyName) throws IOException {
String keyName) throws IOException {
String keyBytes =
metadataManager.getOzoneKey(volumeName, bucketName, keyName);
BucketLayout bucketLayout = getBucketLayout(metadataManager, volumeName,
Expand Down Expand Up @@ -425,6 +443,7 @@ private OmKeyInfo getOmKeyInfoFSO(String volumeName, String bucketName,
fileStatus.getKeyInfo().getKeyName());
fileStatus.getKeyInfo().setKeyName(keyPath);
}
fileStatus.getKeyInfo().setFile(fileStatus.isFile());
return fileStatus.getKeyInfo();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ public InputStream readFile(String key) throws IOException {
return bucket.readFile(key).getInputStream();
} catch (OMException ex) {
if (ex.getResult() == OMException.ResultCodes.FILE_NOT_FOUND
|| ex.getResult() == OMException.ResultCodes.KEY_NOT_FOUND
|| ex.getResult() == OMException.ResultCodes.NOT_A_FILE) {
throw new FileNotFoundException(
ex.getResult().name() + ": " + ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ public InputStream readFile(String pathStr) throws IOException {
return bucket.readFile(key).getInputStream();
} catch (OMException ex) {
if (ex.getResult() == OMException.ResultCodes.FILE_NOT_FOUND
|| ex.getResult() == OMException.ResultCodes.KEY_NOT_FOUND
|| ex.getResult() == OMException.ResultCodes.NOT_A_FILE) {
throw new FileNotFoundException(
ex.getResult().name() + ": " + ex.getMessage());
Expand Down