Minor code improvements

Signed-off-by: Dominic Schabel dominic.schabel@bosch-si.com
This commit is contained in:
Dominic Schabel
2016-08-15 11:30:21 +02:00
parent 7f156f05a4
commit 3accac9ade
50 changed files with 639 additions and 696 deletions

View File

@@ -9,11 +9,24 @@
package org.eclipse.hawkbit.rest.util;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.HttpHeaders.ACCEPT_RANGES;
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
import static com.google.common.net.HttpHeaders.CONTENT_RANGE;
import static com.google.common.net.HttpHeaders.ETAG;
import static com.google.common.net.HttpHeaders.IF_RANGE;
import static com.google.common.net.HttpHeaders.LAST_MODIFIED;
import static java.math.RoundingMode.DOWN;
import static javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT;
import static org.eclipse.hawkbit.rest.util.ByteRange.MULTIPART_BOUNDARY;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.PARTIAL_CONTENT;
import static org.springframework.http.HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE;
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -27,23 +40,19 @@ import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import com.google.common.math.DoubleMath;
import com.google.common.net.HttpHeaders;
/**
* Utility class for the Rest Source API.
*
*/
public final class RestResourceConversionHelper {
private static final Logger LOG = LoggerFactory.getLogger(RestResourceConversionHelper.class);
private static final int BUFFER_SIZE = 4096;
// utility class, private constructor.
private RestResourceConversionHelper() {
}
@@ -92,7 +101,8 @@ public final class RestResourceConversionHelper {
*
* @return http code
*
* @see https://tools.ietf.org/html/rfc7233
* @see <a href="https://tools.ietf.org/html/rfc7233">https://tools.ietf.org
* /html/rfc7233</a>
*/
public static ResponseEntity<InputStream> writeFileResponse(final LocalArtifact artifact,
final HttpServletResponse response, final HttpServletRequest request, final DbArtifact file,
@@ -107,11 +117,11 @@ public final class RestResourceConversionHelper {
response.reset();
response.setBufferSize(BUFFER_SIZE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFilename());
response.setHeader(HttpHeaders.ETAG, etag);
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFilename());
response.setHeader(ETAG, etag);
response.setHeader(ACCEPT_RANGES, "bytes");
response.setDateHeader(LAST_MODIFIED, lastModified);
response.setContentType(APPLICATION_OCTET_STREAM_VALUE);
final ByteRange full = new ByteRange(0, length - 1, length);
final List<ByteRange> ranges = new ArrayList<>();
@@ -123,9 +133,9 @@ public final class RestResourceConversionHelper {
// Range header matches"bytes=n-n,n-n,n-n..."
if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + length);
response.setHeader(CONTENT_RANGE, "bytes */" + length);
LOG.debug("range header for filename ({}) is not satisfiable: ", artifact.getFilename());
return new ResponseEntity<>(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
return new ResponseEntity<>(REQUESTED_RANGE_NOT_SATISFIABLE);
}
// RFC: if the representation is unchanged, send me the part(s) that
@@ -144,32 +154,31 @@ public final class RestResourceConversionHelper {
// full request - no range
if (ranges.isEmpty() || ranges.get(0).equals(full)) {
LOG.debug("filename ({}) results into a full request: ", artifact.getFilename());
fullfileRequest(artifact, response, file, controllerManagement, statusId, full);
result = new ResponseEntity<>(HttpStatus.OK);
handleFullFileRequest(artifact, response, file, controllerManagement, statusId, full);
result = new ResponseEntity<>(OK);
}
// standard range request
else if (ranges.size() == 1) {
LOG.debug("filename ({}) results into a standard range request: ", artifact.getFilename());
standardRangeRequest(artifact, response, file, controllerManagement, statusId, ranges);
result = new ResponseEntity<>(HttpStatus.PARTIAL_CONTENT);
handleStandardRangeRequest(artifact, response, file, controllerManagement, statusId, ranges);
result = new ResponseEntity<>(PARTIAL_CONTENT);
}
// multipart range request
else {
LOG.debug("filename ({}) results into a multipart range request: ", artifact.getFilename());
multipartRangeRequest(artifact, response, file, controllerManagement, statusId, ranges);
result = new ResponseEntity<>(HttpStatus.PARTIAL_CONTENT);
handleMultipartRangeRequest(artifact, response, file, controllerManagement, statusId, ranges);
result = new ResponseEntity<>(PARTIAL_CONTENT);
}
return result;
}
private static void fullfileRequest(final LocalArtifact artifact, final HttpServletResponse response,
private static void handleFullFileRequest(final LocalArtifact artifact, final HttpServletResponse response,
final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId,
final ByteRange full) {
final ByteRange r = full;
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(r.getLength()));
response.setHeader(CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
response.setHeader(CONTENT_LENGTH, String.valueOf(r.getLength()));
try {
copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId,
@@ -182,7 +191,7 @@ public final class RestResourceConversionHelper {
private static ResponseEntity<InputStream> extractRange(final HttpServletResponse response, final long length,
final List<ByteRange> ranges, final String range) {
ResponseEntity<InputStream> result = null;
if (ranges.isEmpty()) {
for (final String part : range.substring(6).split(",")) {
long start = sublong(part, 0, part.indexOf('-'));
@@ -198,9 +207,8 @@ public final class RestResourceConversionHelper {
// Check if Range is syntactically valid. If not, then return
// 416.
if (start > end) {
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + length);
result = new ResponseEntity<>(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
return result;
response.setHeader(CONTENT_RANGE, "bytes */" + length);
return new ResponseEntity<>(REQUESTED_RANGE_NOT_SATISFIABLE);
}
// Add range.
@@ -218,10 +226,10 @@ public final class RestResourceConversionHelper {
private static void checkForShortcut(final HttpServletRequest request, final String etag, final long lastModified,
final ByteRange full, final List<ByteRange> ranges) {
final String ifRange = request.getHeader(HttpHeaders.IF_RANGE);
final String ifRange = request.getHeader(IF_RANGE);
if (ifRange != null && !ifRange.equals(etag)) {
try {
final long ifRangeTime = request.getDateHeader(HttpHeaders.IF_RANGE);
final long ifRangeTime = request.getDateHeader(IF_RANGE);
if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
ranges.add(full);
}
@@ -232,17 +240,17 @@ public final class RestResourceConversionHelper {
}
}
private static void multipartRangeRequest(final LocalArtifact artifact, final HttpServletResponse response,
private static void handleMultipartRangeRequest(final LocalArtifact artifact, final HttpServletResponse response,
final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId,
final List<ByteRange> ranges) {
response.setContentType("multipart/byteranges; boundary=" + ByteRange.MULTIPART_BOUNDARY);
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
response.setStatus(SC_PARTIAL_CONTENT);
try {
for (final ByteRange r : ranges) {
// Add multipart boundary and header fields for every range.
response.getOutputStream().println();
response.getOutputStream().println("--" + ByteRange.MULTIPART_BOUNDARY);
response.getOutputStream().println("--" + MULTIPART_BOUNDARY);
response.getOutputStream()
.println("Content-Range: bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
@@ -253,20 +261,20 @@ public final class RestResourceConversionHelper {
// End with final multipart boundary.
response.getOutputStream().println();
response.getOutputStream().print("--" + ByteRange.MULTIPART_BOUNDARY + "--");
response.getOutputStream().print("--" + MULTIPART_BOUNDARY + "--");
} catch (final IOException e) {
LOG.error("multipartRangeRequest of file ({}) failed!", artifact.getFilename(), e);
throw new FileSteamingFailedException(artifact.getFilename());
}
}
private static void standardRangeRequest(final LocalArtifact artifact, final HttpServletResponse response,
private static void handleStandardRangeRequest(final LocalArtifact artifact, final HttpServletResponse response,
final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId,
final List<ByteRange> ranges) {
final ByteRange r = ranges.get(0);
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(r.getLength()));
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
response.setHeader(CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal());
response.setHeader(CONTENT_LENGTH, String.valueOf(r.getLength()));
response.setStatus(SC_PARTIAL_CONTENT);
try {
copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId,
@@ -315,7 +323,7 @@ public final class RestResourceConversionHelper {
}
if (controllerManagement != null) {
final int newPercent = DoubleMath.roundToInt(total * 100.0 / length, RoundingMode.DOWN);
final int newPercent = DoubleMath.roundToInt(total * 100.0 / length, DOWN);
// every 10 percent an event
if (newPercent == 100 || newPercent > progressPercent + 10) {