Artifactory中Groovy插件调用repositories.getStats始终返回null问题排查
Artifactory Groovy插件获取Docker镜像下载统计的调用问题
在自行部署的Artifactory服务器上开发Groovy插件,需获取平台托管Docker镜像的下载统计信息,已确认所需统计数据完整存储在对应路径的manifest.json文件中。
按照公开接口设计,传入RepoPath参数调用repositories.getStats()方法,预期可返回包含getDownloadCount()方法的StatsInfo对象,但实际无论传入何种路径参数,该方法始终返回null。
已尝试传入的路径值包括:
docker-local(本地Docker仓库根路径)docker-local/ai(Docker镜像路径)docker-local/ai/latest(Docker镜像标签路径)docker-local/ai/latest/manifest.json(镜像清单文件路径)
所有路径调用后均未获得有效返回值。
实际异常表现
开发者预期可正常运行的代码逻辑:
def stats = repositories.getStats(RepoPathFactory.create('docker-local','ai/latest/manifest.json')) def dlCount = stats.getDownloadCount()
实际执行持续报错:Cannot invoke method getDownloadCount() on null object,说明repositories.getStats()未返回有效对象。
对照验证:通过Artifactory原生REST接口查询同一文件,附加?stats参数可正常返回完整下载统计JSON。示例请求为my-artifactory-server.io/api/storage/docker-local/ai/latest/manifest.json?stats,返回结构如下:
{ "uri" : "my-artifactory-server.io/api/storage/docker-local/ai/latest/manifest.json", "downloadCount" : 10, "lastDownloaded" : 1593160404880, "lastDownloadedBy" : "Peter Griffin", "remoteDownloadCount" : 0, "remoteLastDownloaded" : 0 }
对照结果确认:底层存储的下载统计数据完整有效,不存在数据丢失问题,异常完全来自Groovy插件内的API调用逻辑。
具体使用错误定位
- 调用的API与目标数据不匹配
插件上下文的repositories.getStats()方法,设计目标是返回仓库维度的基础存储元数据(包括仓库总存储占用、仓库下的文件总数等),实现逻辑不会读取单文件维度的下载次数、最近下载人、最近下载时间这类访问行为统计。该方法的返回值结构,和REST接口中?stats参数对应的单文件访问统计并非同一套实现,本身就不存在包含downloadCount字段的逻辑。 - 传参不符合方法的内部校验规则
repositories.getStats()仅当传入的RepoPath指向仓库根路径时,才会匹配到对应的仓库级统计对象并返回有效结果;只要传入的路径是仓库下的具体文件路径,方法的内部校验就会判定路径无效,直接返回null。这也解释了尝试传入docker-local/ai/latest/manifest.json这类具体文件路径时,调用结果永远为空。
正确实现逻辑
如需获取和REST接口返回一致的单文件下载统计,需要调用对应粒度的服务接口,而非使用仓库维度的getStats方法,示例代码:
// 根据目标路径生成仓库路径对象 def targetRepoPath = repoPathFactory.create('docker-local', 'ai/latest/manifest.json') // 通过文件服务获取对应路径的文件项 def targetItem = itemService.getItem(targetRepoPath) // 调用统计服务获取单文件访问统计,返回结构与REST接口?stats参数完全对齐 def fileAccessStats = statisticService.getStats(targetItem) def downloadCount = fileAccessStats.downloadCount
内容的提问来源于stack exchange,提问作者DHummel
相关产品推荐
相关产品推荐

