package org.dcache.restful.qos; import org.json.JSONArray; import org.json.JSONObject; import javax.ws.rs.Path; import javax.ws.rs.GET; import javax.ws.rs.Produces; import javax.ws.rs.PathParam; import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.NotFoundException; import javax.ws.rs.ForbiddenException; import javax.ws.rs.core.MediaType; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import diskCacheV111.util.CacheException; import diskCacheV111.util.PermissionDeniedCacheException; import org.dcache.auth.Subjects; import org.dcache.restful.util.ServletContextHandlerAttributes; /** * RestFul API for querying and manipulating QoS */ @Path("/qos-management/qos/") public class QosManagement { public static final String DISK = "disk"; public static final String TAPE = "tape"; public static final String DISK_TAPE = "disk+tape"; public static List<String> cdmi_geographic_placement_provided = Arrays.asList("DE"); /** * Get the list of available QoS for file and directory objects corresponding to some specific quality of services supported by dCache back-end. * For example, storage requirements such as flexible allocation of disk or tape storage space. * * @param qosValue specific object (file | directory) * @return JSONObject List of available QoS * @throws CacheException */ @GET @Path("{qosValue : .*}") @Produces(MediaType.APPLICATION_JSON) public String getQosList(@PathParam("qosValue") String qosValue) throws CacheException { JSONObject json = new JSONObject(); try { if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) { throw new PermissionDeniedCacheException("Permission denied"); } // query the lis of available QoS for file objects if ("file".equals(qosValue)) { JSONArray list = new JSONArray(Arrays.asList(DISK, TAPE, DISK_TAPE)); json.put("name", list); } // query the lis of available QoS for directory objects else if ("directory".equals(qosValue.trim())) { JSONArray list = new JSONArray(Arrays.asList(DISK, TAPE)); json.put("name", list); } else { throw new NotFoundException(); } json.put("status", "200"); json.put("message", "successful"); } catch (PermissionDeniedCacheException e) { if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) { throw new NotAuthorizedException(e); } else { throw new ForbiddenException(e); } } catch (CacheException e) { throw new InternalServerErrorException(e); } return json.toString(); } /** * Query data for specified QoS for file objects. * All QoS objects for file objects are specified by "name", "transition" attributes. * If present, the QoS objects should also contain data system metadata values which are described in the following sections. * * @param qosValue specific QoS {disk|tape|disk+tape} * @return BackendCapabilityDisk detailed description of the QoS * @throws CacheException */ @GET @Path("/file/{qosValue : .*}") @Produces(MediaType.APPLICATION_JSON) public BackendCapabilityResponse getQueriedQosForFiles(@PathParam("qosValue") String qosValue) throws CacheException { BackendCapabilityResponse backendCapabilityResponse = new BackendCapabilityResponse(); BackendCapability backendCapability = new BackendCapability(); try { if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) { throw new PermissionDeniedCacheException("Permission denied"); } backendCapabilityResponse.setStatus("200"); backendCapabilityResponse.setMessage("successful"); // Set data and metadata for "DISK" QoS if (DISK.equals(qosValue)) { QoSMetadata qoSMetadata = new QoSMetadata("1", cdmi_geographic_placement_provided, "100"); setBackendCapability(backendCapability, DISK, "", qoSMetadata); } // Set data and metadata for "TAPE" QoS else if (TAPE.equals(qosValue)) { QoSMetadata qoSMetadata = new QoSMetadata("1", cdmi_geographic_placement_provided, "600000"); setBackendCapability(backendCapability, TAPE, DISK_TAPE, qoSMetadata); } // Set data and metadata for "Disk & TAPE" QoS else if (DISK_TAPE.equals(qosValue)) { QoSMetadata qoSMetadata = new QoSMetadata("2", cdmi_geographic_placement_provided, "100"); setBackendCapability(backendCapability, DISK_TAPE, TAPE, qoSMetadata); } // The QoS is not known or supported. else { throw new NotFoundException(); } } catch (PermissionDeniedCacheException e) { if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) { throw new NotAuthorizedException(e); } else { throw new ForbiddenException(e); } } catch (CacheException e) { throw new InternalServerErrorException(e); } backendCapabilityResponse.setBackendCapability(backendCapability); return backendCapabilityResponse; } /** * Query data for specified QoS for directory objects. * * @param qosValue specific QoS {disk|tape} * @return BackendCapabilityDisk detailed description of the QoS * @throws CacheException */ @GET @Path("/directory/{qosValue : .*}") @Produces(MediaType.APPLICATION_JSON) public BackendCapabilityResponse getQueriedQosForDirectories(@PathParam("qosValue") String qosValue) throws CacheException { BackendCapabilityResponse backendCapabilityResponse = new BackendCapabilityResponse(); BackendCapability backendCapability = new BackendCapability(); try { if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) { throw new PermissionDeniedCacheException("Permission denied"); } backendCapabilityResponse.setStatus("200"); backendCapabilityResponse.setMessage("successful"); // Set data and metadata for "DISK" QoS if (DISK.equals(qosValue)) { QoSMetadata qoSMetadata = new QoSMetadata("1", cdmi_geographic_placement_provided, "100"); setBackendCapability(backendCapability, DISK, TAPE, qoSMetadata); } // Set data and metadata for "TAPE" QoS else if (TAPE.equals(qosValue)) { QoSMetadata qoSMetadata = new QoSMetadata("1", cdmi_geographic_placement_provided, "600000"); setBackendCapability(backendCapability, TAPE, DISK, qoSMetadata); } // The QoS is not known or supported. else { throw new NotFoundException(); } } catch (PermissionDeniedCacheException e) { if (Subjects.isNobody(ServletContextHandlerAttributes.getSubject())) { throw new NotAuthorizedException(e); } else { throw new ForbiddenException(e); } } catch (CacheException e) { throw new InternalServerErrorException(e); } backendCapabilityResponse.setBackendCapability(backendCapability); return backendCapabilityResponse; } public void setBackendCapability(BackendCapability backendCapability, String name, String transition, QoSMetadata qoSMetadata) { backendCapability.setName(name); List<String> transitions = new ArrayList<>(); //TODO optimise if (!"".equals(transition)) { transitions.add(transition); } backendCapability.setTransition(transitions); backendCapability.setMetadata(qoSMetadata); } }