-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DS-3651: Range header support #1884
Conversation
Coverage increased (+0.5%) to 21.305% when pulling b84c2183283511c1e8a252bb647aeb7cc12aeba1 on atmire:DS-3651_Range-Header-support into 716912f on DSpace:master. |
Coverage increased (+0.5%) to 21.341% when pulling 4afa0f240893de74e4a26aa7bcd2a738e5f26426 on atmire:DS-3651_Range-Header-support into 716912f on DSpace:master. |
<!--<bean class="org.dspace.discovery.SolrServiceIndexOutputPlugin" id="solrServiceIndexOutputPlugin"/>--> | ||
|
||
<!-- Statistics services are both lazy loaded (by name), as you are likely just using ONE of them and not both --> | ||
<bean id="elasticSearchLoggerService" class="org.dspace.statistics.ElasticSearchLoggerServiceImpl" lazy-init="true"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this really required? the plan is to withdrawn ES support in DSpace7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved these services from here to this new file so that we can override them in the integration tests.
I suggest we remove the elasticSearchLoggerService
bean once we remove the complete Elastic Search implementation. I don't want to partly cleanup Elastic Search now with the risk of forgetting stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I agree
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestMethod; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
/** | ||
* This is a specialized controller to provide access to the bitstream binary content | ||
* | ||
* @author Andrea Bollini (andrea.bollini at 4science.it) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add the name of the main authors of the class
try { | ||
authorizeService.authorizeAction(context, bit, Constants.READ); | ||
} catch (AuthorizeException e) { | ||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as said I'm unsure about adding the auth check here. In any case we should not deal with the response directly but throw a new REST runtime AuthorizeException that can be annotated see https://github.com/DSpace/DSpace/blob/master/dspace-spring-rest/src/main/java/org/dspace/app/rest/exception/RepositoryNotFoundException.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also implement a @ControllerAdvice
class that has a handler method for AuthorizeException
s. That way we don't have to manually convert this exception to a REST runtime exception. What do you think?
} | ||
|
||
} catch(IOException ex) { | ||
log.debug("Client aborted the request before the download was completed. Client is probably switching to a Range request.", ex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you sure about that? an IOException can occur if we have issue to read from the underline storage. If the client abort the request the exception should occur on the Servlet container stack as writing to the response is in some way "buffered" by tomcat, etc. (I admit I haven't check)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll make the check more specific on the "Client aborted" use case.
|
||
} catch(IOException ex) { | ||
log.debug("Client aborted the request before the download was completed. Client is probably switching to a Range request.", ex); | ||
} catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No please, avoid catch all block. If we have other not runtime exceptions they should be encapsulated in a REST Exception to have single trasversal code to deal with logging and response code. We should move to the SpringMVC exception handling way https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
} | ||
} | ||
|
||
private boolean isNotAnErrorResponse(HttpServletResponse response) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
once you switch to the mvc exception handing this should be not required anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our Range header utility class also sets some error codes. So we cannot remove this method.
import org.dspace.app.rest.model.EPersonRest; | ||
import org.dspace.app.rest.model.GroupRest; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that we have an open conversation about setting code style to avoid such kind of issue... but can you exclude from the PR the file that only have fix to the import? this should be done in a single dedicated pr when we have set our codestyle. This PR doesn't really need to touch more than 5-10 files I guess
dspace/config/dspace.cfg
Outdated
@@ -1972,6 +1963,9 @@ mail.helpdesk = ${mail.admin} | |||
# Should all Request Copy emails go to the helpdesk instead of the item submitter? | |||
request.item.helpdesk.override = false | |||
|
|||
# 2 MB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add more details about the intend of the parameter? it is a limit for the range requests? it is discoverable in some way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the size of the byte buffer used for copying data from the bitstream InputStream to the request OutputStream. We can also omit the configuration property and give it a static value.
@@ -0,0 +1 @@ | |||
You should only add Spring XML definition files here if there is really no way to load them through automatic component scanning. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A good use case to place xml here is to allow override of the provided configuration such as the listners enabled for usage events that you have included
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope that in the future we also find an easy way (using XML?) to override the default bean implementations we now have in dspace-spring-rest. For example, what if I want to use a custom ItemConverter
bean in my own custom repository.
|
||
Context context = ContextUtil.obtainContext(request); | ||
|
||
Bitstream bit = getBitstreamIfAuthorized(context, uuid, response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should throw the authorize exception and use the spring mvc excpetion handling here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it OK if we take the global exception handling approach using @ControllerAdvice
?
* @author Andrea Bollini (andrea.bollini at 4science.it) | ||
* @author Atmire NV (info at atmire dot com) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we haven't really "policed" @author
tags closely in recent years, I feel we should likely keep them pointing at individuals (who want credit for creating/refactoring specific classes) instead of organizations. I'm a bit worried that labeling classes with organizational contact info is a bit misleading, as it no longer refers to the specific creator of the class, and also could become an advertising gimmick/battle within our codebase (over which company gets more credit). The only company that "owns" the code is DuraSpace, and we just own the copyright in order to ensure the code remains open source, etc.
So, personally, I feel we should avoid this sort of change in our codebase. Either leave off the @author
altogether, or reference the individual(s) who created / refactored the class.
However, if others disagree strongly here, I'll gladly bring this to discussion within the Committers group and/or Steering Group, so that we can formalize a policy on @author
tags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only noted this in the first file I found with this company @author
tag. There are a few others
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While Frederic and I did most of the development, there are also other people at Atmire who provided input and ideas for this (and other) pull-requests. And it is because other colleagues are working full-time on other projects, that Frederic and I have time allocated to work on DSpace 7. So it doesn't feel fair to only put my and Frederic's name as this PR would not have been possible without the support of Atmire.
And while I understand your concerns on the "advertising gimmick/battle", our codebase already contains a lot of company names/websites and contacts as people tend to use their professional e-mail address. There already are other examples of general company authors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomdesair : Thanks for pointing out the Lyncode @author
tags. I suspect those slipped in during the massive OAI refactor (i.e. creation of XOAI) many years back. It's simply hard to police this sort of thing. Had I noticed these at the time, I also would have questioned them. And, I'd rather remove them then add in more.
FWIW, other major projects (Apache Foundation and Gradle are two, see this blog post for example) do not allow any @author
tags whatsoever. Their policy seem to be they quickly get out of date or are misleading, and simply cause clutter. While I understand your reasoning, I think individuals should be attributed via commits or via name, and not via a blanket generic statement. As-is, I think "Atmire NV (info at atmire dot com)" gives us no information about who actually worked on this code at Atmire, so there's no way to attribute those individuals in our Contributor list, or even (eventually) consider those individuals for Committership
44b4b2f
to
b0bb8eb
Compare
@tdonohue I've corrected the author tags to unblock this PR. Once there is a decision on the usage of |
I have solved a minor conflict in the dspace-spring-rest/src/test/java/org/dspace/app/rest/test/AbstractControllerIntegrationTest.java |
@Frederic-Atmire and I implemented a solution for https://jira.duraspace.org/browse/DS-3651 and https://jira.duraspace.org/browse/DS-3527 (for bitstreams).
Frederic created a SAF archive you can import and use to test this PR:
bin/dspace registry-loader -bitstream config/registries/bitstream-formats.xml
bin/dspace import -a -s ~/Downloads/ -z DS-3651-SAF.zip -c 123465789/2 -m mapfile -e admin@mail.com
The SAF archive contains 3 items: one with a PDF, one with a MP4 file and one with a MP3 file. Each modern browser should open the files without problems. The MP4 and MP3 files should be downloaded by parts. You should also be able to jump within the media file to undownloaded sections.
Alternatively, you can also test using
curl
as illustrated in the integration tests or with a Download mananger that can pause and resume downloads.