/**
   * Gets the current status of the object, (including transition status), for the object specified
   * by path.
   *
   * @param requestPath path to a file
   * @return JSONObject current QoS status
   * @throws CacheException
   */
  @GET
  @Path("{requestPath : .*}")
  @Produces(MediaType.APPLICATION_JSON)
  public BackendCapabilityResponse getQosStatus(@PathParam("requestPath") String requestPath)
      throws CacheException, URISyntaxException {

    BackendCapabilityResponse response = new BackendCapabilityResponse();
    try {
      if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) {
        throw new PermissionDeniedCacheException("Permission denied");
      }

      FileAttributes fileAttributes = getFileAttributes(requestPath);
      FileLocality fileLocality = getLocality(fileAttributes);

      CellStub cellStub = ServletContextHandlerAttributes.getPinManager(ctx);
      boolean isPinned = isPinned(fileAttributes, cellStub);

      switch (fileLocality) {
        case NEARLINE:
          if (isPinned) {
            response.setQoS(QosManagement.TAPE);
            response.setTargetQoS(QosManagement.DISK_TAPE);
          } else {
            response.setQoS(QosManagement.TAPE);
          }
          break;
        case ONLINE:
          response.setQoS(QosManagement.DISK);
          break;
        case ONLINE_AND_NEARLINE:
          /* When the locality of the file is  NEARLINE_ONLINE and
           * the object is not pinned the result for the user will be displayed as NEARLINE (Tape).
           * else nearline_online (disk+tape)
           */
          if (isPinned) {
            response.setQoS(QosManagement.DISK_TAPE);
          } else {
            response.setQoS(QosManagement.TAPE);
          }
          break;
        default:
          // error cases
          throw new InternalServerErrorException();
      }
    } catch (PermissionDeniedCacheException e) {
      if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) {
        throw new NotAuthorizedException(e);
      } else {
        throw new ForbiddenException(e);
      }
    } catch (FileNotFoundCacheException e) {
      throw new NotFoundException(e);
    } catch (CacheException | InterruptedException e) {
      throw new InternalServerErrorException(e);
    }
    return response;
  }
  /**
   * Starts a object transition to the specified QoS.
   *
   * @param requestPath path to a file
   * @param requestPath requestQuery
   * @return JSONObject current QoS status
   * @throws CacheException
   */
  @POST
  @Path("{requestPath : .*}")
  @Consumes({MediaType.APPLICATION_JSON})
  @Produces(MediaType.APPLICATION_JSON)
  public String changeQosStatus(@PathParam("requestPath") String requestPath, String requestQuery)
      throws CacheException, URISyntaxException, InterruptedException {

    JSONObject jsonResponse = new JSONObject();

    try {
      if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) {
        throw new PermissionDeniedCacheException("Permission denied");
      }

      JSONObject jsonRequest = new JSONObject(requestQuery);
      String update = jsonRequest.get("update").toString();

      FileAttributes fileAttributes = getFileAttributes(requestPath);
      CellStub cellStub = ServletContextHandlerAttributes.getPinManager(ctx);
      FileLocality fileLocality = getLocality(fileAttributes);

      switch (update) {
          // change QoS to "disk+tape"
        case QosManagement.DISK_TAPE:
          makeDiskAndTape(fileLocality, fileAttributes, cellStub);
          break;
          // change QoS to "tape"
        case QosManagement.TAPE:
          makeTape(fileLocality, fileAttributes, cellStub);
          break;
        default:
          // error cases
          throw new BadRequestException();
      }

    } catch (PermissionDeniedCacheException e) {
      if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) {
        throw new NotAuthorizedException(e);
      } else {
        throw new ForbiddenException(e);
      }
    } catch (FileNotFoundCacheException e) {
      throw new NotFoundException(e);
    } catch (CacheException e) {
      throw new InternalServerErrorException(e);
    } catch (JSONException e) {
      throw new BadRequestException(e);
    }

    jsonResponse.put("status", "200");
    jsonResponse.put("message", "Transition was successful");
    return jsonResponse.toString();
  }
  public FileAttributes getFileAttributes(String requestPath) throws CacheException {

    PnfsHandler handler = ServletContextHandlerAttributes.getPnfsHandler(ctx);
    FsPath path;
    if (requestPath == null || requestPath.isEmpty()) {
      path = FsPath.ROOT;
    } else {
      path = FsPath.create(FsPath.ROOT + requestPath);
    }
    Set<FileAttribute> attributes = EnumSet.allOf(FileAttribute.class);

    FileAttributes namespaceAttrributes = handler.getFileAttributes(path, attributes);
    return namespaceAttrributes;
  }
  public FileLocality getLocality(FileAttributes fileAttributes) {

    RemotePoolMonitor remotePoolMonitor = ServletContextHandlerAttributes.getRemotePoolMonitor(ctx);
    return remotePoolMonitor.getFileLocality(fileAttributes, request.getRemoteHost());
  }