Files
gerrit/java/com/google/gerrit/server/restapi/change/DownloadContent.java
Edwin Kempin b446055fc0 Require REST endpoints to return Response<?>
At the moment REST endpoints can choose if they return a result object
(that will be converted to JSON automatically unless it is a
BinaryResult) or if they return a response object that specifies the
response status code and other properties like caching behavior in
addition to the result object. In addition REST endpoints can return
special objects like Response.Redirect and Response.Accepted to trigger
special behavior (Response.Redirect and Response.Accepted are neither a
result object, nor a response object).

If the first approach is chosen and a result object is returned, it is
not clear from the implementation of the REST endpoint which status code
is returned to the client. By default it is '200 OK', for
RestCollectionCreateViews that are invoked via HTTP PUT/POST it is
'201 Created' and for RestCollectionDeleteMissingViews that are invoked
via HTTP DELETE it is '204 No Content'.

By forcing REST endpoints to return a response object they must specify
the status code. Hence implementors must explicitly think about this.
Hopefully this leads to a more consistent use of status codes in our
REST API. At the moment it happens frequently that status codes are
wrong and need to be fixed, which is always a bit risky since callers
may rely on an expected status code.

Having all REST endpoints return response objects also has the advantage
that wrappers around REST endpoints, such as RetryingRestModifyView, can
set additional properties on the response. E.g. change I2b78cbef5
implements automatic request tracing in RetryingRestModifyView, but
currently has no possibility to return the trace ID to the client. If
that was possible, error popups in the frontend could display the trace
ID. If the trace ID is included into bug reports, investigation of
issues gets easier and faster.

Response.Redirect and Response.Accepted are made subclasses of Response
so that REST endpoints can still return them.

Change-Id: I1dd37821a8a859ade43336eb5f6cce6bcc71fc02
Signed-off-by: Edwin Kempin <ekempin@google.com>
2019-08-05 15:35:47 +02:00

53 lines
2.0 KiB
Java

// Copyright (C) 2015 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.server.restapi.change;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.change.FileContentUtil;
import com.google.gerrit.server.change.FileResource;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.inject.Inject;
import java.io.IOException;
import org.kohsuke.args4j.Option;
public class DownloadContent implements RestReadView<FileResource> {
private final FileContentUtil fileContentUtil;
private final ProjectCache projectCache;
@Option(name = "--parent")
private Integer parent;
@Inject
DownloadContent(FileContentUtil fileContentUtil, ProjectCache projectCache) {
this.fileContentUtil = fileContentUtil;
this.projectCache = projectCache;
}
@Override
public Response<BinaryResult> apply(FileResource rsrc)
throws ResourceNotFoundException, IOException, NoSuchChangeException {
String path = rsrc.getPatchKey().fileName();
RevisionResource rev = rsrc.getRevision();
return Response.ok(
fileContentUtil.downloadContent(
projectCache.checkedGet(rev.getProject()), rev.getPatchSet().commitId(), path, parent));
}
}