From ff308e54e60334f7fe99abaf383ec46e19fcdd30 Mon Sep 17 00:00:00 2001 From: Dmitry Litvintsev Date: Wed, 6 Nov 2024 12:46:46 -0600 Subject: [PATCH] tape REST api: additional fix tohandling of prefixed paths Motivation: ----------- Users reported 2 day pin lifetime on staged files (which is a default) despite specifying different values. This is due to failure to match target key on truncated vs prefixed path in target argument map keyed on un-prefixed paths. Modification: ------------- Use full target paths throughout the system. Make sure to strip prefix when exposing paths to users. Result: ------- Observe correct user specified pin lifetime. Ticket: https://github.com/dCache/dcache/issues/7687 Patch: https://rb.dcache.org/r/14339/ Target: trunk Request: 10.2, 10.1, 10.0, 9.2 Require-book: no Require-notes: yes Signed-off-by: Dmitry Litvintsev --- .../restful/resources/tape/ReleaseResources.java | 9 ++++++--- .../restful/resources/tape/StageResources.java | 14 +++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/ReleaseResources.java b/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/ReleaseResources.java index f278bfacb4c..57750c66a01 100644 --- a/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/ReleaseResources.java +++ b/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/ReleaseResources.java @@ -159,6 +159,9 @@ public Response release( JSONArray paths; List targetPaths; + FsPath userRoot = LoginAttributes.getUserRoot(getLoginAttributes(request)); + FsPath rootPath = pathMapper.effectiveRoot(userRoot, ForbiddenException::new); + try { JSONObject reqPayload = new JSONObject(requestPayload); paths = reqPayload.getJSONArray("paths"); @@ -170,7 +173,9 @@ public Response release( int len = paths.length(); targetPaths = new ArrayList<>(); for (int i = 0; i < len; ++i) { - targetPaths.add(paths.getString(i)); + String requestPath = paths.getString(i); + String path = rootPath.chroot(requestPath).toString(); + targetPaths.add(path); } } catch (JSONException e) { throw newBadRequestException(requestPayload, e); @@ -178,8 +183,6 @@ public Response release( Subject subject = getSubject(); Restriction restriction = getRestriction(); - FsPath userRoot = LoginAttributes.getUserRoot(getLoginAttributes(request)); - FsPath rootPath = pathMapper.effectiveRoot(userRoot, ForbiddenException::new); /* * For WLCG, this is a fire-and-forget request, so it does not need to diff --git a/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/StageResources.java b/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/StageResources.java index 9876209b3e5..72f39bb11a1 100644 --- a/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/StageResources.java +++ b/modules/dcache-frontend/src/main/java/org/dcache/restful/resources/tape/StageResources.java @@ -167,6 +167,8 @@ public StageRequestInfo getStageInfo(@ApiParam("The unique id of the request.") @PathParam("id") String id) { Subject subject = getSubject(); Restriction restriction = getRestriction(); + FsPath userRoot = LoginAttributes.getUserRoot(getLoginAttributes(request)); + FsPath rootPath = pathMapper.effectiveRoot(userRoot, ForbiddenException::new); BulkRequestInfo lastInfo = null; List targetInfos = new ArrayList<>(); @@ -187,6 +189,7 @@ public StageRequestInfo getStageInfo(@ApiParam("The unique id of the request.") offset = lastInfo.getNextId(); } + targetInfos.forEach(ti -> ti.setTarget(FsPath.create(ti.getTarget()).stripPrefix(rootPath))); lastInfo.setTargets(targetInfos); return new StageRequestInfo(lastInfo); @@ -218,7 +221,9 @@ public Response cancel( + "does not belong to that stage request, this request will fail.", required = true) String requestPayload) { - JSONObject reqPayload; + FsPath userRoot = LoginAttributes.getUserRoot(getLoginAttributes(request)); + FsPath rootPath = pathMapper.effectiveRoot(userRoot, ForbiddenException::new); + JSONObject reqPayload; JSONArray paths; try { reqPayload = new JSONObject(requestPayload); @@ -233,7 +238,9 @@ public Response cancel( List targetPaths = new ArrayList<>(); int len = paths.length(); for (int i = 0; i < len; ++i) { - targetPaths.add(paths.getString(i)); + String requestPath = paths.getString(i); + String path = rootPath.chroot(requestPath).toString(); + targetPaths.add(path); } Subject subject = getSubject(); @@ -390,7 +397,8 @@ private BulkRequest toBulkRequest(String requestPayload, FsPath rootPath) { if (!file.has("path")) { throw new BadRequestException("file object " + i + " has no path."); } - String path = file.getString("path"); + String requestPath = file.getString("path"); + String path = rootPath.chroot(requestPath).toString(); paths.add(path); if (file.has("diskLifetime")) { jsonLifetimes.put(path,