diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt index a2591704ca5..958f8ff2a45 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt @@ -10,3 +10,4 @@ HDFS-8641. OzoneHandler : Add Quota Support. (Anu Engineer via Arpit Agarwal) + HDFS-8448. Create REST Interface for Volumes. (Anu Engineer via cnauroth) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/OzoneException.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/OzoneException.java new file mode 100644 index 00000000000..04458c18935 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/exceptions/OzoneException.java @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.web.exceptions; + + +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.ObjectMapper; + +import java.io.IOException; + +/** + * Class the represents various errors returned by the + * Ozone Layer. + */ +public class OzoneException extends Exception { + + @JsonProperty("httpCode") + private long httpCode; + @JsonProperty("shortMessage") + private String shortMessage; + @JsonProperty("resource") + private String resource; + @JsonProperty("message") + private String message; + @JsonProperty("requestID") + private String requestId; + @JsonProperty("hostName") + private String hostID; + + + /** + * Constructor that allows a shortMessage. + * + * @param httpCode Error Code + * @param shortMessage Short Message + */ + public OzoneException(long httpCode, String shortMessage) { + this.shortMessage = shortMessage; + this.httpCode = httpCode; + } + + /** + * Constructor that allows a shortMessage and long message. + * + * @param httpCode Error Code + * @param shortMessage Short Message + * @param message long error message + */ + public OzoneException(long httpCode, String shortMessage, String message) { + this.shortMessage = shortMessage; + this.resource = message; + this.httpCode = httpCode; + } + + /** + * Returns the Resource that was involved in the exception. + * + * @return String + */ + public String getResource() { + return resource; + } + + /** + * Sets Resource. + * + * @param resourceName - Name of the Resource + */ + public void setResource(String resourceName) { + this.resource = resourceName; + } + + /** + * Gets a detailed message for the error. + * + * @return String + */ + public String getMessage() { + return message; + } + + /** + * Sets the error message. + * + * @param longMessage - Long message + */ + public void setMessage(String longMessage) { + this.message = longMessage; + } + + /** + * Returns request Id. + * + * @return String + */ + public String getRequestId() { + return requestId; + } + + /** + * Sets request ID. + * + * @param ozoneRequestId Request ID generated by the Server + */ + public void setRequestId(String ozoneRequestId) { + this.requestId = ozoneRequestId; + } + + /** + * Returns short error string. + * + * @return String + */ + public String getShortMessage() { + return shortMessage; + } + + /** + * Sets short error string. + * + * @param shortError Short Error Code + */ + public void setShortMessage(String shortError) { + this.shortMessage = shortError; + } + + /** + * Returns hostID. + * + * @return String + */ + public String getHostID() { + return hostID; + } + + /** + * Sets host ID. + * + * @param hostName host Name + */ + public void setHostID(String hostName) { + this.hostID = hostName; + } + + /** + * Returns http error code. + * + * @return long + */ + public long getHttpCode() { + return httpCode; + } + + /** + * Sets http status. + * + * @param httpStatus http error code. + */ + public void setHttpCode(long httpStatus) { + this.httpCode = httpStatus; + } + + /** + * Returns a Json String. + * + * @return JSON representation of the Error + */ + public String toJsonString() { + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibilityChecker( + mapper.getSerializationConfig().getDefaultVisibilityChecker() + .withCreatorVisibility(JsonAutoDetect.Visibility.NONE) + .withFieldVisibility(JsonAutoDetect.Visibility.NONE) + .withGetterVisibility(JsonAutoDetect.Visibility.NONE) + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) + .withSetterVisibility(JsonAutoDetect.Visibility.NONE)); + return mapper.writeValueAsString(this); + } catch (IOException ex) { + // TODO : Log this error on server side. + } + // TODO : Replace this with a JSON Object -- That represents this error. + return "500 Internal Server Error"; + } + + /** + * Parses an Exception record. + * + * @param jsonString - Exception in Json format. + * + * @return OzoneException Object + * + * @throws IOException + */ + public static OzoneException parse(String jsonString) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(jsonString, OzoneException.class); + } +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/UserArgs.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/UserArgs.java new file mode 100644 index 00000000000..b80de3c2232 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/UserArgs.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.ozone.web.handlers; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Request; +import javax.ws.rs.core.UriInfo; + +/** + * UserArgs is used to package caller info + * and pass it down to file system. + */ +public class UserArgs { + private String userName; + private final long requestID; + private final String hostName; + private final UriInfo uri; + private final Request request; + private final HttpHeaders headers; + + + /** + * Constructs user args. + * + * @param userName - User name + * @param requestID _ Request ID + * @param hostName - Host Name + * @param req - Request + * @param info - Uri Info + * @param httpHeaders - http headers + */ + public UserArgs(String userName, long requestID, String hostName, Request req, + UriInfo info, HttpHeaders httpHeaders) { + this.hostName = hostName; + this.userName = userName; + this.requestID = requestID; + this.uri = info; + this.request = req; + this.headers = httpHeaders; + } + + /** + * Returns hostname. + * + * @return String + */ + public String getHostName() { + return hostName; + } + + /** + * Returns RequestID. + * + * @return Long + */ + public long getRequestID() { + return requestID; + } + + /** + * Returns User Name. + * + * @return String + */ + public String getUserName() { + return userName; + } + + /** + * Sets the user name. + * + * @param userName Name of the user + */ + public void setUserName(String userName) { + this.userName = userName; + } + + /** + * Returns the resource Name. + * + * @return String Resource. + */ + public String getResourceName() { + return getUserName(); + } + + /** + * Returns Http Headers for this call. + * + * @return httpHeaders + */ + public HttpHeaders getHeaders() { + return headers; + } + + /** + * Returns Request Object. + * + * @return Request + */ + public Request getRequest() { + return request; + } + + /** + * Returns UriInfo. + * + * @return UriInfo + */ + public UriInfo getUri() { + return uri; + } +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/VolumeArgs.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/VolumeArgs.java new file mode 100644 index 00000000000..5bb62551b57 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/handlers/VolumeArgs.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.web.handlers; + +import org.apache.hadoop.ozone.web.request.OzoneQuota; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Request; +import javax.ws.rs.core.UriInfo; + +/** + * VolumeArgs is used to package all volume + * related arguments in the call to underlying + * file system. + */ +public class VolumeArgs extends UserArgs { + private String adminName; + private final String volumeName; + private OzoneQuota quota; + + /** + * Returns Quota Information. + * + * @return Quota + */ + public OzoneQuota getQuota() { + return quota; + } + + /** + * Returns volume name. + * + * @return String + */ + public String getVolumeName() { + return volumeName; + } + + /** + * Constructs volume Args. + * + * @param userName - User name + * @param volumeName - volume Name + * @param requestID _ Request ID + * @param hostName - Host Name + * @param request - Http Request + * @param info - URI info + * @param headers - http headers + */ + public VolumeArgs(String userName, String volumeName, long requestID, + String hostName, Request request, UriInfo info, + HttpHeaders headers) { + super(userName, requestID, hostName, request, info, headers); + this.volumeName = volumeName; + } + + /** + * Sets Quota information. + * + * @param quota - Quota Sting + * @throws IllegalArgumentException + */ + public void setQuota(String quota) throws IllegalArgumentException { + this.quota = OzoneQuota.parseQuota(quota); + } + + /** + * Sets quota information. + * + * @param quota - OzoneQuota + */ + public void setQuota(OzoneQuota quota) { + this.quota = quota; + } + + /** + * Gets admin Name. + * + * @return - Admin Name + */ + public String getAdminName() { + return adminName; + } + + /** + * Sets Admin Name. + * + * @param adminName - Admin Name + */ + public void setAdminName(String adminName) { + this.adminName = adminName; + } + + /** + * Returns UserName/VolumeName. + * + * @return String + */ + @Override + public String getResourceName() { + return super.getResourceName() + "/" + getVolumeName(); + } +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java index ac3320884c3..339b008777d 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/headers/Header.java @@ -27,6 +27,10 @@ public final class Header { public static final String OZONE_QUOTA_GB = "GB"; public static final String OZONE_QUOTA_TB = "TB"; public static final String OZONE_QUOTA_REMOVE = "remove"; + public static final String OZONE_QUOTA_UNDEFINED = "undefined"; + + public static final String OZONE_LIST_QUERY_BUCKET ="bucket"; + private Header() { // Never constructed. } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java new file mode 100644 index 00000000000..2088409148f --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/StorageHandler.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.web.interfaces; + +import org.apache.hadoop.ozone.web.exceptions.OzoneException; +import org.apache.hadoop.ozone.web.handlers.UserArgs; +import org.apache.hadoop.ozone.web.handlers.VolumeArgs; +import org.apache.hadoop.ozone.web.response.ListVolumes; +import org.apache.hadoop.ozone.web.response.VolumeInfo; + +import java.io.IOException; + +/** + * Storage handler Interface is the Interface between + * REST protocol and file system. + * + * We will have two default implementations of this interface. + * One for the local file system that is handy while testing + * and another which will point to the HDFS backend. + */ +public interface StorageHandler { + + /** + * Creates a Storage Volume. + * + * @param args - Volume Name + * + * @throws IOException + * @throws OzoneException + */ + void createVolume(VolumeArgs args) throws IOException, OzoneException; + + + /** + * setVolumeOwner - sets the owner of the volume. + * + * @param args owner info is present in the args + * + * @throws IOException + * @throws OzoneException + */ + void setVolumeOwner(VolumeArgs args) throws IOException, OzoneException; + + + /** + * Set Volume Quota. + * + * @param args - Has Quota info + * @param remove - true if the request is to remove the quota + * + * @throws IOException + * @throws OzoneException + */ + void setVolumeQuota(VolumeArgs args, boolean remove) + throws IOException, OzoneException; + + /** + * Checks if a Volume exists and the user specified has access to the + * Volume. + * + * @param args - Volume Args + * + * @return - Boolean - True if the user can modify the volume. + * This is possible for owners of the volume and admin users + * + * @throws IOException + * @throws OzoneException + */ + boolean checkVolumeAccess(VolumeArgs args) throws IOException, OzoneException; + + + /** + * Returns the List of Volumes owned by the specific user. + * + * @param args - UserArgs + * + * @return - List of Volumes + * + * @throws IOException + * @throws OzoneException + */ + ListVolumes listVolumes(UserArgs args) throws IOException, OzoneException; + + /** + * Deletes an Empty Volume. + * + * @param args - Volume Args + * + * @throws IOException + * @throws OzoneException + */ + void deleteVolume(VolumeArgs args) throws IOException, OzoneException; + + + /** + * Returns Info about the specified Volume. + * + * @param args - Volume Args + * + * @return VolumeInfo + * + * @throws IOException + * @throws OzoneException + */ + VolumeInfo getVolumeInfo(VolumeArgs args) throws IOException, OzoneException; +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Volume.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Volume.java new file mode 100644 index 00000000000..6ad742acb9d --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/interfaces/Volume.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.web.interfaces; + +import org.apache.hadoop.ozone.web.exceptions.OzoneException; +import org.apache.hadoop.ozone.web.headers.Header; + +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Request; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +/** + * Volume Interface acts as the HTTP entry point for + * volume related functionality. + */ +@Path("/{volume}") +public interface Volume { + + /** + * Creates a Volume owned by the user. + * + * Params : + * Quota - Specifies the Maximum usable size by the user + * the valid parameters for quota are () | remove. + * For example 10GB or "remove". + * + * @param volume Volume Name, this has to be unique at Ozone Level + * @param quota Quota for this Storage Volume - () | remove + * @param req - Request Object - Request Object + * @param uriInfo - Http UriInfo + * @param headers Http Headers HttpHeaders + * + * @return Response + * + * @throws OzoneException + */ + + @POST + Response createVolume(@PathParam("volume") String volume, + @DefaultValue(Header.OZONE_QUOTA_UNDEFINED) + @QueryParam("quota") String quota, + @Context Request req, + @Context UriInfo uriInfo, + @Context HttpHeaders headers) + throws OzoneException; + + + /** + * Updates a Volume owned by the user. + * + * Params : + * Owner - Specifies the name of the owner + * Quota - Specifies the Maximum usable size by the user + * the valid parameters for quota are () | remove. + * For example 10GB or "remove". + * + * @param volume Volume Name, this has to be unique at Ozone Level + * @param quota Quota for this Storage Volume - () | remove + * @param req - Request Object - Request Object + * @param headers Http Headers HttpHeaders + * + * @return Response + * + * @throws OzoneException + */ + @PUT + Response updateVolume(@PathParam("volume") String volume, + @DefaultValue(Header.OZONE_QUOTA_UNDEFINED) + @QueryParam("quota") String quota, + @Context Request req, + @Context UriInfo uriInfo, + @Context HttpHeaders headers) + throws OzoneException; + + + /** + * Deletes a Volume if it is empty. + * + * @param volume Storage Volume Name + * + * @return Response Response + * + * @throws OzoneException + */ + @DELETE + Response deleteVolume(@PathParam("volume") String volume, + @Context Request req, + @Context UriInfo uriInfo, + @Context HttpHeaders headers) + throws OzoneException; + + /** + * Returns Volume info. This API can be invoked either + * by admin or the owner + * + * @param volume - Storage Volume Name + * @param req - Http Req + * @param headers - Http headers + * + * @return - Response + * + * @throws OzoneException + */ + @GET + Response getVolumeInfo(@PathParam("volume") String volume, + @DefaultValue(Header.OZONE_LIST_QUERY_BUCKET) + @QueryParam("info") String info, + @Context Request req, + @Context UriInfo uriInfo, + @Context HttpHeaders headers) + throws OzoneException; + +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/ListVolumes.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/ListVolumes.java new file mode 100644 index 00000000000..9c2ec9fd220 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/ListVolumes.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.ozone.web.response; + +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonMethod; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.ObjectWriter; +import org.codehaus.jackson.map.annotate.JsonFilter; +import org.codehaus.jackson.map.ser.FilterProvider; +import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter; +import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider; + +import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * List Volume Class is the class that is returned in JSON format to + * users when they call ListVolumes. + */ +public class ListVolumes { + private List volumes; + + static final String VOLUME_LIST = "VOLUME_LIST_FILTER"; + + /** + * Used for json filtering. + */ + @JsonFilter(VOLUME_LIST) + class MixIn { + } + + /** + * Constructs ListVolume objects. + */ + public ListVolumes() { + this.volumes = new LinkedList(); + } + + /** + * Gets the list of volumes. + * + * @return List of VolumeInfo Objects + */ + public List getVolumes() { + return volumes; + } + + + /** + * Sets volume info. + * + * @param volumes - List of Volumes + */ + public void setVolumes(List volumes) { + this.volumes = volumes; + } + + /** + * Returns a JSON string of this object. + * After stripping out bytesUsed and bucketCount + * + * @return String + */ + public String toJsonString() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + String[] ignorableFieldNames = {"bytesUsed", "bucketCount"}; + + FilterProvider filters = new SimpleFilterProvider() + .addFilter(VOLUME_LIST, + SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)); + + mapper.setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY); + mapper.getSerializationConfig() + .addMixInAnnotations(Object.class, MixIn.class); + ObjectWriter writer = mapper.writer(filters); + + return writer.writeValueAsString(this); + } + + /** + * When we serialize a volumeInfo to our database + * we will use all fields. However the toJsonString + * will strip out bytesUsed and bucketCount from the + * volume Info + * + * @return Json String + * + * @throws IOException + */ + public String toDBString() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(this); + } + + /** + * Parses a String to return ListVolumes object. + * + * @param data - Json String + * + * @return - ListVolumes + * + * @throws IOException + */ + public static ListVolumes parse(String data) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(data, ListVolumes.class); + } + + /** + * Adds a new volume info to the List. + * + * @param info - VolumeInfo + */ + public void addVolume(VolumeInfo info) { + this.volumes.add(info); + } + + /** + * Sorts the volume names based on volume name. + * This is useful when we return the list of volume names + */ + public void sort() { + Collections.sort(volumes); + } +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/VolumeInfo.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/VolumeInfo.java new file mode 100644 index 00000000000..e3ef53371db --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/VolumeInfo.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.web.response; + + +import org.apache.hadoop.ozone.web.request.OzoneQuota; +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonMethod; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.ObjectWriter; +import org.codehaus.jackson.map.annotate.JsonFilter; +import org.codehaus.jackson.map.ser.FilterProvider; +import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter; +import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider; + +import java.io.IOException; + +/** + * VolumeInfo Class is the Java class that represents + * Json when VolumeInfo Call is made. + */ +public class VolumeInfo implements Comparable { + + static final String VOLUME_INFO = "VOLUME_INFO_FILTER"; + + /** + * Custom Json Filter Class. + */ + @JsonFilter(VOLUME_INFO) + class MixIn { + } + private VolumeOwner owner; + private OzoneQuota quota; + private String volumeName; + private String createdOn; + private String createdBy; + + private long bytesUsed; + private long bucketCount; + + + /** + * Constructor for VolumeInfo. + * + * @param volumeName - Name of the Volume + * @param createdOn _ Date String + * @param createdBy - Person who created it + */ + public VolumeInfo(String volumeName, String createdOn, String createdBy) { + this.createdOn = createdOn; + this.volumeName = volumeName; + this.createdBy = createdBy; + } + + /** + * Constructor for VolumeInfo. + */ + public VolumeInfo() { + } + + /** + * Returns the name of the person who created this volume. + * + * @return Name of Admin who created this + */ + public String getCreatedBy() { + return createdBy; + } + + /** + * Sets the user name of the person who created this volume. + * + * @param createdBy - UserName + */ + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + /** + * Gets the date on which this volume was created. + * + * @return - Date String + */ + public String getCreatedOn() { + return createdOn; + } + + /** + * Sets the date string. + * + * @param createdOn - Date String + */ + public void setCreatedOn(String createdOn) { + this.createdOn = createdOn; + } + + /** + * Returns the owner info. + * + * @return - OwnerInfo + */ + public VolumeOwner getOwner() { + return owner; + } + + /** + * Sets the owner. + * + * @param owner - OwnerInfo + */ + public void setOwner(VolumeOwner owner) { + this.owner = owner; + } + + /** + * Returns the quota information on a volume. + * + * @return Quota + */ + public OzoneQuota getQuota() { + return quota; + } + + /** + * Sets the quota info. + * + * @param quota - Quota Info + */ + public void setQuota(OzoneQuota quota) { + this.quota = quota; + } + + /** + * gets the volume name. + * + * @return - Volume Name + */ + public String getVolumeName() { + return volumeName; + } + + /** + * Sets the volume name. + * + * @param volumeName - Volume Name + */ + public void setVolumeName(String volumeName) { + this.volumeName = volumeName; + } + + /** + * Returns a JSON string of this object. + * After stripping out bytesUsed and bucketCount + * + * @return String - json string + * @throws IOException + */ + public String toJsonString() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + String[] ignorableFieldNames = {"bytesUsed", "bucketCount"}; + + FilterProvider filters = new SimpleFilterProvider() + .addFilter(VOLUME_INFO, SimpleBeanPropertyFilter + .serializeAllExcept(ignorableFieldNames)); + + mapper.setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY); + mapper.getSerializationConfig() + .addMixInAnnotations(Object.class, MixIn.class); + ObjectWriter writer = mapper.writer(filters); + + return writer.writeValueAsString(this); + } + + /** + * When we serialize a volumeInfo to our database + * we will use all fields. However the toJsonString + * will strip out bytesUsed and bucketCount from the + * volume Info + * + * @return Json String + * + * @throws IOException + */ + public String toDBString() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(this); + } + + + /** + * Comparable Interface. + * @param o VolumeInfo Object. + * @return Result of comparison + */ + @Override + public int compareTo(VolumeInfo o) { + return this.volumeName.compareTo(o.getVolumeName()); + } + + /** + * Gets the number of bytesUsed by this volume. + * + * @return long - Bytes used + */ + public long getBytesUsed() { + return bytesUsed; + } + + /** + * Sets number of bytesUsed by this volume. + * + * @param bytesUsed - Number of bytesUsed + */ + public void setBytesUsed(long bytesUsed) { + this.bytesUsed = bytesUsed; + } + + /** + * Returns VolumeInfo class from json string. + * + * @param data - Json String + * + * @return VolumeInfo + * + * @throws IOException + */ + public static VolumeInfo parse(String data) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(data, VolumeInfo.class); + } + + /** + * Indicates whether some other object is "equal to" this one. + * + * @param obj the reference object with which to compare. + * + * @return {@code true} if this object is the same as the obj + * argument; {@code false} otherwise. + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + VolumeInfo otherInfo = (VolumeInfo) obj; + return otherInfo.getVolumeName().equals(this.getVolumeName()); + } + + /** + * Returns a hash code value for the object. This method is + * supported for the benefit of hash tables such as those provided by + * HashMap. + * @return a hash code value for this object. + * + * @see Object#equals(Object) + * @see System#identityHashCode + */ + @Override + public int hashCode() { + return getVolumeName().hashCode(); + } + + /** + * Total number of buckets under this volume. + * + * @return - bucketCount + */ + public long getBucketCount() { + return bucketCount; + } + + /** + * Sets the buckets count. + * + * @param bucketCount - Bucket Count + */ + public void setBucketCount(long bucketCount) { + this.bucketCount = bucketCount; + } +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/VolumeOwner.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/VolumeOwner.java new file mode 100644 index 00000000000..02c4d048897 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/response/VolumeOwner.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.web.response; + + +import org.codehaus.jackson.map.annotate.JsonSerialize; + +/** + * Volume Owner represents the owner of a volume. + * + * This is a class instead of a string since we might need to extend this class + * to support other forms of authentication. + */ +public class VolumeOwner { + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + private String name; + + /** + * Constructor for VolumeOwner. + * + * @param name - name of the User + */ + public VolumeOwner(String name) { + this.name = name; + } + + /** + * Constructs Volume Owner. + */ + public VolumeOwner() { + name = null; + } + + /** + * Returns the user name. + * + * @return Name + */ + public String getName() { + return name; + } + +}