Skip to content

Commit

Permalink
chimera: make list method to support virtual directory listing
Browse files Browse the repository at this point in the history
Motivation

Tags can be attached to a file, and it was poosible to list files by labels but only using RESTFUL API.

This patch is the draft for addapting listing virtual directories based on label of files.

currently is will work in a way only if we use the following syntacs `.(collection)(cat)` than files having cat label will be returned.

Modifications

Add a new FSInode Type LABEL to separate real inode from virtual one.

Result

chimera.newDirectory() method can distinguesh between to cases.

but there is work to be done to test list() method for more cases and change FSPATH.create() method to addapt for  `.(collection)(cat)`.

Acked-by: Tigran
Target: master
Require-book: no
  • Loading branch information
mksahakyan committed Mar 6, 2024
1 parent 030d5ce commit 1fbd7ae
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public enum FsInodeType {
PCRC(11), // the content of the inode is a name-value list of checksum types and checksums
SURI(12), // read, write or update/overwrite location info for type TAPE
PINS(13), // the content of the inode is a list of current pins
CKSTYP(14); // the available checksum types

CKSTYP(14), // the available checksum types
LABEL(15); // virtual directory type (ls labels)
private final int _id;

FsInodeType(int id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* dCache - http://www.dcache.org/
*
* Copyright (C) 2023 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.dcache.chimera;

import java.util.Set;

public class FsInode_LABEL extends FsInode {

public String getLabel() {
return _label;
}

private final String _label;

/**
* @param fs pointer to 'File System'
* @param ino inode number of the label_id
* @param label
*/
public FsInode_LABEL(FileSystemProvider fs, long ino, String label) {
super(fs, ino, FsInodeType.LABEL);
_label = label;
}

@Override
public boolean exists() {
boolean rc = false;
try {
Set<String> list = _fs.getLabels(this);
if (list.contains(_label)) {
rc = true;
}
} catch (Exception e) {
}
return rc;
}

@Override
public boolean isDirectory() {
return true;
}

@Override
public boolean isLink() {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2134,9 +2134,12 @@ void addLabel(FsInode inode, String labelname) throws ChimeraFsException {
* @param labelname a name of the label attached to files
* @return stream of files having the given label
*/
DirectoryStreamB<ChimeraDirectoryEntry> virtualDirectoryStream(FsInode dir, String labelname) {
DirectoryStreamB<ChimeraDirectoryEntry> virtualDirectoryStream(FsInode dir)
throws ChimeraFsException {

return new DirectoryStreamB<ChimeraDirectoryEntry>() {
final VirtualDirectoryStreamImpl stream = new VirtualDirectoryStreamImpl(labelname,

final VirtualDirectoryStreamImpl stream = new VirtualDirectoryStreamImpl(((FsInode_LABEL)dir).getLabel(),
_jdbc);


Expand Down
23 changes: 21 additions & 2 deletions modules/chimera/src/main/java/org/dcache/chimera/JdbcFs.java
Original file line number Diff line number Diff line change
Expand Up @@ -539,13 +539,17 @@ public void createFileWithId(FsInode parent, String id, String name, int owner,
@Override
public DirectoryStreamB<ChimeraDirectoryEntry> newDirectoryStream(FsInode dir)
throws ChimeraFsException {
return _sqlDriver.newDirectoryStream(dir);
if ((dir instanceof FsInode_LABEL)) {
return _sqlDriver.virtualDirectoryStream(dir);
} else {
return _sqlDriver.newDirectoryStream(dir);
}
}

@Override
public DirectoryStreamB<ChimeraDirectoryEntry> virtualDirectoryStream(FsInode dir,
String labelname) throws ChimeraFsException {
return _sqlDriver.virtualDirectoryStream(dir, labelname);
return _sqlDriver.virtualDirectoryStream(dir);
}

@Override
Expand Down Expand Up @@ -863,6 +867,21 @@ public FsInode inodeOf(FsInode parent, String name, StatCacheOption cacheOption)
return nameofInode;
}

if (name.startsWith(".(collection)(")) {
String[] cmd = PnfsCommandProcessor.process(name);
if (cmd.length != 2) {
throw FileNotFoundChimeraFsException.ofFileInDirectory(parent, name);
}

FsInode labelInode = new FsInode_LABEL(this, _sqlDriver.getLabel(cmd[1]), cmd[1]);
if (!(labelInode.type() == FsInodeType.LABEL)) {
if (!labelInode.exists()) {
throw FileNotFoundChimeraFsException.ofFileInDirectory(parent, name);
}
}
return labelInode;
}

if (name.startsWith(".(const)(")) {
String[] cmd = PnfsCommandProcessor.process(name);
if (cmd.length != 2) {
Expand Down
40 changes: 40 additions & 0 deletions modules/chimera/src/test/java/org/dcache/chimera/JdbcFsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.dcache.acl.ACE;
import org.dcache.acl.enums.AccessMask;
import org.dcache.acl.enums.AceType;
Expand Down Expand Up @@ -1847,6 +1849,44 @@ public void testGetLabels() throws Exception {
assertThat("List labels without order", labelsSet, containsInAnyOrder(labels));


}

@Test
public void testLsWithLabel() throws Exception {

FsInode dir = _fs.mkdir("/test");
FsInode inodeA = _fs.createFile(dir, "aFile");
FsInode inodeB = _fs.createFile(dir, "bFile");
FsInode inodeC = _fs.createFile(dir, "cFile");

FsInode dir1 = _fs.mkdir("/test1");
FsInode inodeB2 = _fs.createFile(dir1, "bFile");

String[] labels = {"cat", "dog", "yellow", "green"};

for (String labelName : labels) {
_fs.addLabel(inodeA, labelName);
_fs.addLabel(inodeB, labelName);
_fs.addLabel(inodeB2, labelName);
}

FsInode newInode = _fs.inodeOf(_rootInode, (".(collection)(cat)"), NO_STAT);

Collection<String> dirLs = new HashSet<>();
try (DirectoryStreamB<ChimeraDirectoryEntry> dirStream = _fs.newDirectoryStream(
newInode)) {

for (ChimeraDirectoryEntry entry : dirStream) {
dirLs.add(entry.getInode().getId());

}
}

assertThat("List file's pnfsid without order", dirLs,
containsInAnyOrder(inodeA.getId(), inodeB.getId(), inodeB2.getId()));
assertEquals("Unexpected number of entries", 3, getDirEntryCount(newInode));


}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
import org.dcache.chimera.FileSystemProvider;
import org.dcache.chimera.FileSystemProvider.SetXattrMode;
import org.dcache.chimera.FsInode;
import org.dcache.chimera.FsInode_LABEL;
import org.dcache.chimera.NoXdataChimeraException;
import org.dcache.chimera.NotDirChimeraException;
import org.dcache.chimera.StorageGenericLocation;
Expand Down Expand Up @@ -262,6 +263,11 @@ private ExtendedInode pathToInode(Subject subject, String path)
return new ExtendedInode(_fs, _fs.path2inode(path));
}

if (path.startsWith("/.(collection)")) {
ExtendedInode dir = new ExtendedInode(_fs, _fs.path2inode(path));
return dir.inodeOf(path, STAT);
}

List<FsInode> inodes;
try {
inodes = _fs.path2inodes(path);
Expand Down Expand Up @@ -1289,6 +1295,7 @@ public void list(Subject subject, String path, Glob glob, Range<Integer> range,
try {
Pattern pattern = (glob == null) ? null : glob.toPattern();
ExtendedInode dir = pathToInode(subject, path);
// TODO this should be checkt for virtual directories and test casse for list() must e added
if (!dir.isDirectory()) {
throw new NotDirCacheException("Not a directory: " + path);
}
Expand Down

0 comments on commit 1fbd7ae

Please sign in to comment.