package org.dcache.chimera.namespace; import com.google.common.collect.ImmutableList; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriUtils; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import diskCacheV111.util.AccessLatency; import diskCacheV111.util.CacheException; import diskCacheV111.util.RetentionPolicy; import diskCacheV111.vehicles.EnstoreStorageInfo; import diskCacheV111.vehicles.StorageInfo; import org.dcache.chimera.ChimeraFsException; import org.dcache.chimera.StorageGenericLocation; import org.dcache.chimera.posix.Stat; public class ChimeraEnstoreStorageInfoExtractor extends ChimeraHsmStorageInfoExtractor { public ChimeraEnstoreStorageInfoExtractor(AccessLatency defaultAL, RetentionPolicy defaultRP) { super(defaultAL,defaultRP); } @Override public StorageInfo getFileStorageInfo(ExtendedInode inode) throws CacheException { EnstoreStorageInfo info; Stat stat; ExtendedInode level2 = inode.getLevel(2); try { List<String> locations = inode.getLocations(StorageGenericLocation.TAPE); EnstoreStorageInfo parentStorageInfo = (EnstoreStorageInfo) getDirStorageInfo(inode); if (locations.isEmpty()) { info = parentStorageInfo; } else { info = new EnstoreStorageInfo(parentStorageInfo.getStorageGroup(), parentStorageInfo.getFileFamily()); info.setIsNew(false); for(String location: locations) { UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(location); try { URI uri = builder.build(isEncoded(location)).toUri(); info.addLocation(uri); for (String part : uri.getQuery().split("&")) { String[] data = part.split("="); String key = data[0]; String value = (data.length == 2 ? data[1] : ""); switch (key) { case "bfid": info.setBitfileId(value); break; case "volume": info.setVolume(value); break; case "location_cookie": info.setLocation(value); break; case "original_name": info.setPath(value); break; } } } catch (UnsupportedEncodingException ignore) { } } } stat = inode.stat(); info.setIsNew((stat.getSize() == 0) && (!level2.exists())); } catch (ChimeraFsException e) { throw new CacheException(e.getMessage()); } return info; } @Override public StorageInfo getDirStorageInfo(ExtendedInode inode) throws CacheException { ExtendedInode dirInode; if (!inode.isDirectory()) { dirInode = inode.getParent(); } else { dirInode = inode; } Map<String, String> hash = new HashMap<>(); ImmutableList<String> OSMTemplate = dirInode.getTag("OSMTemplate"); ImmutableList<String> group = dirInode.getTag("storage_group"); ImmutableList<String> family = dirInode.getTag("file_family"); for (String line: OSMTemplate) { StringTokenizer st = new StringTokenizer(line); if (st.countTokens() >= 2) { hash.put(st.nextToken().intern(), st.nextToken()); } } String sg = getFirstLine(group).transform(String::intern).or("none"); String ff = getFirstLine(family).transform(String::intern).or("none"); EnstoreStorageInfo info = new EnstoreStorageInfo(sg,ff); info.addKeys(hash); return info; } private static boolean isEncoded(String s) throws UnsupportedEncodingException { return !s.equals(UriUtils.decode(s,"UTF-8")); } }