Package com.github.ambry.rest
Class RestUtils
- java.lang.Object
-
- com.github.ambry.rest.RestUtils
-
public class RestUtils extends java.lang.Object
Common utility functions that will be used across implementations of REST interfaces.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
RestUtils.Headers
Ambry specific HTTP headers.static class
RestUtils.InternalKeys
Ambry specific keys used internally in aRestRequest
.static class
RestUtils.MultipartPost
static class
RestUtils.SubResource
Permitted sub-resources of a blob.static class
RestUtils.TrackingHeaders
-
Field Summary
Fields Modifier and Type Field Description static java.lang.String
BYTE_RANGE_UNITS
static java.lang.String
HTTP_DATE_FORMAT
static java.lang.String
JSON_CONTENT_TYPE
static java.lang.String
SIGNED_ID_PREFIX
-
Constructor Summary
Constructors Constructor Description RestUtils()
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static void
accountAndContainerNamePreconditionCheck(RestRequest restRequest)
Check preconditions for request if therestRequest
contains the target account and container.static BlobProperties
buildBlobProperties(java.util.Map<java.lang.String,java.lang.Object> args)
BuildsBlobProperties
given the arguments associated with a request.static com.github.ambry.utils.Pair<java.lang.String,java.lang.Long>
buildContentRangeAndLength(ByteRange range, long blobSize, boolean resolveRangeOnEmptyBlob)
Build the value for the Content-Range header that corresponds to the provided range and blob size.static GetBlobOptions
buildGetBlobOptions(java.util.Map<java.lang.String,java.lang.Object> args, RestUtils.SubResource subResource, GetOption getOption, int blobSegmentIdx)
Build aGetBlobOptions
object from an argument map for a certain sub-resource.static java.util.Map<java.lang.String,java.lang.String>
buildUserMetadata(byte[] userMetadata)
Gets deserialized metadata from the byte array if possiblestatic byte[]
buildUserMetadata(java.util.Map<java.lang.String,java.lang.Object> args)
Builds user metadata given the arguments associated with a request.static void
ensureRequiredHeadersOrThrow(RestRequest restRequest, java.util.Set<java.lang.String> requiredHeaders)
Ensures the required headers are present.static Account
getAccountFromArgs(java.util.Map<java.lang.String,java.lang.Object> args)
Extract the injectedAccount
from a map of arguments.static boolean
getBooleanHeader(java.util.Map<java.lang.String,java.lang.Object> args, java.lang.String header, boolean required)
Gets the value of a header as aboolean
.static Container
getContainerFromArgs(java.util.Map<java.lang.String,java.lang.Object> args)
Extract the injectedContainer
from a map of arguments.static GetOption
getGetOption(RestRequest restRequest, GetOption defaultGetOption)
Gets theGetOption
required by the request.static java.lang.String
getHeader(java.util.Map<java.lang.String,?> args, java.lang.String header, boolean required)
Gets the value of the headerheader
inargs
.static java.lang.Long
getLongHeader(java.util.Map<java.lang.String,?> args, java.lang.String header, boolean required)
Gets the value of a header as aLong
static <T extends java.lang.Number>
TgetNumericalHeader(java.util.Map<java.lang.String,?> args, java.lang.String header, boolean required, java.util.function.Function<java.lang.String,T> converter)
Gets the value of a header as aNumber
, using the provided converter function to parse the string.static RequestPath
getRequestPath(RestRequest restRequest)
Extract theRequestPath
object fromRestRequest
arguments.static java.lang.Long
getTimeFromDateString(java.lang.String dateString)
Fetch time in ms for thedateString
passed in, since epochstatic boolean
isChunkUpload(java.util.Map<java.lang.String,java.lang.Object> args)
Determine ifRestUtils.Headers.CHUNK_UPLOAD
is set in the request args.static boolean
isPrivate(java.util.Map<java.lang.String,java.lang.Object> args)
Gets the isPrivate setting from the args.static boolean
setUserMetadataHeaders(byte[] userMetadata, RestResponseChannel restResponseChannel)
Sets the user metadata in the headers of the response.static void
setUserMetadataHeaders(java.util.Map<java.lang.String,java.lang.String> userMetadataMap, RestResponseChannel restResponseChannel)
Sets the user metadata in the headers of the response.static java.lang.String
stripSlashAndExtensionFromId(java.lang.String blobIdWithExtension)
Drops the leading slash and extension (if any) in the blob ID.static long
toSecondsPrecisionInMs(long ms)
Reduces the precision of a time in milliseconds to seconds precision.static java.lang.String
verifyChunkUploadSession(java.util.Map<java.lang.String,java.lang.String> chunkMetadata, java.lang.String expectedSession)
Verify that the session ID in the chunk metadata matches the expected session.
-
-
-
Field Detail
-
HTTP_DATE_FORMAT
public static final java.lang.String HTTP_DATE_FORMAT
- See Also:
- Constant Field Values
-
BYTE_RANGE_UNITS
public static final java.lang.String BYTE_RANGE_UNITS
- See Also:
- Constant Field Values
-
SIGNED_ID_PREFIX
public static final java.lang.String SIGNED_ID_PREFIX
- See Also:
- Constant Field Values
-
JSON_CONTENT_TYPE
public static final java.lang.String JSON_CONTENT_TYPE
- See Also:
- Constant Field Values
-
-
Method Detail
-
buildBlobProperties
public static BlobProperties buildBlobProperties(java.util.Map<java.lang.String,java.lang.Object> args) throws RestServiceException
BuildsBlobProperties
given the arguments associated with a request.- Parameters:
args
- the arguments associated with the request. Cannot benull
.- Returns:
- the
BlobProperties
extracted from the arguments. - Throws:
RestServiceException
- if required arguments aren't present or if they aren't in the format or number expected.
-
buildUserMetadata
public static byte[] buildUserMetadata(java.util.Map<java.lang.String,java.lang.Object> args) throws RestServiceException
Builds user metadata given the arguments associated with a request.The following binary format will be used:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | size | total | | | | | | | | | version | excluding | no of | key1 size | key1 | value1 size | value 1 | key2 size | ... | Crc | |(2 bytes)| ver & crc | entries | (4 bytes) |(key1 size| (4 bytes) |(value1 size| (4 bytes) | ... | (8 bytes) | | | (4 bytes) | (4 bytes)| | bytes) | | bytes) | | | | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - version - The version of the user metadata record size exluding ver & CRC - The size of the user metadata content excluding the version and the CRC total no of entries - Total number of entries in user metadata key1 size - Size of 1st key key1 - Content of key1 value1 size - Size of 1st value value1 - Content of value1 key2 size - Size of 2nd key crc - The crc of the user metadata record
- Parameters:
args
- the arguments associated with the request.- Returns:
- the user metadata extracted from arguments.
- Throws:
RestServiceException
- if usermetadata arguments have null values.
-
buildUserMetadata
public static java.util.Map<java.lang.String,java.lang.String> buildUserMetadata(byte[] userMetadata)
Gets deserialized metadata from the byte array if possible- Parameters:
userMetadata
- the byte array which has the user metadata- Returns:
- the user metadata that is read from the byte array, or
null
if theuserMetadata
cannot be parsed in expected format
-
buildGetBlobOptions
public static GetBlobOptions buildGetBlobOptions(java.util.Map<java.lang.String,java.lang.Object> args, RestUtils.SubResource subResource, GetOption getOption, int blobSegmentIdx) throws RestServiceException
Build aGetBlobOptions
object from an argument map for a certain sub-resource.- Parameters:
args
- the arguments associated with the request. This is typically a map of header names and query string arguments to values.subResource
- theRestUtils.SubResource
for the request, ornull
if no sub-resource is requested.getOption
- theGetOption
required.blobSegmentIdx
- index of blob segment one wishes to GET,GetBlobOptions.NO_BLOB_SEGMENT_IDX_SPECIFIED
if not used- Returns:
- a populated
GetBlobOptions
object. - Throws:
RestServiceException
- if theGetBlobOptions
could not be constructed.
-
buildContentRangeAndLength
public static com.github.ambry.utils.Pair<java.lang.String,java.lang.Long> buildContentRangeAndLength(ByteRange range, long blobSize, boolean resolveRangeOnEmptyBlob) throws RestServiceException
Build the value for the Content-Range header that corresponds to the provided range and blob size. The returned Content-Range header value will be in the following format:bytes {a}-{b}/{c}
, where{a}
is the inclusive start byte offset of the returned range,{b}
is the inclusive end byte offset of the returned range, and{c}
is the total size of the blob in bytes. This function also generates the range length in bytes.- Parameters:
range
- aByteRange
used to generate the Content-Range header.blobSize
- the total size of the associated blob in bytes.resolveRangeOnEmptyBlob
-true
to force range resolution to succeed if the blob is empty. In other words, returnbytes 1-0/0
iftotalSize == 0
.- Returns:
- a
Pair
containing the content range header value and the content length in bytes. - Throws:
RestServiceException
-
getRequestPath
public static RequestPath getRequestPath(RestRequest restRequest)
Extract theRequestPath
object fromRestRequest
arguments.- Parameters:
restRequest
- theRestRequest
.- Returns:
- the
RequestPath
-
getTimeFromDateString
public static java.lang.Long getTimeFromDateString(java.lang.String dateString)
Fetch time in ms for thedateString
passed in, since epoch- Parameters:
dateString
- the String representation of the date that needs to be parsed- Returns:
- Time in ms since epoch. Note http time is kept in Seconds so last three digits will be 000.
Returns null if the
dateString
is not in the expected format or could not be parsed
-
toSecondsPrecisionInMs
public static long toSecondsPrecisionInMs(long ms)
Reduces the precision of a time in milliseconds to seconds precision. Result returned is in milliseconds with last three digits 000. Useful for comparing times kept in milliseconds that get converted to seconds and back (as is done with HTTP date format).- Parameters:
ms
- time that needs to be parsed- Returns:
- milliseconds with seconds precision (last three digits 000).
-
getGetOption
public static GetOption getGetOption(RestRequest restRequest, GetOption defaultGetOption) throws RestServiceException
Gets theGetOption
required by the request.- Parameters:
restRequest
- the representation of the request.defaultGetOption
- theGetOption
to use if therestRequest
doesn't have one. Can benull
.- Returns:
- the required
GetOption
. Defaults toGetOption.None
. - Throws:
RestServiceException
- if theRestUtils.Headers.GET_OPTION
is present but not recognized.
-
isPrivate
public static boolean isPrivate(java.util.Map<java.lang.String,java.lang.Object> args) throws RestServiceException
Gets the isPrivate setting from the args.- Parameters:
args
- The args where to include the isPrivate setting.- Returns:
- A boolean to indicate the value of the isPrivate flag.
- Throws:
RestServiceException
- if exception occurs during parsing the arg.
-
isChunkUpload
public static boolean isChunkUpload(java.util.Map<java.lang.String,java.lang.Object> args) throws RestServiceException
Determine ifRestUtils.Headers.CHUNK_UPLOAD
is set in the request args.- Parameters:
args
- The request arguments.- Returns:
true
ifRestUtils.Headers.CHUNK_UPLOAD
is set.- Throws:
RestServiceException
- if exception occurs during parsing the arg.
-
ensureRequiredHeadersOrThrow
public static void ensureRequiredHeadersOrThrow(RestRequest restRequest, java.util.Set<java.lang.String> requiredHeaders) throws RestServiceException
Ensures the required headers are present.- Parameters:
restRequest
- TheRestRequest
to ensure header presence. Cannot benull
.requiredHeaders
- A set of headers to check presence. Cannot benull
.- Throws:
RestServiceException
- if any of the headers is missing.
-
getHeader
public static java.lang.String getHeader(java.util.Map<java.lang.String,?> args, java.lang.String header, boolean required) throws RestServiceException
Gets the value of the headerheader
inargs
.- Parameters:
args
- a map of arguments to be used to look forheader
.header
- the name of the header.required
- iftrue
,IllegalArgumentException
will be thrown ifheader
is not present inargs
.- Returns:
- the value of
header
inargs
if it exists. If it does not exist andrequired
isfalse
, then returns null. - Throws:
RestServiceException
- ifrequired
istrue
andheader
does not exist inargs
or if there is more than one value forheader
inargs
.
-
getLongHeader
public static java.lang.Long getLongHeader(java.util.Map<java.lang.String,?> args, java.lang.String header, boolean required) throws RestServiceException
Gets the value of a header as aLong
- Parameters:
args
- a map of arguments to be used to look forheader
.header
- the name of the header.required
- iftrue
,RestServiceException
will be thrown ifheader
is not present inargs
.- Returns:
- the value of
header
inargs
if it exists. If it does not exist andrequired
isfalse
, then returns null. - Throws:
RestServiceException
- same as cases ofgetHeader(Map, String, boolean)
and if the value cannot be converted to aLong
.
-
getNumericalHeader
public static <T extends java.lang.Number> T getNumericalHeader(java.util.Map<java.lang.String,?> args, java.lang.String header, boolean required, java.util.function.Function<java.lang.String,T> converter) throws RestServiceException
Gets the value of a header as aNumber
, using the provided converter function to parse the string.- Parameters:
args
- a map of arguments to be used to look forheader
.header
- the name of the header.required
- iftrue
,RestServiceException
will be thrown ifheader
is not present inargs
.converter
- a function to convert from aString
to the desired numerical type. This should throwNumberFormatException
if the argument is not a valid number.- Returns:
- the value of
header
inargs
if it exists. If it does not exist andrequired
isfalse
, then returns null. - Throws:
RestServiceException
- same as cases ofgetHeader(Map, String, boolean)
and if the value cannot be converted to aLong
.
-
getBooleanHeader
public static boolean getBooleanHeader(java.util.Map<java.lang.String,java.lang.Object> args, java.lang.String header, boolean required) throws RestServiceException
Gets the value of a header as aboolean
.- Parameters:
args
- a map of arguments to be used to look forheader
.header
- the name of the header.required
- iftrue
,RestServiceException
will be thrown ifheader
is not present inargs
.- Returns:
true
if the header's value is"true"
(case-insensitive), orfalse
if the header's value is"false
(case-insensitive) or the header is not present andrequired
isfalse
.- Throws:
RestServiceException
- same as cases ofgetHeader(Map, String, boolean)
and if the value cannot be converted to aboolean
.
-
getAccountFromArgs
public static Account getAccountFromArgs(java.util.Map<java.lang.String,java.lang.Object> args) throws RestServiceException
Extract the injectedAccount
from a map of arguments.- Parameters:
args
- a map of arguments that possibly contains the injectedAccount
andContainer
.- Returns:
- the
Account
- Throws:
RestServiceException
-
getContainerFromArgs
public static Container getContainerFromArgs(java.util.Map<java.lang.String,java.lang.Object> args) throws RestServiceException
Extract the injectedContainer
from a map of arguments.- Parameters:
args
- a map of arguments that possibly contains the injectedAccount
andContainer
.- Returns:
- a
Container
- Throws:
RestServiceException
-
accountAndContainerNamePreconditionCheck
public static void accountAndContainerNamePreconditionCheck(RestRequest restRequest) throws RestServiceException
Check preconditions for request if therestRequest
contains the target account and container.- Parameters:
restRequest
- theRestRequest
that contains theAccount
andContainer
details.- Throws:
RestServiceException
- if preconditions check failed.
-
setUserMetadataHeaders
public static boolean setUserMetadataHeaders(byte[] userMetadata, RestResponseChannel restResponseChannel)
Sets the user metadata in the headers of the response.- Parameters:
userMetadata
- byte array containing user metadata that needs to be sent.restResponseChannel
- theRestResponseChannel
that is used for sending the response.- Returns:
true
if the user metadata was successfully deserialized into headers,false
if not.- Throws:
RestServiceException
- if there are any problems setting the header.
-
setUserMetadataHeaders
public static void setUserMetadataHeaders(java.util.Map<java.lang.String,java.lang.String> userMetadataMap, RestResponseChannel restResponseChannel)
Sets the user metadata in the headers of the response.- Parameters:
userMetadataMap
- map of user metadata that needs to be sent.restResponseChannel
- theRestResponseChannel
that is used for sending the response.- Throws:
RestServiceException
- if there are any problems setting the header.
-
verifyChunkUploadSession
public static java.lang.String verifyChunkUploadSession(java.util.Map<java.lang.String,java.lang.String> chunkMetadata, java.lang.String expectedSession) throws RestServiceException
Verify that the session ID in the chunk metadata matches the expected session.- Parameters:
chunkMetadata
- the metadata map parsed from a signed chunk ID.expectedSession
- the session that the chunk should match. This can be null for the first chunk (where any session ID is valid).- Returns:
- this chunk's session ID
- Throws:
RestServiceException
- if the chunk has a null session ID or it does not match the expected value.
-
stripSlashAndExtensionFromId
public static java.lang.String stripSlashAndExtensionFromId(java.lang.String blobIdWithExtension)
Drops the leading slash and extension (if any) in the blob ID.- Parameters:
blobIdWithExtension
- the blob ID possibly with an extension.- Returns:
blobIdWithExtension
without an extension if there was one.
-
-