Skip to content

Commit

Permalink
restfulapi: add restful Api call to query the lable of a givin file o…
Browse files Browse the repository at this point in the history
…bject

Motivation
The patch … has introduced a new feature of adding labels to a file.
This patch will provide dCache users with Restful Api call to query file labels.

Result
The label of a given file object could be queried using the following Restful Api call:
curl  -v   -u  http://localhost:3880/api/v1/namespace/public/label1.log\?labels=true

Target: master
Require-book: yes
Require-notes: yes
Patch: https://rb.dcache.org/r/13112/
Acked-by: Lea Morschel, Albert Rossi
  • Loading branch information
mksahakyan committed Aug 11, 2021
1 parent e54e3c4 commit 0a1d34d
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 7 deletions.
Expand Up @@ -1007,6 +1007,9 @@ private FileAttributes getFileAttributes(ExtendedInode inode, Set<FileAttribute>
}
attributes.setXattrs(xattrs);
break;
case LABELS:
attributes.setLabels(_fs.getLabels(inode));
break;
default:
throw new UnsupportedOperationException("Attribute " + attribute + " not supported yet.");
}
Expand Down Expand Up @@ -1145,6 +1148,12 @@ public FileAttributes setFileAttributes(Subject subject, PnfsId pnfsId,
}
}

if (attr.isDefined(LABELS)) {
for (String label : attr.getLabels()) {
_fs.addLabel(inode, label);
}
}

if (attr.isDefined(FileAttribute.LOCATIONS)) {
for (String location : attr.getLocations()) {
_fs.addInodeLocation(inode, StorageGenericLocation.DISK, location);
Expand Down
Expand Up @@ -3,10 +3,9 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.net.FileNameMap;
import java.net.URI;
import java.net.URLConnection;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -134,6 +133,9 @@ public class JsonFileAttributes
@ApiModelProperty("File's extended attributes.")
private Map<String,String> xattr;

@ApiModelProperty("File's labels.")
private Set<String> labels;

public ACL getAcl() {
return _acl;
}
Expand Down Expand Up @@ -395,4 +397,16 @@ public void setExtendedAttributes(Map<String,String> attributes) {
public Map<String,String> getExtendedAttributes() {
return xattr;
}

public void setLabels(Set<String> labelnames) {
if (labelnames == null) return;
if(labels == null) {
labels = new HashSet();
}
labels.addAll(labelnames);
}

public Set<String> getLabels() {
return labels == null ? new HashSet() : labels;
}
}
Expand Up @@ -146,6 +146,8 @@ public JsonFileAttributes getFileAttributes(@ApiParam("Path of file or directory
@QueryParam("qos") boolean isQos,
@ApiParam("Whether to include extended attributes.")
@QueryParam("xattr") boolean isXattr,
@ApiParam("Whether to include labels.")
@QueryParam("labels") boolean isLabels,
@ApiParam("Limit number of replies in directory listing.")
@QueryParam("limit") String limit,
@ApiParam("Number of entries to skip in directory listing.")
Expand All @@ -164,7 +166,7 @@ public JsonFileAttributes getFileAttributes(@ApiParam("Path of file or directory
FileAttributes namespaceAttributes = handler.getFileAttributes(path, attributes);
NamespaceUtils.chimeraToJsonAttributes(path.name(), fileAttributes,
namespaceAttributes,
isLocality, isLocations,
isLocality, isLocations, isLabels,
false, isXattr,
request, poolMonitor);
if (isQos) {
Expand Down Expand Up @@ -206,7 +208,7 @@ public JsonFileAttributes getFileAttributes(@ApiParam("Path of file or directory
NamespaceUtils.chimeraToJsonAttributes(fName,
childrenAttributes,
entry.getFileAttributes(),
isLocality, isLocations,
isLocality, isLocations, isLabels,
false, isXattr,
request, poolMonitor);
childrenAttributes.setFileName(fName);
Expand Down
Expand Up @@ -187,6 +187,7 @@ public JsonFileAttributes getAttributes(@ApiParam("The PNFS-ID of a file or dire
true,
true,
true,
true,
false,
request,
poolMonitor);
Expand Down
Expand Up @@ -77,6 +77,7 @@ public static void addQoSAttributes(JsonFileAttributes json,
* @param isLocality used to check weather user queried
* locality of the file
* @param isLocations add locations if true
* @param isLabels add label if true
* @param isOptional add optional attributes if true
* @param request to check for client info
* @param poolMonitor for access to remote PoolMonitor
Expand All @@ -86,6 +87,7 @@ public static void chimeraToJsonAttributes(String name,
FileAttributes attributes,
boolean isLocality,
boolean isLocations,
boolean isLabels,
boolean isOptional,
boolean isXattr,
HttpServletRequest request,
Expand Down Expand Up @@ -145,6 +147,12 @@ public static void chimeraToJsonAttributes(String name,
Map<String,String> xattr = attributes.getXattrs();
json.setExtendedAttributes(xattr);
}

if (isLabels) {
if (attributes.isDefined(FileAttribute.LABELS)) {
json.setLabels(attributes.getLabels());
}
}
}

private static String mimeTypeOf(String name, FileAttributes attributes)
Expand All @@ -158,7 +166,6 @@ private static String mimeTypeOf(String name, FileAttributes attributes)

case SPECIAL:
return "application/vnd.dcache.special";

case REGULAR:
if (attributes.hasXattr("mime_type")) {
try {
Expand Down Expand Up @@ -252,6 +259,7 @@ public static Set<FileAttribute> getRequestedAttributes(boolean locality,
attributes.add(FileAttribute.SIZE);
attributes.add(FileAttribute.TYPE);
attributes.add(FileAttribute.XATTR);
attributes.add(FileAttribute.LABELS);
attributes.add(FileAttribute.MODE);

if (locations || locality || qos || optional) {
Expand Down
Expand Up @@ -37,5 +37,12 @@ public enum FileAttribute {
/**
* @since 6.2
*/
XATTR // Be careful not to send this to pools before next golden release (7.2)
}
XATTR, // Be careful not to send this to pools before next golden release (7.2)

/**
* @since 7.2
*/
LABELS


}
Expand Up @@ -179,6 +179,12 @@ public class FileAttributes implements Serializable, Cloneable {
*/
private Map<String, String> _xattr;

/**
* File labels.
*/

private Set<String> _labels;

@Override
public FileAttributes clone()
{
Expand Down Expand Up @@ -276,6 +282,10 @@ public FileAttributes clone()
if (isDefined(XATTR)) {
clone.setXattrs(_xattr);
}

if (isDefined(LABELS)) {
clone.setLabels(_labels);
}
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Bad clone: " + e, e);
Expand Down Expand Up @@ -659,6 +669,21 @@ public Map<String, String> getXattrs()
return _xattr;
}

public void setLabels(Set<String> labels) {

define(LABELS);
if (labels == null) return;
if(_labels == null) {
_labels = new HashSet();
}
_labels.addAll(labels);
}

public Set<String> getLabels() {

return _labels == null ? new HashSet() : _labels;
}

/**
* Check whether an extended attribute is defined. Unlike
* {@link #getXattrs()}, this method does not throw an exception if
Expand Down Expand Up @@ -689,6 +714,21 @@ public Optional<String> updateXattr(String name, String value)
return Optional.ofNullable(oldValue);
}

/**
* Check whether a label is defined. Unlike
* {@link #getLabels()}, this method does not throw an exception if
* the label is not set.
* @param name The label name to check.
* @return True if there exists a label with this name.
*/

public boolean hasLabel(String name)
{
return _labels != null && _labels.contains(name);
}



/**
* Remove the {@link FileType} corresponding to the file. The FileType
* must be specified before this method is called. Subsequent getFileType
Expand Down Expand Up @@ -730,6 +770,7 @@ public String toString()
.add("cacheClass", _cacheClass)
.add("hsm", _hsm)
.add("xattr", _xattr)
.add("labels", _labels)
.omitNullValues()
.toString();
}
Expand Down
@@ -0,0 +1,100 @@
/*
* dCache - http://www.dcache.org/
*
* Copyright (C) 2021 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.vehicles;

import org.junit.Test;

import java.util.Collections;
import java.util.Set;

import static org.dcache.namespace.FileAttribute.LABELS;
import static org.junit.Assert.*;

public class FileLabelsTest
{
FileAttributes fileAttributes;

@Test
public void shouldNotHaveLabelsInitially()
{
given(fileAttributes());
assertFalse(fileAttributes.hasLabel("cat"));
assertFalse(fileAttributes.isDefined(LABELS));
}

@Test
public void shouldAllowFetchingLabelsInitially()
{
given(fileAttributes());
fileAttributes.getLabels();
}

@Test
public void shouldAcceptLabels()
{
given(fileAttributes().withLabel("dog"));
assertTrue(fileAttributes.isDefined(LABELS));
assertTrue(fileAttributes.hasLabel("dog"));
assertTrue(fileAttributes.getLabels().contains("dog"));
}


@Test
public void checkSetLabels()
{
Set<String> labels = Set.of("dog", "cat", "yellow");
given(fileAttributes().withLabels(labels));
assertEquals(labels, fileAttributes.getLabels());
}

private void given(FileAttributesBuilder builder)
{
fileAttributes = builder.build();
}


private FileAttributesBuilder fileAttributes()
{
return new FileAttributesBuilder();

}

private static class FileAttributesBuilder
{
FileAttributes attributes = new FileAttributes();
public FileAttributesBuilder withLabel(String name)
{
attributes.setLabels(Collections.singleton(name));
return this;
}


public FileAttributesBuilder withLabels(Set<String> names)
{
attributes.setLabels(names);
return this;
}

public FileAttributes build()
{
return attributes;
}
}
}
Expand Up @@ -173,6 +173,10 @@ private void registerFileAttributesInNameSpace() throws CacheException
if (_fileAttributes.isDefined(XATTR)) {
attributesToUpdate.setXattrs(_fileAttributes.getXattrs());
}

if (_fileAttributes.isDefined(LABELS)) {
attributesToUpdate.setLabels(_fileAttributes.getLabels());
}
}

_pnfs.setFileAttributes(_entry.getPnfsId(), attributesToUpdate);
Expand Down

0 comments on commit 0a1d34d

Please sign in to comment.