-
Notifications
You must be signed in to change notification settings - Fork 682
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-17351: Decompose filestore "get file" API #3047
base: main
Are you sure you want to change the base?
SOLR-17351: Decompose filestore "get file" API #3047
Conversation
Tests pass
Identical to the pre-existing`/cluster/files/a/b.txt?meta=true`, but in its own endpoint. Does NOT remove the existing endpoint or switch tests over to use it, but we will want to do this eventually on `main`.
Identical to the pre-existing`/node/files/a/b.txt`, but in its own endpoint. Does NOT remove the existing endpoint or switch tests over to use it. Those can be handled in a separate commit to enable this one to be easily backported later to 9x if desired. This also doesn't enable codegen for the new API, though I think the blockers are sufficiently cleared up now to enable that if desired.
Still no modifications to use the API internally, or removal of the old endpoint, in order to ease backporting.
This should probably be pulled into a separate PR/branch, and modified to address all relevant endpoints and other loose ends of SOLR-17562.
TestDistribFileStore fails with the changes in this commit. The changes themselves are fine, but it fails because of a pre-existing *ahem* feature in SolrClient where SolrParams are encoded as form-params instead of query-params in some circumstances. I could probably hack around this for the moment (e.g. by using a builder setter to ensure 'getFrom' is sent as a true query param). But I've decided to halt progress on this branch and break some other pieces out into their own PRs, while I send some questions out to the community on this front.
Ensures v2 POST query-params aren't put in a 'form' body.
Still TODO: ref-guide updates, additional testing. |
Does this impact #3031 ? Since I am using |
That PR uses the Java interface, and not the HTTP APIs directly, so it should be fine afaict. |
@POST | ||
@Operation( | ||
summary = | ||
"Pushes a file to other nodes, or pulls a file from other nodes in the Solr cluster.", |
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 the fact that one thing does a push or pull suggest a issue to fix? https://en.wikipedia.org/wiki/List_of_Doctor_Dolittle_characters#Pushmi-Pullyu
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.
"Syncs a file via either pushing or pulling across the nodes in the Solr cluster." ???
String getFrom, | ||
@Parameter( | ||
description = | ||
"If true, triggers syncing for this file across all nodes in the filestore") |
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.
maybe it's own end point? Or, do we somehow eliminate the need for this?
it -> { | ||
try { | ||
InputStream inputStream = it.getInputStream(); | ||
if (inputStream != null) { |
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.
could this ever be null? wouldn't you have an exception instead?
return dirListingResponse; | ||
} | ||
|
||
// TODO Modify the filestore implementation itself to return this object, so conversion isn't |
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.
+1 to this
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 think i also ran into this in the schema designer
@@ -194,6 +301,48 @@ public SolrJerseyResponse deleteFile(String filePath, Boolean localDelete) { | |||
return response; | |||
} | |||
|
|||
@Override | |||
@PermissionName(PermissionNameProvider.Name.FILESTORE_WRITE_PERM) | |||
public SolrJerseyResponse executeFileStoreCommand(String path, String getFrom, Boolean sync) { |
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.
aren't we trying to get rid of the "command" pattern in our new APIs?
} catch (IOException e) { | ||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error getting file ", e); | ||
} | ||
ClusterFileStore.syncToAllNodes(fileStore, path); |
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've been a bit confused between NodeFileStore, ClusterFileStore, DistribFileStore ;-).
.collect(Collectors.toList()); | ||
directoryListingResponse.files = Collections.singletonMap(path, directoryContents); | ||
return directoryListingResponse; | ||
if (type == FileStore.FileType.NOFILE |
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 feels overly finicky logic.. why is it so hard to decide when to get metadata? What are we missing that doens't just make this simple. A thing has a meta thing. That should be the only way.
throw new SolrException( | ||
SolrException.ErrorCode.SERVER_ERROR, "Error reading file " + pathCopy); | ||
// User wants to get the "raw" file | ||
// TODO Should we be trying to json-ify otherwise "raw" files in this way? It seems like a |
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.
What is the use case FOR this? Do we have one right now?
@@ -173,7 +173,7 @@ public void uninstall(String packageName, String version) | |||
String.format(Locale.ROOT, "/package/%s/%s/%s", packageName, version, "manifest.json")); | |||
for (String filePath : filesToDelete) { | |||
DistribFileStore.deleteZKFileEntry(zkClient, filePath); | |||
String path = "/api/cluster/files" + filePath; | |||
String path = "/api/cluster/filestore/files" + filePath; |
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 like the more verbose path I think... Can a filestore have anything under than files? If not, what about just "/api/cluster/filestore"
@@ -115,7 +115,7 @@ openssl dgst -sha1 -sign my_key.pem runtimelibs.jar | openssl enc -base64 | sed | |||
+ | |||
[source, bash] | |||
---- | |||
curl --data-binary @runtimelibs.jar -X PUT http://localhost:8983/api/cluster/files/mypkg/1.0/myplugins.jar?sig=<signature-of-jar> | |||
curl --data-binary @runtimelibs.jar -X PUT http://localhost:8983/api/cluster/filestore/files/mypkg/1.0/myplugins.jar?sig=<signature-of-jar> |
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.
maybe drops the files
?
try { | ||
fileStore.syncToAllNodes(path); | ||
} catch (IOException e) { | ||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error getting file ", 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.
We don't know if we can blame the user
ByteBuffer filedata = null; | ||
try { | ||
final var fileRequest = new FileStoreApi.GetFile(path); | ||
final var client = coreContainer.getSolrClientCache().getHttpSolrClient(baseUrl); |
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 don't use the SolrClientCache for anything other than streaming expressions. I'm stamping out such usages here: https://issues.apache.org/jira/browse/SOLR-17630
I'm particularly surprised to see you removed a use of the new requestWithBaseUrl
.
https://issues.apache.org/jira/browse/SOLR-17351
Description
Solr's filestore "get file" API actually covers 4 or 5 distinct operations. Depending on provided query parameters, it can:
This makes the code for this endpoint somewhat complex. It also makes it hard to model and parse the response on the client side.
Solution
This PR splits up the "get file" endpoint into a number of different APIs. Specifically:
GET/api/cluster/filestore/metadata/some/path.txt
POST /api/cluster/filestore/commands
These divisions allow us to generate SolrRequest/SolrResponse classes representing these APIs, meaning that SolrJ users no longer need to use GenericSolrRequest/GenericSolrResponse.
Tests
Some rewriting in TestDistribFileStore. Existing package and filestore tests continue to pass.
Checklist
Please review the following and check all that apply:
main
branch../gradlew check
.