本文整理汇总了Python中WMCore.Services.SiteDB.SiteDB.SiteDBJSON.phEDExNodetocmsName方法的典型用法代码示例。如果您正苦于以下问题:Python SiteDBJSON.phEDExNodetocmsName方法的具体用法?Python SiteDBJSON.phEDExNodetocmsName怎么用?Python SiteDBJSON.phEDExNodetocmsName使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WMCore.Services.SiteDB.SiteDB.SiteDBJSON
的用法示例。
在下文中一共展示了SiteDBJSON.phEDExNodetocmsName方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: PhEDExInjectorSubscriber
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
class PhEDExInjectorSubscriber(BaseWorkerThread):
"""
_PhEDExInjectorSubscriber_
Poll the DBSBuffer database and subscribe datasets as they are
created.
"""
def __init__(self, config):
"""
___init___
Initialise class members
"""
BaseWorkerThread.__init__(self)
self.phedex = PhEDEx({"endpoint": config.PhEDExInjector.phedexurl}, "json")
self.siteDB = SiteDBJSON()
self.dbsUrl = config.DBSInterface.globalDBSUrl
self.group = getattr(config.PhEDExInjector, "group", "DataOps")
self.tier0Mode = getattr(config.PhEDExInjector, "tier0Mode", False)
# We will map node names to CMS names, that what the spec will have.
# If a CMS name is associated to many PhEDEx node then choose the MSS option
self.cmsToPhedexMap = {}
self.phedexNodes = {'MSS':[], 'Disk':[]}
# initialize the alert framework (if available - config.Alert present)
# self.sendAlert will be then be available
self.initAlerts(compName = "PhEDExInjector")
def setup(self, parameters):
"""
_setup_
Create a DAO Factory for the PhEDExInjector. Also load the SE names to
PhEDEx node name mappings from the data service.
"""
myThread = threading.currentThread()
daofactory = DAOFactory(package = "WMComponent.PhEDExInjector.Database",
logger = self.logger,
dbinterface = myThread.dbi)
self.getUnsubscribed = daofactory(classname = "GetUnsubscribedDatasets")
self.getUnsubscribedBlocks = daofactory(classname = "GetUnsubscribedBlocks")
self.markSubscribed = daofactory(classname = "MarkDatasetSubscribed")
nodeMappings = self.phedex.getNodeMap()
for node in nodeMappings["phedex"]["node"]:
cmsName = self.siteDB.phEDExNodetocmsName(node["name"])
if cmsName not in self.cmsToPhedexMap:
self.cmsToPhedexMap[cmsName] = {}
logging.info("Loaded PhEDEx node %s for site %s" % (node["name"], cmsName))
if node["kind"] not in self.cmsToPhedexMap[cmsName]:
self.cmsToPhedexMap[cmsName][node["kind"]] = node["name"]
if node["kind"] in [ "MSS", "Disk" ]:
self.phedexNodes[node["kind"]].append(node["name"])
return
def algorithm(self, parameters):
"""
_algorithm_
Run the subscription algorithm as configured
"""
if self.tier0Mode:
self.subscribeTier0Blocks()
self.subscribeDatasets()
return
def subscribeTier0Blocks(self):
"""
_subscribeTier0Blocks_
Subscribe blocks to the Tier-0 where a replica subscription
already exists. All Tier-0 subscriptions are move, custodial
and autoapproved with high priority.
"""
myThread = threading.currentThread()
myThread.transaction.begin()
# Check for candidate blocks for subscription
blocksToSubscribe = self.getUnsubscribedBlocks.execute(node = 'T0_CH_CERN',
conn = myThread.transaction.conn,
transaction = True)
if not blocksToSubscribe:
return
# For the blocks we don't really care about the subscription options
# We are subscribing all blocks with the same recipe.
subscriptionMap = {}
for subInfo in blocksToSubscribe:
dataset = subInfo['path']
if dataset not in subscriptionMap:
subscriptionMap[dataset] = []
subscriptionMap[dataset].append(subInfo['blockname'])
#.........这里部分代码省略.........
示例2: SiteDBTest
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
class SiteDBTest(unittest.TestCase):
"""
Unit tests for SiteScreening module
"""
def setUp(self):
"""
Setup for unit tests
"""
self.mySiteDB = SiteDBJSON()
@attr("integration")
def testCmsNametoPhEDExNode(self):
"""
Tests CmsNametoSE
"""
target = ['T1_US_FNAL_MSS','T1_US_FNAL_Buffer']
results = self.mySiteDB.cmsNametoPhEDExNode("T1_US_FNAL")
self.failUnless(sorted(results) == sorted(target))
@attr("integration")
def testPhEDExNodetocmsName(self):
"""
Tests PhEDExNodetocmsName
"""
result = self.mySiteDB.phEDExNodetocmsName('T1_US_FNAL_MSS')
self.failUnless(result == 'T1_US_FNAL')
result = self.mySiteDB.phEDExNodetocmsName('T1_US_FNAL_Buffer')
self.failUnless(result == 'T1_US_FNAL')
result = self.mySiteDB.phEDExNodetocmsName('T2_UK_London_IC')
self.failUnless(result == 'T2_UK_London_IC')
# don't check this anymore, see comment in phEDExNodetocmsName function
#self.assertRaises(ValueError, self.mySiteDB.phEDExNodetocmsName,
# 'T9_DOESNT_EXIST_Buffer')
@attr("integration")
def testCmsNametoSE(self):
"""
Tests CmsNametoSE
"""
target = ['srm-cms.gridpp.rl.ac.uk']
results = self.mySiteDB.cmsNametoSE("T1_UK_RAL")
self.failUnless(sorted(results) == sorted(target))
@attr("integration")
def testSEtoCmsName(self):
"""
Tests CmsNametoSE
"""
target = 'T1_US_FNAL'
results = self.mySiteDB.seToCMSName("cmssrm.fnal.gov")
self.failUnless(results == target)
@attr("integration")
def testCmsNametoCE(self):
"""
Tests CmsNametoCE
"""
target = ['lcgce06.gridpp.rl.ac.uk', 'lcgce07.gridpp.rl.ac.uk', 'lcgce09.gridpp.rl.ac.uk']
results = self.mySiteDB.cmsNametoCE("T1_UK_RAL")
self.failUnless(sorted(results) == target)
@attr("integration")
def testJSONParser(self):
"""
Tests the JSON parser directly
"""
cmsName = "cmsgrid02.hep.wisc.edu"
results = self.mySiteDB.getJSON("CEtoCMSName",
file="CEtoCMSName",
name=cmsName)
self.failUnless(results['0']['name'] == "T2_US_Wisconsin")
@attr("integration")
def testDNUserName(self):
"""
Tests DN to Username lookup
"""
testDn = "/C=UK/O=eScience/OU=Bristol/L=IS/CN=simon metson"
testUserName = "metson"
userName = self.mySiteDB.dnUserName(dn=testDn)
self.failUnless(testUserName == userName)
def testDNWithApostrophe(self):
"""
Tests a DN with an apostrophy in - will fail till SiteDB2 appears
"""
testDn = "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=liviof/CN=472739/CN=Livio Fano'"
testUserName = "liviof"
userName = self.mySiteDB.dnUserName(dn=testDn)
self.failUnless(testUserName == userName)
@attr("integration")
def testParsingJsonWithApostrophe(self):
"""
Tests parsing a DN json with an apostrophe in
"""
json = """{"dn": "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=liviof/CN=472739/CN=Livio Fano'", "user": "liviof"}"""
d = self.mySiteDB.parser.dictParser(json)
self.assertEquals("/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=liviof/CN=472739/CN=Livio Fano'", d['dn'])
#.........这里部分代码省略.........
示例3: getFiles
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
def getFiles(datasetName, runBlacklist, runWhitelist, blockBlacklist,
blockWhitelist, dbsUrl):
"""
_getFiles_
Get the full information of a dataset including files, blocks, runs and lumis.
Filter it using run and block white/black lists.
It can receive and optional DBSUrl.
"""
dbsReader = DBSReader(endpoint = dbsUrl)
phedexReader = PhEDEx()
siteDB = SiteDBJSON()
files = {}
outputDatasetParts = datasetName.split("/")
datasets = dbsReader.matchProcessedDatasets(outputDatasetParts[1],
outputDatasetParts[3],
outputDatasetParts[2])
if len(datasets) == 0:
raise RuntimeError("Dataset %s doesn't exist in given DBS instance" % datasetName)
blockNames = dbsReader.listFileBlocks(datasetName)
for blockName in blockNames:
if blockBlacklist and blockName in blockBlacklist:
continue
if blockWhitelist and blockName not in blockWhitelist:
continue
replicaInfo = phedexReader.getReplicaInfoForBlocks(block = blockName,
subscribed = 'y')
block = dbsReader.listFilesInBlockWithParents(blockName)
blockLocations = set()
if len(replicaInfo["phedex"]["block"]) > 0:
for replica in replicaInfo["phedex"]["block"][0]["replica"]:
node = replica["node"]
cmsSites = siteDB.phEDExNodetocmsName(node)
if type(cmsSites) != list:
cmsSites = [cmsSites]
for cmsName in cmsSites:
blockLocations.update(siteDB.cmsNametoSE(cmsName))
for blockFile in block:
parentLFNs = []
for fileParent in blockFile["ParentList"]:
parentLFNs.append(fileParent["LogicalFileName"])
runInfo = {}
for lumiSection in blockFile["LumiList"]:
if runBlacklist and lumiSection["RunNumber"] in runBlacklist:
continue
if runWhitelist and lumiSection["RunNumber"] not in runWhitelist:
continue
if lumiSection["RunNumber"] not in runInfo.keys():
runInfo[lumiSection["RunNumber"]] = []
runInfo[lumiSection["RunNumber"]].append(lumiSection["LumiSectionNumber"])
if len(runInfo.keys()) > 0:
files[blockFile["LogicalFileName"]] = {"runs": runInfo,
"events": blockFile["NumberOfEvents"],
"size": blockFile["FileSize"],
"locations": list(blockLocations),
"parents": parentLFNs}
return files
示例4: SiteDBTest
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
class SiteDBTest(unittest.TestCase):
"""
Unit tests for SiteScreening module
"""
def setUp(self):
"""
Setup for unit tests
"""
EmulatorHelper.setEmulators(siteDB = True)
self.mySiteDB = SiteDBJSON()
def tearDown(self):
EmulatorHelper.resetEmulators()
def testCmsNametoPhEDExNode(self):
"""
Tests CmsNametoSE
"""
target = ['T1_US_FNAL_MSS','T1_US_FNAL_Buffer']
results = self.mySiteDB.cmsNametoPhEDExNode("T1_US_FNAL")
self.failUnless(sorted(results) == sorted(target))
def testPhEDExNodetocmsName(self):
"""
Tests PhEDExNodetocmsName
"""
result = self.mySiteDB.phEDExNodetocmsName('T1_US_FNAL_MSS')
self.failUnless(result == 'T1_US_FNAL')
result = self.mySiteDB.phEDExNodetocmsName('T1_US_FNAL_Buffer')
self.failUnless(result == 'T1_US_FNAL')
result = self.mySiteDB.phEDExNodetocmsName('T2_UK_London_IC')
self.failUnless(result == 'T2_UK_London_IC')
# don't check this anymore, see comment in phEDExNodetocmsName function
#self.assertRaises(ValueError, self.mySiteDB.phEDExNodetocmsName,
# 'T9_DOESNT_EXIST_Buffer')
def testCmsNametoSE(self):
"""
Tests CmsNametoSE
"""
target = ['srm-cms.gridpp.rl.ac.uk']
results = self.mySiteDB.cmsNametoSE("T1_UK_RAL")
self.failUnless(sorted(results) == sorted(target))
def testSEtoCmsName(self):
"""
Tests CmsNametoSE
"""
target = ['T1_US_FNAL']
results = self.mySiteDB.seToCMSName("cmssrm.fnal.gov")
self.failUnless(results == target)
target = sorted(['T2_CH_CERN', 'T2_CH_CERN_HLT'])
results = sorted(self.mySiteDB.seToCMSName("srm-eoscms.cern.ch"))
self.failUnless(results == target)
def testCmsNametoCE(self):
"""
Tests CmsNametoCE
"""
target = ['lcgce11.gridpp.rl.ac.uk', 'lcgce10.gridpp.rl.ac.uk',
'lcgce02.gridpp.rl.ac.uk']
results = self.mySiteDB.cmsNametoCE("T1_UK_RAL")
self.failUnless(sorted(results) == sorted(target))
def testDNUserName(self):
"""
Tests DN to Username lookup
"""
testDn = "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=gutsche/CN=582680/CN=Oliver Gutsche"
testUserName = "gutsche"
userName = self.mySiteDB.dnUserName(dn=testDn)
self.failUnless(testUserName == userName)
@attr("integration")
def testDNWithApostrophe(self):
"""
Tests a DN with an apostrophy in - will fail till SiteDB2 appears
"""
testDn = "/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN=liviof/CN=472739/CN=Livio Fano'"
testUserName = "liviof"
userName = self.mySiteDB.dnUserName(dn=testDn)
self.failUnless(testUserName == userName)
def testSEFinder(self):
"""
_testSEFinder_
See if we can retrieve seNames from all sites
"""
seNames = self.mySiteDB.getAllSENames()
self.assertTrue(len(seNames) > 1)
self.assertTrue('cmssrm.fnal.gov' in seNames)
return
示例5: PhEDExInjectorSubscriber
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
class PhEDExInjectorSubscriber(BaseWorkerThread):
"""
_PhEDExInjectorSubscriber_
Poll the DBSBuffer database and subscribe datasets as they are
created.
"""
def __init__(self, config):
"""
___init___
Initialise class members
"""
BaseWorkerThread.__init__(self)
self.phedex = PhEDEx({"endpoint": config.PhEDExInjector.phedexurl}, "json")
self.siteDB = SiteDBJSON()
self.dbsUrl = config.DBSInterface.globalDBSUrl
self.group = getattr(config.PhEDExInjector, "group", "DataOps")
self.safeMode = getattr(config.PhEDExInjector, "safeOperationMode", False)
# Subscribed state in the DBSBuffer table for datasets
self.terminalSubscriptionState = 1
if self.safeMode:
self.terminalSubscriptionState = 2
# We will map node names to CMS names, that what the spec will have.
# If a CMS name is associated to many PhEDEx node then choose the MSS option
self.cmsToPhedexMap = {}
# initialize the alert framework (if available - config.Alert present)
# self.sendAlert will be then be available
self.initAlerts(compName = "PhEDExInjector")
def setup(self, parameters):
"""
_setup_
Create a DAO Factory for the PhEDExInjector. Also load the SE names to
PhEDEx node name mappings from the data service.
"""
myThread = threading.currentThread()
daofactory = DAOFactory(package = "WMComponent.PhEDExInjector.Database",
logger = self.logger,
dbinterface = myThread.dbi)
self.getUnsubscribed = daofactory(classname = "GetUnsubscribedDatasets")
self.markSubscribed = daofactory(classname = "MarkDatasetSubscribed")
self.getPartiallySubscribed = daofactory(classname = "GetPartiallySubscribedDatasets")
nodeMappings = self.phedex.getNodeMap()
for node in nodeMappings["phedex"]["node"]:
cmsName = self.siteDB.phEDExNodetocmsName(node["name"])
if cmsName not in self.cmsToPhedexMap:
self.cmsToPhedexMap[cmsName] = {}
logging.info("Loaded PhEDEx node %s for site %s" % (node["name"], cmsName))
if node["kind"] not in self.cmsToPhedexMap[cmsName]:
self.cmsToPhedexMap[cmsName][node["kind"]] = node["name"]
return
def algorithm(self, parameters):
"""
_algorithm_
Poll the database for datasets and subscribe them.
"""
myThread = threading.currentThread()
myThread.transaction.begin()
# Check for completely unsubscribed datasets
unsubscribedDatasets = self.getUnsubscribed.execute(conn = myThread.transaction.conn,
transaction = True)
if self.safeMode:
partiallySubscribedDatasets = self.getPartiallySubscribed.execute(conn = myThread.transaction.conn,
transaction = True)
unsubscribedDatasets.extend(partiallySubscribedDatasets)
partiallySubscribedSet = set()
for entry in partiallySubscribedDatasets:
partiallySubscribedSet.add(entry["path"])
# Map the datasets to their specs
specDatasetMap = {}
for unsubscribedDataset in unsubscribedDatasets:
datasetPath = unsubscribedDataset["path"]
workflow = unsubscribedDataset["workflow"]
spec = unsubscribedDataset["spec"]
if datasetPath not in specDatasetMap:
specDatasetMap[datasetPath] = []
specDatasetMap[datasetPath].append({"workflow" : workflow, "spec" : spec})
specCache = {}
siteMap = {}
# Distribute the subscriptions by site, type and priority
# This is to make as few subscriptions as possible
#.........这里部分代码省略.........
示例6: PhEDExInjectorSubscriber
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
class PhEDExInjectorSubscriber(BaseWorkerThread):
"""
_PhEDExInjectorSubscriber_
Poll the DBSBuffer database and subscribe datasets as they are
created.
"""
def __init__(self, config):
"""
___init___
Initialise class members
"""
BaseWorkerThread.__init__(self)
self.phedex = PhEDEx({"endpoint": config.PhEDExInjector.phedexurl}, "json")
self.siteDB = SiteDBJSON()
self.dbsUrl = config.DBSInterface.globalDBSUrl
self.group = getattr(config.PhEDExInjector, "group", "DataOps")
# We will map node names to CMS names, that what the spec will have.
# If a CMS name is associated to many PhEDEx node then choose the MSS option
self.cmsToPhedexMap = {}
self.phedexNodes = {"MSS": [], "Disk": []}
# initialize the alert framework (if available - config.Alert present)
# self.sendAlert will be then be available
self.initAlerts(compName="PhEDExInjector")
def setup(self, parameters):
"""
_setup_
Create a DAO Factory for the PhEDExInjector. Also load the SE names to
PhEDEx node name mappings from the data service.
"""
myThread = threading.currentThread()
daofactory = DAOFactory(
package="WMComponent.PhEDExInjector.Database", logger=self.logger, dbinterface=myThread.dbi
)
self.getUnsubscribed = daofactory(classname="GetUnsubscribedDatasets")
self.markSubscribed = daofactory(classname="MarkDatasetSubscribed")
nodeMappings = self.phedex.getNodeMap()
for node in nodeMappings["phedex"]["node"]:
cmsName = self.siteDB.phEDExNodetocmsName(node["name"])
if cmsName not in self.cmsToPhedexMap:
self.cmsToPhedexMap[cmsName] = {}
logging.info("Loaded PhEDEx node %s for site %s" % (node["name"], cmsName))
if node["kind"] not in self.cmsToPhedexMap[cmsName]:
self.cmsToPhedexMap[cmsName][node["kind"]] = node["name"]
if node["kind"] in ["MSS", "Disk"]:
self.phedexNodes[node["kind"]].append(node["name"])
return
def algorithm(self, parameters):
"""
_algorithm_
Run the subscription algorithm as configured
"""
self.subscribeDatasets()
return
def subscribeDatasets(self):
"""
_subscribeDatasets_
Poll the database for datasets and subscribe them.
"""
myThread = threading.currentThread()
myThread.transaction.begin()
# Check for completely unsubscribed datasets
unsubscribedDatasets = self.getUnsubscribed.execute(conn=myThread.transaction.conn, transaction=True)
# Keep a list of subscriptions to tick as subscribed in the database
subscriptionsMade = []
# Create a list of subscriptions as defined by the PhEDEx data structures
subs = SubscriptionList()
# Create the subscription objects and add them to the list
# The list takes care of the sorting internally
for subInfo in unsubscribedDatasets:
site = subInfo["site"]
if site not in self.phedexNodes["MSS"] and site not in self.phedexNodes["Disk"]:
if site not in self.cmsToPhedexMap:
msg = "Site %s doesn't appear to be valid to PhEDEx, " % site
msg += "skipping subscription: %s" % subInfo["id"]
logging.error(msg)
self.sendAlert(7, msg=msg)
continue
#.........这里部分代码省略.........
示例7: getFiles
# 需要导入模块: from WMCore.Services.SiteDB.SiteDB import SiteDBJSON [as 别名]
# 或者: from WMCore.Services.SiteDB.SiteDB.SiteDBJSON import phEDExNodetocmsName [as 别名]
def getFiles(datasetName, runBlacklist, runWhitelist, blockBlacklist,
blockWhitelist, dbsUrl):
"""
_getFiles_
Get the full information of a dataset including files, blocks, runs and lumis.
Filter it using run and block white/black lists.
It can receive and optional DBSUrl.
"""
dbsReader = DBSReader(endpoint = dbsUrl)
phedexReader = PhEDEx()
siteDB = SiteDBJSON()
files = {}
outputDatasetParts = datasetName.split("/")
print "dataset",datasetName,"parts",outputDatasetParts
try:
#retrieve list of blocks from dataset
blockNames = dbsReader.listFileBlocks(datasetName)
except:
raise RuntimeError("Dataset %s doesn't exist in given DBS instance" % datasetName)
#traverse each block
for blockName in blockNames:
#deal with white and black list.
if blockBlacklist and blockName in blockBlacklist:
continue
if blockWhitelist and blockName not in blockWhitelist:
continue
#existing blocks in phedex
replicaInfo = phedexReader.getReplicaInfoForBlocks(block = blockName,
subscribed = 'y')
blockFiles = dbsReader.listFilesInBlock(blockName, lumis=True)
blockLocations = set()
#load block locations
if len(replicaInfo["phedex"]["block"]) > 0:
for replica in replicaInfo["phedex"]["block"][0]["replica"]:
node = replica["node"]
cmsSites = siteDB.phEDExNodetocmsName(node)
if type(cmsSites) != list:
cmsSites = [cmsSites]
for cmsName in cmsSites:
blockLocations.update(siteDB.cmsNametoSE(cmsName))
#for each file on the block
for blockFile in blockFiles:
parentLFNs = []
#get parent information about file
blockFileParents = dbsReader.listFilesInBlockWithParents(blockName)
#populate parent information
if blockFileParents and "ParentList" in blockFileParents[0]:
for fileParent in blockFileParents[0]["ParentList"]:
parentLFNs.append(fileParent["LogicalFileName"])
runInfo = {}
#Lumis not included in file
for lumiSection in blockFile["LumiList"]:
if runBlacklist and lumiSection["RunNumber"] in runBlacklist:
continue
if runWhitelist and lumiSection["RunNumber"] not in runWhitelist:
continue
if lumiSection["RunNumber"] not in runInfo.keys():
runInfo[lumiSection["RunNumber"]] = []
runInfo[lumiSection["RunNumber"]].append(lumiSection["LumiSectionNumber"])
if len(runInfo.keys()) > 0:
files[blockFile["LogicalFileName"]] = {"runs": runInfo,
"events": blockFile["NumberOfEvents"],
"size": blockFile["FileSize"],
"locations": list(blockLocations),
"parents": parentLFNs}
return files