Search in sources :

Example 1 with PinManagerPinMessage

use of org.dcache.pinmanager.PinManagerPinMessage in project dcache by dCache.

the class StagingAdjuster method poll.

/**
 * Polled by main map thread.  If the future is done, this will trigger the completion handler.
 */
public void poll() {
    synchronized (this) {
        if (future == null) {
            completionHandler.taskFailed(pnfsId, Optional.empty(), new CacheException(CacheException.SERVICE_UNAVAILABLE, "no future returned by message send."));
            return;
        }
    }
    PinManagerPinMessage migrationReply = null;
    Object error = null;
    try {
        LOGGER.debug("poll, checking pin request future.isDone() for {}.", pnfsId);
        if (!future.isDone()) {
            return;
        }
        migrationReply = getUninterruptibly(future);
        if (migrationReply.getReturnCode() != 0) {
            error = migrationReply.getErrorObject();
        }
    } catch (CancellationException e) {
    /*
             *  Cancelled state set by caller.
             */
    } catch (ExecutionException e) {
        error = e.getCause();
    }
    LOGGER.debug("poll, calling completion handler for {}.", pnfsId);
    String target = migrationReply.getPool();
    if (error == null) {
        completionHandler.taskCompleted(pnfsId, Optional.ofNullable(target));
    } else if (error instanceof Throwable) {
        completionHandler.taskFailed(pnfsId, Optional.ofNullable(target), new CacheException("Pin failure", (Throwable) error));
    } else {
        completionHandler.taskFailed(pnfsId, Optional.ofNullable(target), new CacheException(String.valueOf(error)));
    }
}
Also used : CacheException(diskCacheV111.util.CacheException) CancellationException(java.util.concurrent.CancellationException) PinManagerPinMessage(org.dcache.pinmanager.PinManagerPinMessage) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with PinManagerPinMessage

use of org.dcache.pinmanager.PinManagerPinMessage in project dcache by dCache.

the class FileResources method cmrResources.

@POST
@ApiOperation(value = "Modify a file or directory.")
@Path("{path : .*}")
@ApiResponses({ @ApiResponse(code = 400, message = "Transition for directories not supported"), @ApiResponse(code = 400, message = "Unsupported QoS transition"), @ApiResponse(code = 400, message = "Unknown target QoS"), @ApiResponse(code = 400, message = "Unknown action"), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 404, message = "Not Found"), @ApiResponse(code = 409, message = "Attribute already exists"), @ApiResponse(code = 409, message = "No such attribute"), @ApiResponse(code = 500, message = "Internal Server Error") })
@Consumes({ MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON)
public Response cmrResources(@ApiParam(value = "Path of file or directory to be modified.", required = true) @PathParam("path") String requestPath, @ApiParam(value = "A JSON object that has an 'action' " + "item with a String value.\n" + "\n" + "If the 'action' value is 'mkdir' " + "then a new directory is created " + "with the name taken from the " + "value of the JSON object 'name' " + "item.  This directory is created " + "within the supplied path parameter, " + "which must be an existing directory.\n" + "\n" + "If action is 'mv' then the file " + "or directory specified by the path " + "parameter is moved and/or " + "renamed with the value of the JSON " + "object 'destination' item describing " + "the final location.  If the " + "'destination' value is a relative " + "path then it is resolved against " + "the path parameter value.\n" + "\n" + "If action is 'qos' then the value " + "of the JSON object 'target' item " + "describes the desired QoS." + "\n" + "If action is 'pin' then the default " + "value of lifetime is 0 and liftime-unit " + "SECONDS." + "\n" + "If action is 'rm-xattr' then " + "extended attributes of a file " + "or directory are removed as " + "given by the 'names' item.  The " + "'names' value is either a " + "string or an array of strings." + "\n" + "If action is 'set-xattr' then " + "extended attributes are created " + "or modified.  The optional " + "'mode' item controls whether to " + "create a new attribute (CREATE), " + "to modify an existing attribute " + "(MODIFY), or to assign the value " + "by either creating a new " + "attribute or modifying an " + "existing attribute (EITHER).  " + "EITHER is the default mode.  The " + "'attributes' item value is a JSON " + "Object with the new attributes," + "where the JSON Object's key is " + "the attribute name and the " + "corresponding JSON Object's " + "value is this attribute's value." + "\n" + "If action is 'set-label' then " + "a label is added to the" + "given file object." + "'label' item value is a String." + "\n" + "If action is 'rm-label' then the corresponding" + "label of a file is removed." + "The  'label' value is either a string." + "\n" + "If action is 'chgrp' then the " + "command requests the change of " + "group-owner of the target file " + "or directory.  The value of the " + "JSON object 'gid' item is the " + "numerical value of the desired " + "new group-owner." + "\n" + "If action is 'chmod' then the " + "command reqests the change of " + "the target file's or directory's " + "permissions.  The value of the " + "JSON object 'mode' item is the " + "numerical value of the desired " + "mode.", required = true, examples = @Example({ @ExampleProperty(mediaType = "MV", value = "{\n" + "    \"action\" : \"mv\",\n" + "    \"destination\" : \"../foo\"\n" + "}"), @ExampleProperty(mediaType = "MKDIR", value = "{\n" + "    \"action\" : \"mkdir\",\n" + "    \"name\" : \"new-subdir\"\n" + "}"), @ExampleProperty(mediaType = "QOS", value = "{\n" + "    \"action\" : \"qos\",\n" + "    \"target\" : \"DISK+TAPE\"\n" + "}"), @ExampleProperty(mediaType = "PIN", value = "{\n" + "    \"action\" : \"pin\",\n" + "    \"lifetime\" : \"number\"\n" + "    \"lifetime-unit\" : \"SECONDS|MINUTES|HOURS|DAYS\"\n" + "}"), @ExampleProperty(mediaType = "UNPIN", value = "{\n" + "    \"action\" : \"unpin\",\n" + "}"), @ExampleProperty(mediaType = "SET-XATTR", value = "{\n" + "    \"action\" : \"set-xattr\",\n" + "    \"mode\" : \"CREATE\",\n" + "    \"attributes\" : {\n" + "        \"attr-1\": \"First attribute\",\n" + "        \"attr-2\": \"Second attribute\"\n" + "    }\n" + "}"), @ExampleProperty(mediaType = "RM-XATTR", value = "{\n" + "    \"action\" : \"rm-xattr\",\n" + "    \"names\" : [\n" + "        \"attr-1\",\n" + "        \"attr-2\"\n" + "    ]\n" + "}"), @ExampleProperty(mediaType = "SET-LABEL", value = "{\n" + "    \"action\" : \"set-label\",\n" + "    \"label\" : : \"label\",\n" + "}"), @ExampleProperty(mediaType = "RM-LABEL", value = "{\n" + "    \"action\" : \"rm-label\",\n" + "    \"label\" :  \"label\",\n" + "}"), @ExampleProperty(mediaType = "CHGRP", value = "{\n" + "    \"action\" : \"chgrp\",\n" + "    \"gid\" : 1000\n" + "}"), @ExampleProperty(mediaType = "CHMOD", value = "{\n" + "    \"action\" : \"chmod\",\n" + "    \"mode\" : 493\n" + "}") })) String requestPayload) {
    try {
        JSONObject reqPayload = new JSONObject(requestPayload);
        String action = (String) reqPayload.get("action");
        PnfsHandler pnfsHandler = HandlerBuilders.roleAwarePnfsHandler(pnfsmanager);
        FsPath path = pathMapper.asDcachePath(request, requestPath, ForbiddenException::new);
        PnfsId pnfsId;
        Long uid;
        switch(action) {
            case "mkdir":
                String name = (String) reqPayload.get("name");
                FsPath.checkChildName(name, BadRequestException::new);
                pnfsHandler = HandlerBuilders.pnfsHandler(// FIXME: non-role identity to ensure correct ownership
                pnfsmanager);
                pnfsHandler.createPnfsDirectory(path.child(name).toString());
                break;
            case "mv":
                String dest = (String) reqPayload.get("destination");
                FsPath target = pathMapper.resolve(request, path, dest);
                pnfsHandler.renameEntry(path.toString(), target.toString(), true);
                break;
            case "qos":
                String targetQos = reqPayload.getString("target");
                new QoSTransitionEngine(poolmanager, poolMonitor, pnfsHandler, pinmanager).adjustQoS(path, targetQos, request.getRemoteHost());
                break;
            case "pin":
                Integer lifetime = reqPayload.optInt("lifetime");
                if (lifetime == null) {
                    lifetime = 0;
                }
                String lifetimeUnitVal = reqPayload.optString("lifetime-unit");
                TimeUnit lifetimeUnit = lifetimeUnitVal == null ? TimeUnit.SECONDS : TimeUnit.valueOf(lifetimeUnitVal);
                pnfsId = pnfsHandler.getPnfsIdByPath(path.toString());
                /*
                     *  Fire-and-forget, as it was in 5.2
                     */
                pinmanager.notify(new PinManagerPinMessage(FileAttributes.ofPnfsId(pnfsId), getProtocolInfo(), getRequestId(), lifetimeUnit.toMillis(lifetime)));
                break;
            case "unpin":
                pnfsId = pnfsHandler.getPnfsIdByPath(path.toString());
                PinManagerUnpinMessage message = new PinManagerUnpinMessage(pnfsId);
                message.setRequestId(getRequestId());
                pinmanager.notify(message);
                break;
            case "rm-xattr":
                Object namesArgument = reqPayload.get("names");
                if (namesArgument instanceof String) {
                    pnfsHandler.removeExtendedAttribute(path, (String) namesArgument);
                } else if (namesArgument instanceof JSONArray) {
                    JSONArray namesArray = (JSONArray) namesArgument;
                    List<String> names = new ArrayList<>(namesArray.length());
                    for (int i = 0; i < namesArray.length(); i++) {
                        names.add(namesArray.getString(i));
                    }
                    pnfsHandler.removeExtendedAttribute(path, names);
                } else {
                    throw new JSONException("\"names\" is not a String or an array");
                }
                break;
            case "set-xattr":
                String modeString = reqPayload.optString("mode", "EITHER");
                Mode xattrSetMode = modeOf(modeString);
                JSONObject attributeOject = reqPayload.getJSONObject("attributes");
                Map<String, byte[]> attributes = new HashMap<>(attributeOject.length());
                for (String key : attributeOject.keySet()) {
                    String value = attributeOject.getString(key);
                    attributes.put(key, value.getBytes(StandardCharsets.UTF_8));
                }
                pnfsHandler.writeExtendedAttribute(path, attributes, xattrSetMode);
                break;
            case "set-label":
                String label = reqPayload.getString("label");
                pnfsHandler.setFileAttributes(path, FileAttributes.ofLabel(label));
                break;
            case "rm-label":
                String labelsArgument = reqPayload.getString("label");
                pnfsHandler.removeLabel(path, labelsArgument);
                break;
            case "chgrp":
                int gid = reqPayload.getInt("gid");
                pnfsHandler.setFileAttributes(path, FileAttributes.ofGid(gid));
                break;
            case "chmod":
                int mode = reqPayload.getInt("mode");
                pnfsHandler.setFileAttributes(path, FileAttributes.ofMode(mode));
                break;
            default:
                throw new UnsupportedOperationException("No such action " + action);
        }
    } catch (FileNotFoundCacheException e) {
        throw new NotFoundException(e);
    } catch (PermissionDeniedCacheException e) {
        if (RequestUser.isAnonymous()) {
            throw new NotAuthorizedException(e);
        } else {
            throw new ForbiddenException(e);
        }
    } catch (AttributeExistsCacheException e) {
        throw new WebApplicationException(Response.status(409, "Attribute already exist").build());
    } catch (NoAttributeCacheException e) {
        throw new WebApplicationException(Response.status(409, "No such attribute").build());
    } catch (UnsupportedOperationException | URISyntaxException | JSONException | CacheException | InterruptedException | NoRouteToCellException e) {
        throw new BadRequestException(e.getMessage(), e);
    }
    return successfulResponse(Response.Status.CREATED);
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) AttributeExistsCacheException(diskCacheV111.util.AttributeExistsCacheException) CacheException(diskCacheV111.util.CacheException) NoAttributeCacheException(diskCacheV111.util.NoAttributeCacheException) FileNotFoundCacheException(diskCacheV111.util.FileNotFoundCacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) QoSTransitionEngine(org.dcache.qos.QoSTransitionEngine) NotFoundException(javax.ws.rs.NotFoundException) NotAuthorizedException(javax.ws.rs.NotAuthorizedException) URISyntaxException(java.net.URISyntaxException) NoAttributeCacheException(diskCacheV111.util.NoAttributeCacheException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ArrayList(java.util.ArrayList) FsPath(diskCacheV111.util.FsPath) AttributeExistsCacheException(diskCacheV111.util.AttributeExistsCacheException) ForbiddenException(javax.ws.rs.ForbiddenException) PnfsId(diskCacheV111.util.PnfsId) Mode(diskCacheV111.vehicles.PnfsWriteExtendedAttributesMessage.Mode) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) PnfsHandler(diskCacheV111.util.PnfsHandler) PinManagerPinMessage(org.dcache.pinmanager.PinManagerPinMessage) PinManagerUnpinMessage(org.dcache.pinmanager.PinManagerUnpinMessage) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) JSONObject(org.json.JSONObject) NoRouteToCellException(dmg.cells.nucleus.NoRouteToCellException) BadRequestException(javax.ws.rs.BadRequestException) FileNotFoundCacheException(diskCacheV111.util.FileNotFoundCacheException) JSONObject(org.json.JSONObject) Path(javax.ws.rs.Path) FsPath(diskCacheV111.util.FsPath) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 3 with PinManagerPinMessage

use of org.dcache.pinmanager.PinManagerPinMessage in project dcache by dCache.

the class PinJob method doRun.

@Override
protected void doRun() {
    long lifetime = getLifetime(arguments);
    try {
        String requestId = arguments == null ? null : arguments.get(PIN_REQUEST_ID.getName());
        if (requestId == null) {
            requestId = key.getRequestId();
        }
        PinManagerPinMessage message = new PinManagerPinMessage(attributes, getProtocolInfo(), requestId, lifetime);
        sendToPinManager(message);
    } catch (URISyntaxException e) {
        setError(e);
    }
}
Also used : PinManagerPinMessage(org.dcache.pinmanager.PinManagerPinMessage) URISyntaxException(java.net.URISyntaxException)

Example 4 with PinManagerPinMessage

use of org.dcache.pinmanager.PinManagerPinMessage in project dcache by dCache.

the class QoSTransitionEngine method adjustQoS.

public void adjustQoS(FsPath path, String target, String remoteHost) throws UnsupportedOperationException, URISyntaxException, CacheException, InterruptedException, NoRouteToCellException {
    attributes = pnfsHandler.getFileAttributes(path, TRANSITION_ATTRIBUTES);
    FileLocality locality = getLocality(remoteHost);
    PnfsId id = attributes.getPnfsId();
    LOGGER.debug("{} locality: {}", id, locality);
    if (locality == FileLocality.NONE) {
        throw new UnsupportedOperationException("Transition for directories " + "not supported");
    }
    Qos qosTarget;
    try {
        qosTarget = Qos.fromDisplayName(target);
        LOGGER.debug("{}, new target QoS {}.", id, qosTarget);
    } catch (IllegalArgumentException e) {
        throw new UnsupportedOperationException("Bad QoS Target type", e);
    }
    AccessLatency currentAccessLatency = attributes.getAccessLatency();
    RetentionPolicy currentRetentionPolicy = attributes.getRetentionPolicy();
    LOGGER.debug("{}, AccessLatency {}, Retention Policy {}.", id, currentAccessLatency, currentRetentionPolicy);
    FileAttributes modifiedAttr = new FileAttributes();
    ListenableFuture<PoolMigrationMessage> migrationFuture = null;
    ListenableFuture<PinManagerPinMessage> pinFuture = null;
    switch(qosTarget) {
        case DISK_TAPE:
            if (locality == FileLocality.ONLINE) {
                LOGGER.debug("{}, attempting to migrate.", id);
                migrationFuture = conditionallyMigrateToTapePool(modifiedAttr, currentRetentionPolicy);
            }
            if (!currentAccessLatency.equals(AccessLatency.ONLINE)) {
                LOGGER.debug("{}, changing access latency to ONLINE", id);
                modifiedAttr.setAccessLatency(AccessLatency.ONLINE);
            }
            updateNamespace(modifiedAttr, id, path);
            // REVISIT when Resilience manages QoS for all files, remove
            if (!isPinnedForQoS()) {
                LOGGER.debug("{}, pinning for QoS.", id);
                pinFuture = pinForQoS(remoteHost);
            }
            break;
        case DISK:
            if (locality == FileLocality.ONLINE) {
                /*
                     *  ONLINE locality may not denote ONLINE access latency.
                     *  ONLINE locality and NEARLINE access latency should
                     *  not translate to 'Disk' qos.
                     */
                if (!currentAccessLatency.equals(AccessLatency.ONLINE)) {
                    LOGGER.debug("{}, changing access latency to ONLINE", id);
                    modifiedAttr.setAccessLatency(AccessLatency.ONLINE);
                    updateNamespace(modifiedAttr, id, path);
                }
                // REVISIT when Resilience manages QoS for all files, remove
                if (!isPinnedForQoS()) {
                    LOGGER.debug("{}, pinning for QoS.", id);
                    pinFuture = pinForQoS(remoteHost);
                }
            } else if (currentRetentionPolicy.equals(RetentionPolicy.CUSTODIAL)) {
                /*
                     *  Technically, to make the QoS semantics in
                     *  Chimera consistent, one would need to change this
                     *  to REPLICA, even though this would not trigger
                     *  deletion from tape.  It is probably best to
                     *  continue not supporting this transition.
                     */
                throw new UnsupportedOperationException("Unsupported QoS transition");
            }
            break;
        case TAPE:
            if (locality == FileLocality.ONLINE) {
                LOGGER.debug("{}, attempting to migrate.", id);
                migrationFuture = conditionallyMigrateToTapePool(modifiedAttr, currentRetentionPolicy);
            }
            if (!currentAccessLatency.equals(AccessLatency.NEARLINE)) {
                LOGGER.debug("{}, changing access latency to NEARLINE", id);
                modifiedAttr.setAccessLatency(AccessLatency.NEARLINE);
            }
            updateNamespace(modifiedAttr, id, path);
            // REVISIT when Resilience manages QoS for all files, remove
            LOGGER.debug("{}, unpinning QoS.", id);
            unpinForQoS();
            break;
        default:
            throw new UnsupportedOperationException("Unsupported QoS target for transition");
    }
    if (replyHandler != null) {
        replyHandler.setMigrationFuture(migrationFuture);
        replyHandler.setPinFuture(pinFuture);
        replyHandler.listen();
    }
}
Also used : AccessLatency(diskCacheV111.util.AccessLatency) PnfsId(diskCacheV111.util.PnfsId) PoolMigrationMessage(org.dcache.pool.migration.PoolMigrationMessage) PinManagerPinMessage(org.dcache.pinmanager.PinManagerPinMessage) FileLocality(diskCacheV111.util.FileLocality) RetentionPolicy(diskCacheV111.util.RetentionPolicy) FileAttributes(org.dcache.vehicles.FileAttributes)

Example 5 with PinManagerPinMessage

use of org.dcache.pinmanager.PinManagerPinMessage in project dcache by dCache.

the class QoSTransitionEngine method pinForQoS.

/**
 * The QOS_PIN_REQUEST_ID is stored for the pin to allow filtering on files that are pinned by
 * Qos or SRM.
 */
private ListenableFuture<PinManagerPinMessage> pinForQoS(String remoteHost) throws URISyntaxException {
    HttpProtocolInfo protocolInfo = new HttpProtocolInfo("Http", 1, 1, new InetSocketAddress(remoteHost, 0), null, null, null, new URI("http", remoteHost, null, null));
    PinManagerPinMessage message = new PinManagerPinMessage(attributes, protocolInfo, QOS_PIN_REQUEST_ID, -1);
    return pinManager.send(message, Long.MAX_VALUE);
}
Also used : InetSocketAddress(java.net.InetSocketAddress) HttpProtocolInfo(diskCacheV111.vehicles.HttpProtocolInfo) PinManagerPinMessage(org.dcache.pinmanager.PinManagerPinMessage) URI(java.net.URI)

Aggregations

PinManagerPinMessage (org.dcache.pinmanager.PinManagerPinMessage)7 CacheException (diskCacheV111.util.CacheException)3 URISyntaxException (java.net.URISyntaxException)3 PermissionDeniedCacheException (diskCacheV111.util.PermissionDeniedCacheException)2 PnfsId (diskCacheV111.util.PnfsId)2 NoRouteToCellException (dmg.cells.nucleus.NoRouteToCellException)2 InetSocketAddress (java.net.InetSocketAddress)2 AccessLatency (diskCacheV111.util.AccessLatency)1 AttributeExistsCacheException (diskCacheV111.util.AttributeExistsCacheException)1 FileLocality (diskCacheV111.util.FileLocality)1 FileNotFoundCacheException (diskCacheV111.util.FileNotFoundCacheException)1 FsPath (diskCacheV111.util.FsPath)1 NoAttributeCacheException (diskCacheV111.util.NoAttributeCacheException)1 PnfsHandler (diskCacheV111.util.PnfsHandler)1 RetentionPolicy (diskCacheV111.util.RetentionPolicy)1 DCapProtocolInfo (diskCacheV111.vehicles.DCapProtocolInfo)1 HttpProtocolInfo (diskCacheV111.vehicles.HttpProtocolInfo)1 Mode (diskCacheV111.vehicles.PnfsWriteExtendedAttributesMessage.Mode)1 ProtocolInfo (diskCacheV111.vehicles.ProtocolInfo)1 ApiOperation (io.swagger.annotations.ApiOperation)1