HDFS-9916. OzoneHandler : Add Key handler. Contributed by Anu Engineer.
This commit is contained in:
parent
93201330b8
commit
a9879798a6
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Class that packages all key Arguments.
|
||||
*/
|
||||
public class KeyArgs extends BucketArgs {
|
||||
private String key;
|
||||
private boolean delete;
|
||||
private String hash;
|
||||
private long size;
|
||||
|
||||
/**
|
||||
* Constructor for Key Args.
|
||||
*
|
||||
* @param volumeName - Volume Name
|
||||
* @param bucketName - Bucket Name
|
||||
* @param objectName - Key
|
||||
*/
|
||||
public KeyArgs(String volumeName, String bucketName,
|
||||
String objectName, UserArgs args) {
|
||||
super(volumeName, bucketName, args);
|
||||
this.key = objectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Key Name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this request is for a Delete key.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isDelete() {
|
||||
return delete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key request as a Delete Request.
|
||||
*
|
||||
* @param delete bool, indicating if this is a delete request
|
||||
*/
|
||||
public void setDelete(boolean delete) {
|
||||
this.delete = delete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed File hash.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash String.
|
||||
*
|
||||
* @param hash String
|
||||
*/
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file size.
|
||||
*
|
||||
* @return long - file size
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Size.
|
||||
*
|
||||
* @param size Size of the file
|
||||
*/
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the resource.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getResourceName() {
|
||||
return super.getResourceName() + "/" + getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parent name of this resource.
|
||||
*
|
||||
* @return String.
|
||||
*/
|
||||
@Override
|
||||
public String getParentName() {
|
||||
return super.getResourceName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* 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.commons.codec.binary.Hex;
|
||||
import org.apache.hadoop.hdfs.server.datanode.fsdataset.LengthInputStream;
|
||||
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||
import org.apache.hadoop.ozone.web.interfaces.Keys;
|
||||
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
||||
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Request;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import static java.net.HttpURLConnection.HTTP_CREATED;
|
||||
import static java.net.HttpURLConnection.HTTP_OK;
|
||||
|
||||
/**
|
||||
* KeyHandler deals with basic Key Operations.
|
||||
*/
|
||||
public class KeyHandler implements Keys {
|
||||
|
||||
/**
|
||||
* Gets the Key if it exists.
|
||||
*
|
||||
* @param volume Storage Volume
|
||||
* @param bucket Name of the bucket
|
||||
* @param req Request
|
||||
* @param info - UriInfo
|
||||
* @param headers Http Header
|
||||
* @return Response
|
||||
* @throws OzoneException
|
||||
*/
|
||||
@Override
|
||||
public Response getKey(String volume, String bucket, String key,
|
||||
Request req, UriInfo info, HttpHeaders headers)
|
||||
throws OzoneException {
|
||||
return new KeyProcessTemplate() {
|
||||
/**
|
||||
* Abstract function that gets implemented in the KeyHandler functions.
|
||||
* This function will just deal with the core file system related logic
|
||||
* and will rely on handleCall function for repetitive error checks
|
||||
*
|
||||
* @param args - parsed bucket args, name, userName, ACLs etc
|
||||
* @param input - The body as an Input Stream
|
||||
* @param request - Http request
|
||||
* @param headers - Parsed http Headers.
|
||||
* @param info - UriInfo
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws IOException - From the file system operations
|
||||
*/
|
||||
@Override
|
||||
public Response doProcess(KeyArgs args, InputStream input,
|
||||
Request request, HttpHeaders headers,
|
||||
UriInfo info)
|
||||
throws IOException, OzoneException, NoSuchAlgorithmException {
|
||||
StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
|
||||
LengthInputStream stream = fs.newKeyReader(args);
|
||||
return OzoneUtils.getResponse(args, HTTP_OK, stream);
|
||||
}
|
||||
}.handleCall(volume, bucket, key, req, headers, info, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a key to an existing bucket. If the object already exists this call
|
||||
* will overwrite or add with new version number if the bucket versioning is
|
||||
* turned on.
|
||||
*
|
||||
* @param volume Storage Volume Name
|
||||
* @param bucket Name of the bucket
|
||||
* @param keys Name of the Object
|
||||
* @param is InputStream or File Data
|
||||
* @param req Request
|
||||
* @param info - UriInfo
|
||||
* @param headers http headers
|
||||
* @return Response
|
||||
* @throws OzoneException
|
||||
*/
|
||||
@Override
|
||||
public Response putKey(String volume, String bucket, String keys,
|
||||
InputStream is, Request req, UriInfo info,
|
||||
HttpHeaders headers) throws OzoneException {
|
||||
|
||||
return new KeyProcessTemplate() {
|
||||
/**
|
||||
* Abstract function that gets implemented in the KeyHandler functions.
|
||||
* This function will just deal with the core file system related logic
|
||||
* and will rely on handleCall function for repetitive error checks
|
||||
*
|
||||
* @param args - parsed bucket args, name, userName, ACLs etc
|
||||
* @param input - The body as an Input Stream
|
||||
* @param request - Http request
|
||||
* @param headers - Parsed http Headers.
|
||||
* @param info - UriInfo
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws IOException - From the file system operations
|
||||
*/
|
||||
@Override
|
||||
public Response doProcess(KeyArgs args, InputStream input,
|
||||
Request request, HttpHeaders headers,
|
||||
UriInfo info)
|
||||
throws IOException, OzoneException, NoSuchAlgorithmException {
|
||||
final int eof = -1;
|
||||
StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
|
||||
|
||||
byte[] buffer = new byte[4 * 1024];
|
||||
String contentLenString = getContentLength(headers, args);
|
||||
String newLen = contentLenString.replaceAll("\"", "");
|
||||
int contentLen = Integer.parseInt(newLen);
|
||||
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
int bytesRead = 0;
|
||||
int len = 0;
|
||||
OutputStream stream = fs.newKeyWriter(args);
|
||||
while ((bytesRead < contentLen) && (len != eof)) {
|
||||
int readSize =
|
||||
(contentLen - bytesRead > buffer.length) ? buffer.length :
|
||||
contentLen - bytesRead;
|
||||
len = input.read(buffer, 0, readSize);
|
||||
if (len != eof) {
|
||||
stream.write(buffer, 0, len);
|
||||
md5.update(buffer, 0, len);
|
||||
bytesRead += len;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
checkFileLengthMatch(args, fs, contentLen, bytesRead);
|
||||
|
||||
String hashString = Hex.encodeHexString(md5.digest());
|
||||
// TODO : Enable hash value checking.
|
||||
// String contentHash = getContentMD5(headers, args);
|
||||
// checkFileHashMatch(args, hashString, fs, contentHash);
|
||||
args.setHash(hashString);
|
||||
args.setSize(bytesRead);
|
||||
fs.commitKey(args, stream);
|
||||
return OzoneUtils.getResponse(args, HTTP_CREATED, "");
|
||||
}
|
||||
}.handleCall(volume, bucket, keys, req, headers, info, is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing key.
|
||||
*
|
||||
* @param volume Storage Volume Name
|
||||
* @param bucket Name of the bucket
|
||||
* @param keys Name of the Object
|
||||
* @param req http Request
|
||||
* @param info - UriInfo
|
||||
* @param headers HttpHeaders
|
||||
* @return Response
|
||||
* @throws OzoneException
|
||||
*/
|
||||
@Override
|
||||
public Response deleteKey(String volume, String bucket, String keys,
|
||||
Request req, UriInfo info, HttpHeaders headers)
|
||||
throws OzoneException {
|
||||
return new KeyProcessTemplate() {
|
||||
/**
|
||||
* Abstract function that gets implemented in the KeyHandler functions.
|
||||
* This function will just deal with the core file system related logic
|
||||
* and will rely on handleCall function for repetitive error checks
|
||||
*
|
||||
* @param args - parsed bucket args, name, userName, ACLs etc
|
||||
* @param input - The body as an Input Stream
|
||||
* @param request - Http request
|
||||
* @param headers - Parsed http Headers.
|
||||
* @param info - UriInfo
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws IOException - From the file system operations
|
||||
*/
|
||||
@Override
|
||||
public Response doProcess(KeyArgs args, InputStream input,
|
||||
Request request, HttpHeaders headers,
|
||||
UriInfo info)
|
||||
throws IOException, OzoneException, NoSuchAlgorithmException {
|
||||
StorageHandler fs = StorageHandlerBuilder.getStorageHandler();
|
||||
fs.deleteKey(args);
|
||||
return OzoneUtils.getResponse(args, HTTP_OK, "");
|
||||
}
|
||||
}.handleCall(volume, bucket, keys, req, headers, info, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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.commons.codec.binary.Base64;
|
||||
import org.apache.hadoop.ozone.web.exceptions.ErrorTable;
|
||||
import org.apache.hadoop.ozone.web.exceptions.OzoneException;
|
||||
import org.apache.hadoop.ozone.web.headers.Header;
|
||||
import org.apache.hadoop.ozone.web.interfaces.StorageHandler;
|
||||
import org.apache.hadoop.ozone.web.interfaces.UserAuth;
|
||||
import org.apache.hadoop.ozone.web.utils.OzoneUtils;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Request;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.hadoop.ozone.web.exceptions.ErrorTable.BAD_DIGEST;
|
||||
import static org.apache.hadoop.ozone.web.exceptions.ErrorTable.INCOMPLETE_BODY;
|
||||
import static org.apache.hadoop.ozone.web.exceptions.ErrorTable.INVALID_BUCKET_NAME;
|
||||
import static org.apache.hadoop.ozone.web.exceptions.ErrorTable.INVALID_REQUEST;
|
||||
import static org.apache.hadoop.ozone.web.exceptions.ErrorTable.SERVER_ERROR;
|
||||
import static org.apache.hadoop.ozone.web.exceptions.ErrorTable.newError;
|
||||
|
||||
/**
|
||||
* This class abstracts way the repetitive tasks in Key handling code.
|
||||
*/
|
||||
public abstract class KeyProcessTemplate {
|
||||
|
||||
/**
|
||||
* This function serves as the common error handling function for all Key
|
||||
* related operations.
|
||||
*
|
||||
* @param bucket bucket Name
|
||||
* @param key the object name
|
||||
* @param headers Http headers
|
||||
* @param is Input XML stream
|
||||
* @throws OzoneException
|
||||
*/
|
||||
public Response handleCall(String volume, String bucket, String key,
|
||||
Request request, HttpHeaders headers, UriInfo info,
|
||||
InputStream is) throws OzoneException {
|
||||
|
||||
String reqID = OzoneUtils.getRequestID();
|
||||
String hostName = OzoneUtils.getHostName();
|
||||
UserArgs userArgs = null;
|
||||
try {
|
||||
OzoneUtils.validate(request, headers, reqID, bucket, hostName);
|
||||
OzoneUtils.verifyBucketName(bucket);
|
||||
|
||||
UserAuth auth = UserHandlerBuilder.getAuthHandler();
|
||||
userArgs = new UserArgs(reqID, hostName, request, info, headers);
|
||||
userArgs.setUserName(auth.getUser(userArgs));
|
||||
|
||||
KeyArgs args = new KeyArgs(volume, bucket, key, userArgs);
|
||||
return doProcess(args, is, request, headers, info);
|
||||
} catch (IllegalArgumentException argExp) {
|
||||
OzoneException ex =
|
||||
newError(INVALID_BUCKET_NAME, reqID, bucket, hostName);
|
||||
ex.setMessage(argExp.getMessage());
|
||||
throw ex;
|
||||
} catch (IOException fsExp) {
|
||||
// TODO : Handle errors from the FileSystem , let us map to server error
|
||||
// for now.
|
||||
throw ErrorTable.newError(ErrorTable.SERVER_ERROR, userArgs, fsExp);
|
||||
} catch (NoSuchAlgorithmException algoEx) {
|
||||
OzoneException ex =
|
||||
ErrorTable.newError(SERVER_ERROR, reqID, key, hostName);
|
||||
ex.setMessage(algoEx.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract function that gets implemented in the KeyHandler functions. This
|
||||
* function will just deal with the core file system related logic and will
|
||||
* rely on handleCall function for repetitive error checks
|
||||
*
|
||||
* @param args - parsed bucket args, name, userName, ACLs etc
|
||||
* @param input - The body as an Input Stream
|
||||
* @param request - Http request
|
||||
* @param headers - Parsed http Headers.
|
||||
* @param info - UriInfo
|
||||
* @return Response
|
||||
* @throws IOException - From the file system operations
|
||||
*/
|
||||
public abstract Response doProcess(KeyArgs args, InputStream input,
|
||||
Request request, HttpHeaders headers,
|
||||
UriInfo info)
|
||||
throws IOException, OzoneException, NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* checks if the File Content-MD5 we wrote matches the hash we computed from
|
||||
* the stream. if it does match we delete the file and throw and exception to
|
||||
* let the user know that we have a hash mismatch
|
||||
*
|
||||
* @param args Object Args
|
||||
* @param computedString MD5 hash value
|
||||
* @param fs Pointer to File System so we can delete the file
|
||||
* @param contentHash User Specified hash string
|
||||
* @throws IOException
|
||||
* @throws OzoneException
|
||||
*/
|
||||
public void checkFileHashMatch(KeyArgs args, String computedString,
|
||||
StorageHandler fs, String contentHash)
|
||||
throws IOException, OzoneException {
|
||||
if (contentHash != null) {
|
||||
String contentString =
|
||||
new String(Base64.decodeBase64(contentHash), OzoneUtils.ENCODING)
|
||||
.trim();
|
||||
|
||||
if (!contentString.equals(computedString)) {
|
||||
fs.deleteKey(args);
|
||||
OzoneException ex = ErrorTable.newError(BAD_DIGEST, args.getRequestID(),
|
||||
args.getKeyName(), args.getHostName());
|
||||
ex.setMessage(String.format("MD5 Digest mismatch. Expected %s Found " +
|
||||
"%s", contentString, computedString));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the content-length matches the actual stream length. if we find a
|
||||
* mismatch we will delete the file and throw an exception to let the user
|
||||
* know that length mismatch detected
|
||||
*
|
||||
* @param args Object Args
|
||||
* @param fs Pointer to File System Object, to delete the file that we
|
||||
* wrote
|
||||
* @param contentLen Http Content-Length Header
|
||||
* @param bytesRead Actual Bytes we read from the stream
|
||||
* @throws IOException
|
||||
* @throws OzoneException
|
||||
*/
|
||||
public void checkFileLengthMatch(KeyArgs args, StorageHandler fs,
|
||||
int contentLen, int bytesRead)
|
||||
throws IOException, OzoneException {
|
||||
if (bytesRead != contentLen) {
|
||||
fs.deleteKey(args);
|
||||
OzoneException ex = ErrorTable.newError(INCOMPLETE_BODY,
|
||||
args.getRequestID(), args.getKeyName(), args.getHostName());
|
||||
ex.setMessage(String.format("Body length mismatch. Expected length : %d" +
|
||||
" Found %d", contentLen, bytesRead));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Content Length header value if available.
|
||||
*
|
||||
* @param headers - Http Headers
|
||||
* @return - String or null
|
||||
*/
|
||||
public String getContentLength(HttpHeaders headers, KeyArgs args)
|
||||
throws OzoneException {
|
||||
List<String> contentLengthList =
|
||||
headers.getRequestHeader(HttpHeaders.CONTENT_LENGTH);
|
||||
if ((contentLengthList != null) && (contentLengthList.size() > 0)) {
|
||||
return contentLengthList.get(0);
|
||||
}
|
||||
|
||||
OzoneException ex = ErrorTable.newError(INVALID_REQUEST, args);
|
||||
ex.setMessage("Content-Length is a required header for putting a key.");
|
||||
throw ex;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Content MD5 value if available.
|
||||
*
|
||||
* @param headers - Http Headers
|
||||
* @return - String or null
|
||||
*/
|
||||
public String getContentMD5(HttpHeaders headers, KeyArgs args) {
|
||||
List<String> contentLengthList =
|
||||
headers.getRequestHeader(Header.CONTENT_MD5);
|
||||
if ((contentLengthList != null) && (contentLengthList.size() > 0)) {
|
||||
return contentLengthList.get(0);
|
||||
}
|
||||
// TODO : Should we make this compulsory ?
|
||||
// OzoneException ex = ErrorTable.newError(ErrorTable.invalidRequest, args);
|
||||
// ex.setMessage("Content-MD5 is a required header for putting a key");
|
||||
// throw ex;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Supports listing keys with pagination.
|
||||
*/
|
||||
public class ListArgs extends BucketArgs {
|
||||
private String startPage;
|
||||
private String prefix;
|
||||
private int maxKeys;
|
||||
|
||||
/**
|
||||
* Constructor for ListArgs.
|
||||
*
|
||||
* @param args - BucketArgs
|
||||
* @param prefix Prefix to start Query from
|
||||
* @param maxKeys Max result set
|
||||
* @param startPage - Page token
|
||||
*/
|
||||
public ListArgs(BucketArgs args, String prefix, int maxKeys,
|
||||
String startPage) {
|
||||
super(args);
|
||||
setPrefix(prefix);
|
||||
setMaxKeys(maxKeys);
|
||||
setStartPage(startPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Constructor for ListArgs.
|
||||
*
|
||||
* @param args - List Args
|
||||
*/
|
||||
public ListArgs(ListArgs args) {
|
||||
this(args, args.getPrefix(), args.getMaxKeys(), args.getStartPage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns page token.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getStartPage() {
|
||||
return startPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets page token.
|
||||
*
|
||||
* @param startPage - Page token
|
||||
*/
|
||||
public void setStartPage(String startPage) {
|
||||
this.startPage = startPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets max keys.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int getMaxKeys() {
|
||||
return maxKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets max keys.
|
||||
*
|
||||
* @param maxKeys - Maximum keys to return
|
||||
*/
|
||||
public void setMaxKeys(int maxKeys) {
|
||||
this.maxKeys = maxKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets prefix.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets prefix.
|
||||
*
|
||||
* @param prefix - The prefix that we are looking for
|
||||
*/
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This in the accounting interface, Ozone Rest interface will call into this
|
||||
* interface whenever a put or delete key happens.
|
||||
* <p>
|
||||
* TODO : Technically we need to report bucket creation and deletion too
|
||||
* since the bucket names and metadata consume storage.
|
||||
* <p>
|
||||
* TODO : We should separate out reporting metadata & data --
|
||||
* <p>
|
||||
* In some cases end users will only want to account for the data they are
|
||||
* storing since metadata is mostly a cost of business.
|
||||
*/
|
||||
public interface Accounting {
|
||||
/**
|
||||
* This call is made when ever a put key call is made.
|
||||
* <p>
|
||||
* In case of a Put which causes a over write of a key accounting system will
|
||||
* see two calls, a removeByte call followed by an addByte call.
|
||||
*
|
||||
* @param owner - Volume Owner
|
||||
* @param volume - Name of the Volume
|
||||
* @param bucket - Name of the bucket
|
||||
* @param bytes - How many bytes are put
|
||||
*/
|
||||
void addBytes(String owner, String volume, String bucket, int bytes);
|
||||
|
||||
/**
|
||||
* This call is made whenever a delete call is made.
|
||||
*
|
||||
* @param owner - Volume Owner
|
||||
* @param volume - Name of the Volume
|
||||
* @param bucket - Name of the bucket
|
||||
* @param bytes - How many bytes are deleted
|
||||
*/
|
||||
void removeBytes(String owner, String volume, String bucket, int bytes);
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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 javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Request;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* This interface defines operations permitted on a key.
|
||||
*/
|
||||
|
||||
@Path("/{volume}/{bucket}/{keys}")
|
||||
public interface Keys {
|
||||
|
||||
/**
|
||||
* Adds a key to an existing bucket. If the object already exists
|
||||
* this call will overwrite or add with new version number if the bucket
|
||||
* versioning is turned on.
|
||||
*
|
||||
* @param volume Storage Volume Name
|
||||
* @param bucket Name of the bucket
|
||||
* @param keys Name of the Object
|
||||
* @param is InputStream or File Data
|
||||
* @param req Request
|
||||
* @param headers http headers
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws OzoneException
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
Response putKey(@PathParam("volume") String volume,
|
||||
@PathParam("bucket") String bucket,
|
||||
@PathParam("keys") String keys,
|
||||
InputStream is,
|
||||
@Context Request req,
|
||||
@Context UriInfo info,
|
||||
@Context HttpHeaders headers)
|
||||
throws OzoneException;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Key if it exists.
|
||||
*
|
||||
* @param volume Storage Volume
|
||||
* @param bucket Name of the bucket
|
||||
* @param keys Object Name
|
||||
* @param req Request
|
||||
* @param headers Http Header
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws OzoneException
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||
Response getKey(@PathParam("volume") String volume,
|
||||
@PathParam("bucket") String bucket,
|
||||
@PathParam("keys") String keys,
|
||||
@Context Request req,
|
||||
@Context UriInfo info,
|
||||
@Context HttpHeaders headers)
|
||||
throws OzoneException;
|
||||
|
||||
/**
|
||||
* Deletes an existing key.
|
||||
*
|
||||
* @param volume Storage Volume Name
|
||||
* @param bucket Name of the bucket
|
||||
* @param keys Name of the Object
|
||||
* @param req http Request
|
||||
* @param headers HttpHeaders
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws OzoneException
|
||||
*/
|
||||
@DELETE
|
||||
Response deleteKey(@PathParam("volume") String volume,
|
||||
@PathParam("bucket") String bucket,
|
||||
@PathParam("keys") String keys,
|
||||
@Context Request req,
|
||||
@Context UriInfo info,
|
||||
@Context HttpHeaders headers)
|
||||
throws OzoneException;
|
||||
}
|
||||
|
|
@ -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.messages;
|
||||
|
||||
import org.apache.hadoop.hdfs.server.datanode.fsdataset.LengthInputStream;
|
||||
import org.apache.hadoop.io.IOUtils;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.ext.MessageBodyWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Writes outbound HTTP response object bytes. The content length is determined
|
||||
* from the {@link LengthInputStream}.
|
||||
*/
|
||||
public final class LengthInputStreamMessageBodyWriter
|
||||
implements MessageBodyWriter<LengthInputStream> {
|
||||
private static final int CHUNK_SIZE = 8192;
|
||||
|
||||
@Override
|
||||
public long getSize(LengthInputStream lis, Class<?> type, Type genericType,
|
||||
Annotation[] annotations, MediaType mediaType) {
|
||||
return lis.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(Class<?> type, Type genericType,
|
||||
Annotation[] annotations, MediaType mediaType) {
|
||||
return LengthInputStream.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(LengthInputStream lis, Class<?> type, Type genericType,
|
||||
Annotation[] annotations, MediaType mediaType,
|
||||
MultivaluedMap<String, Object> httpHeaders,
|
||||
OutputStream out) throws IOException {
|
||||
IOUtils.copyBytes(lis, out, CHUNK_SIZE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* 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.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Represents an Ozone key Object.
|
||||
*/
|
||||
public class KeyInfo implements Comparable<KeyInfo> {
|
||||
static final String OBJECT_INFO = "OBJECT_INFO_FILTER";
|
||||
/**
|
||||
* This class allows us to create custom filters
|
||||
* for the Json serialization.
|
||||
*/
|
||||
@JsonFilter(OBJECT_INFO)
|
||||
class MixIn {
|
||||
|
||||
}
|
||||
private long version;
|
||||
private String md5hash;
|
||||
private String createdOn;
|
||||
private long size;
|
||||
private String keyName;
|
||||
|
||||
private String dataFileName;
|
||||
|
||||
/**
|
||||
* When this key was created.
|
||||
*
|
||||
* @return Date String
|
||||
*/
|
||||
public String getCreatedOn() {
|
||||
return createdOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* When this key was created.
|
||||
*
|
||||
* @param createdOn - Date String
|
||||
*/
|
||||
public void setCreatedOn(String createdOn) {
|
||||
this.createdOn = createdOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full path to where the actual data for this key is stored.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getDataFileName() {
|
||||
return dataFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up where the file path is stored.
|
||||
*
|
||||
* @param dataFileName - Data File Name
|
||||
*/
|
||||
public void setDataFileName(String dataFileName) {
|
||||
this.dataFileName = dataFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Keyname of this object.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Key name of this object.
|
||||
*
|
||||
* @param keyName - String
|
||||
*/
|
||||
public void setKeyName(String keyName) {
|
||||
this.keyName = keyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MD5 Hash for the data of this key.
|
||||
*
|
||||
* @return String MD5
|
||||
*/
|
||||
public String getMd5hash() {
|
||||
return md5hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the MD5 of this file.
|
||||
*
|
||||
* @param md5hash - Md5 of this file
|
||||
*/
|
||||
public void setMd5hash(String md5hash) {
|
||||
this.md5hash = md5hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of bytes stored in the data part of this key.
|
||||
*
|
||||
* @return long size of the data file
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of the Data part of this key.
|
||||
*
|
||||
* @param size - Size in long
|
||||
*/
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of this key.
|
||||
*
|
||||
* @return - returns the version of this key.
|
||||
*/
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the version of this key.
|
||||
*
|
||||
* @param version - Version String
|
||||
*/
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this object with the specified object for order. Returns a
|
||||
* negative integer, zero, or a positive integer as this object is less
|
||||
* than, equal to, or greater than the specified object.
|
||||
*
|
||||
* @param o the object to be compared.
|
||||
*
|
||||
* @return a negative integer, zero, or a positive integer as this object
|
||||
* is less than, equal to, or greater than the specified object.
|
||||
*
|
||||
* @throws NullPointerException if the specified object is null
|
||||
* @throws ClassCastException if the specified object's type prevents it
|
||||
* from being compared to this object.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(KeyInfo o) {
|
||||
if (this.keyName.compareTo(o.getKeyName()) != 0) {
|
||||
return this.keyName.compareTo(o.getKeyName());
|
||||
}
|
||||
|
||||
if (this.getVersion() == o.getVersion()) {
|
||||
return 0;
|
||||
}
|
||||
if (this.getVersion() < o.getVersion()) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyInfo keyInfo = (KeyInfo) o;
|
||||
|
||||
return new EqualsBuilder()
|
||||
.append(version, keyInfo.version)
|
||||
.append(keyName, keyInfo.keyName)
|
||||
.isEquals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return new HashCodeBuilder(17, 37)
|
||||
.append(version)
|
||||
.append(keyName)
|
||||
.toHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* Parse a string to retuen BucketInfo Object.
|
||||
*
|
||||
* @param jsonString - Json String
|
||||
*
|
||||
* @return - BucketInfo
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static KeyInfo parse(String jsonString) throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.readValue(jsonString, KeyInfo.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a JSON string of this object.
|
||||
* After stripping out bytesUsed and keyCount
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String toJsonString() throws IOException {
|
||||
String[] ignorableFieldNames = {"dataFileName"};
|
||||
|
||||
FilterProvider filters = new SimpleFilterProvider()
|
||||
.addFilter(OBJECT_INFO, SimpleBeanPropertyFilter
|
||||
.serializeAllExcept(ignorableFieldNames));
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper()
|
||||
.setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||
mapper.getSerializationConfig()
|
||||
.addMixInAnnotations(Object.class, MixIn.class);
|
||||
ObjectWriter writer = mapper.writer(filters);
|
||||
return writer.writeValueAsString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Object as a Json String.
|
||||
*/
|
||||
public String toDBString() throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.writeValueAsString(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* 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.handlers.ListArgs;
|
||||
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;
|
||||
|
||||
/**
|
||||
* This class the represents the list of keys (Objects) in a bucket.
|
||||
*/
|
||||
public class ListKeys {
|
||||
static final String OBJECT_LIST = "OBJECT_LIST_FILTER";
|
||||
private String name;
|
||||
private String prefix;
|
||||
private long maxKeys;
|
||||
private boolean truncated;
|
||||
private List<KeyInfo> objectList;
|
||||
|
||||
/**
|
||||
* Default constructor needed for json serialization.
|
||||
*/
|
||||
public ListKeys() {
|
||||
this.objectList = new LinkedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for ListKeys.
|
||||
*
|
||||
* @param args ListArgs
|
||||
* @param truncated is truncated
|
||||
*/
|
||||
public ListKeys(ListArgs args, boolean truncated) {
|
||||
this.name = args.getBucketName();
|
||||
this.prefix = args.getPrefix();
|
||||
this.maxKeys = args.getMaxKeys();
|
||||
this.truncated = truncated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Json string to POJO.
|
||||
* @param jsonString
|
||||
* @return ListObject
|
||||
* @throws IOException
|
||||
*/
|
||||
public static ListKeys parse(String jsonString) throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.readValue(jsonString, ListKeys.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of Objects.
|
||||
*
|
||||
* @return List of KeyInfo Objects.
|
||||
*/
|
||||
public List<KeyInfo> getObjectList() {
|
||||
return objectList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of Objects.
|
||||
*
|
||||
* @param objectList
|
||||
*/
|
||||
public void setObjectList(List<KeyInfo> objectList) {
|
||||
this.objectList = objectList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Max Key Count.
|
||||
*
|
||||
* @return long
|
||||
*/
|
||||
public long getMaxKeys() {
|
||||
return maxKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets bucket Name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Prefix.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets truncated Status.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public boolean isTruncated() {
|
||||
return truncated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of truncated.
|
||||
*
|
||||
* @param value - Boolean
|
||||
*/
|
||||
public void setTruncated(boolean value) {
|
||||
this.truncated = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON string of this object. After stripping out bytesUsed and
|
||||
* keyCount.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String toJsonString() throws IOException {
|
||||
String[] ignorableFieldNames = {"dataFileName"};
|
||||
|
||||
FilterProvider filters = new SimpleFilterProvider().addFilter(OBJECT_LIST,
|
||||
SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper()
|
||||
.setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||
mapper.getSerializationConfig()
|
||||
.addMixInAnnotations(Object.class, MixIn.class);
|
||||
ObjectWriter writer = mapper.writer(filters);
|
||||
return writer.writeValueAsString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Object as a Json String.
|
||||
*/
|
||||
public String toDBString() throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.writeValueAsString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the keys based on name and version. This is useful when we return the
|
||||
* list of keys.
|
||||
*/
|
||||
public void sort() {
|
||||
Collections.sort(objectList);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class allows us to create custom filters for the Json serialization.
|
||||
*/
|
||||
@JsonFilter(OBJECT_LIST)
|
||||
class MixIn {
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue