-
Notifications
You must be signed in to change notification settings - Fork 661
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
SOLR-16470: Create V2 equivalent of V1 Replication: Get files/{filePath} #2734
base: main
Are you sure you want to change the base?
Conversation
Hey @gerlowskija, should be the last API for SOLR-16470 whenever you get time to review. Thanks! |
Awesome - thanks @mlbiscoc . Sorry for the delay getting to this - took me awhile to catch back up after the travel last week. Reviewing now... |
@@ -68,6 +71,45 @@ public FileListResponse fetchFileList( | |||
return doFetchFileList(gen); | |||
} | |||
|
|||
@GET |
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 all correct and in line with the v2 APIs you did back in 2023 (PR #1620 PR #1704).
But we've made a slight tweak since then to support the OpenAPI code generation stuff. In short - we needed the JAX-RS annotations to live somewhere that gets compiled before "core", so that "core" can use all the nice generated code. We managed this by creating a new Gradle module - "api" - where the JAX-RS annotations live on interfaces. (Code in "core" can then implement those interfaces with methods containing the API logic).
Long story short - we'll want to do the same here. There's some instructions here that might be helpful. Though in your case most of the steps are already done - the pieces just need moved around a bit.
(Slightly my fault for not calling out more explicitly on SOLR-16470 that the setup had changed since your earlier commits, so I'm willing to make the necessary changes here. You may beat me to it, but if not I'll try and update this eventually.)
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.
Ah good to know. No worries though, I just got back from vacation so will find some bandwidth soon to make the necessary adjustments.
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'll leave you to it, but if you have any questions or get stuck, lmk and I'll try to help out!
(Hope you had a great vacation!)
@GET | ||
@Path("/files/{filePath}") | ||
@Produces({MediaType.TEXT_PLAIN, BINARY_CONTENT_TYPE_V2}) | ||
public String fetchFile( |
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 this really return a String
? Since it can return raw files I would've expected this to have to return InputStream
or Object
or something more generic in order to handle the potentially-binary content coming back?
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.
String
seems to work fine but if I remember correctly I wasn't sure what was a better return Object
. There is a higher level indexFetcher
test that seems to pass just with the string but let me do more digging.
Hey @gerlowskija made the changes but ended up kind of inflating this PR to support the OpenAPI code generation and moving files. Lmk if this went the right direction |
public class ReplicationFileResponse extends SolrJerseyResponse implements StreamingOutput { | ||
|
||
public StreamingOutput dfs; | ||
|
||
public ReplicationFileResponse(StreamingOutput stream) { | ||
this.dfs = stream; | ||
} | ||
|
||
@Override | ||
public void write(OutputStream outputStream) throws IOException, WebApplicationException { | ||
dfs.write(outputStream); | ||
} | ||
} |
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.
So instead of String, I found jax-rs supports StreamingOutput but the code generation didn't like how it compiled just returning StreamingOutput
without a SolrJerseyResponse
so I went with this approach for now. This might look a bit hacky, but wasn't sure what other ways. Maybe there is an obvious fix here but lmk if this is or isn't right.
Awesome! I see a lot of the increase comes from moving some of the other replication APIs ("list files", "get index version") from core over to the "api" module -- I've actually got another PR that takes a stab at some of those changes as well, so if we rebase one on top of the other, that should shrink this PR back down a good bit. Will take a crack at that shortly, and check back in when that's done! Very curious about the "StreamingOutput" type you found. I've used |
Alright, merged in the latest 'main' and synced it with the changes here. The only real change of note is that the interface file is now named 'ReplicationApis.java' (I went with the name on 'main' since it was already there. The merge conflicts were a bit hairy, so if anything other than that seems "off", it's likely a mistake so please point it out 😆 Hoping to dig into the StreamingOutput thing shortly - thanks @mlbiscoc ! |
Great, thanks Jason. Will go back through it and take a look at the merge soon. Also need to look that precommit failure… |
After a bit of reading, I agree with Matt that StreamingOutput seems to be the "preferred" approach. The best explanation I could find on "why" comes from this SO post. To summarize: StreamingOutput is easier for various JAX-RS supported interceptor hooks (MessageBodyWriter, ResponseFilter, etc.). The example given is an interceptor that implements gzip-encoding - apparently that's tough to do on an OutputStream, but easier in some way for JAX-RS to handle when wrapped as a 'StreamingOutput'. That said - supporting this type in our Java code-generation might take a bit more effort than we want to bite off here and now. The API should be fine as far as Javascript and Python clients are concerned, but the custom template we're using for Java makes that one a bit trickier. I'll exempt |
https://issues.apache.org/jira/browse/SOLR-16470
Description
Create a V2 equivalent API for the replication "GET files/{filePath}"
V1
/solr/{coreName}/replication?command=filecontent&file=_0_Lucene99_0.tmd&wt=filestream
V2
/api/cores/{coreName}/replication/files/{filePath}?dirType=file
Other sample requests
/api/cores/{coreName}/replication/files/./tlog.0000000000000000000?dirType=tlogFile
/api/cores/{coreName}/replication/files/./solrconfig.xml?dirType=cf
Solution
Moved getFileStream() logic into ReplicationAPIBase class and updated the V1 endpoint to use the CoreReplicationAPI class so that the ReplicationHandler can be deprecated in the future.
For the V2 api, made
dirType
a required parameters specifying what file directory (cf/tlogFile/file) to fetch a file from and better expressed the optional parameters that exist for the apioffset
compression
checksum
maxWriteMBPerSec
generation
Tests
Wrote new unit test in CoreReplicationAPITest class testFetchFile()
Checklist
Please review the following and check all that apply:
main
branch../gradlew check
.