Repository navigation
SOLR-18457: Migrate V2 /update endpoints to using JAX-RS #4177
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
base: main
Are you sure you want to change the base?
Changes from all commits
7b437c7
89fdf9d
863fbf1
f5e49ea
3b79fb8
014880c
3cc0acc
e40d417
92d70a8
74bdf15
6a675bf
4d2cbc0
7337062
b932cb2
055f200
296f33a
090749a
793eef0
9d87a15
3dab0ef
3ed21dd
6455c2e
6b32a74
cfb1d52
d11876f
162511f
d904bef
ec090e1
7523441
8723661
9b00cce
8971144
37d6f22
0f23c24
c783adb
ed6bc2c
3a96567
0337730
8fc4bef
1de44e5
acca0f3
ca2d06b
ac83841
ba5bb51
ddffebb
00ad6ef
675e724
8a51c10
3198bb2
4fe0bb2
576a0c7
ea3d27b
d681a31
054fc61
8afa6bd
b98bc2f
107a5a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| title: > | ||
| Migrated the v2 update endpoints to JAX-RS. The v2 javabin endpoint is now /update/javabin, | ||
| where v1 uses the shorter /update/bin. Migrated the Admin UI's document-upload screen to use | ||
| these v2 endpoints. That screen now only supports the /update endpoint; it can no longer target | ||
| a custom endpoint. As part of updating the examples in the Ref Guide, the bundled techproducts | ||
| example schema also changed: "price" and "popularity" are now docValues-only (no longer indexed | ||
| or stored), the "price_c" copyField from "price" was removed, and nested/child-document support | ||
| ("_nest_path_"/"_nest_parent_") was added. | ||
| type: changed | ||
| authors: | ||
| - name: Eric Pugh | ||
| links: | ||
| - name: SOLR-18457 | ||
| url: https://issues.apache.org/jira/browse/SOLR-18457 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You 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 org.apache.solr.client.api.endpoint; | ||
|
|
||
| import static org.apache.solr.client.api.util.Constants.GENERIC_ENTITY_PROPERTY; | ||
| import static org.apache.solr.client.api.util.Constants.INDEX_PATH_PREFIX; | ||
|
|
||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.Parameter; | ||
| import io.swagger.v3.oas.annotations.extensions.Extension; | ||
| import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; | ||
| import io.swagger.v3.oas.annotations.parameters.RequestBody; | ||
| import jakarta.ws.rs.Consumes; | ||
| import jakarta.ws.rs.POST; | ||
| import jakarta.ws.rs.Path; | ||
| import jakarta.ws.rs.QueryParam; | ||
| import java.io.InputStream; | ||
| import org.apache.solr.client.api.model.UpdateResponse; | ||
| import org.apache.solr.client.api.util.StoreApiParameters; | ||
|
|
||
| /** V2 API definitions for indexing documents via the update handler. */ | ||
| @Path(INDEX_PATH_PREFIX + "/update") | ||
| public interface UpdateApi { | ||
|
|
||
| @POST | ||
| @Consumes({ | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a big enhancement over the existing non JAX-RS appaoche, which required you to call /update/csv for cSV etc. Now we support content-types and you can access /update. |
||
| "application/json", | ||
| "text/json", | ||
| "application/xml", | ||
| "text/xml", | ||
| "application/csv", | ||
| "text/csv", | ||
| "application/javabin", | ||
| "application/cbor" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. v1 has a |
||
| }) | ||
| @StoreApiParameters | ||
| @Operation( | ||
| summary = "Send updates using any supported content type", | ||
| tags = {"update"}) | ||
| UpdateResponse update( | ||
| @Parameter(description = "Commit the update immediately") @QueryParam("commit") | ||
| Boolean commit, | ||
| @Parameter(description = "Commit the update within this many milliseconds") | ||
| @QueryParam("commitWithin") | ||
| Integer commitWithin, | ||
| @Parameter(description = "Overwrite documents with the same unique key") | ||
| @QueryParam("overwrite") | ||
| Boolean overwrite, | ||
| @Parameter(description = "Perform a soft commit") @QueryParam("softCommit") | ||
| Boolean softCommit, | ||
| @Parameter(description = "Include assigned document versions in the response") | ||
| @QueryParam("versions") | ||
| Boolean versions, | ||
| @Parameter(required = true) | ||
| @RequestBody( | ||
| required = true, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The generated SolrJ Java client can't call this -- The Java template hardcodes
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hate touching the mustache templates, but this one seems pretty clear cut: 8a51c10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Followup question - if our SolrJ classes use the generated Java client from these templates, do we have test coverage on those SolrJ classes that would have caught this. I guess we have no SolrJ test attempting cbor encoding, since cbor is for other client languages -- solrj has javabin.. |
||
| description = "Update content in the format selected by the Content-Type header.", | ||
| extensions = | ||
| @Extension( | ||
| properties = { | ||
| @ExtensionProperty(name = GENERIC_ENTITY_PROPERTY, value = "true") | ||
| })) | ||
| InputStream requestBody) | ||
| throws Exception; | ||
|
|
||
| @POST | ||
| @Path("/json") | ||
| @Consumes({"application/json", "text/json"}) | ||
| @StoreApiParameters | ||
| @Operation( | ||
| summary = "Index documents in JSON format", | ||
| tags = {"update"}) | ||
| UpdateResponse updateJson( | ||
| @Parameter(description = "Commit the update immediately") @QueryParam("commit") | ||
| Boolean commit, | ||
| @Parameter(description = "Commit the update within this many milliseconds") | ||
| @QueryParam("commitWithin") | ||
| Integer commitWithin, | ||
| @Parameter(description = "Overwrite documents with the same unique key") | ||
| @QueryParam("overwrite") | ||
| Boolean overwrite, | ||
| @Parameter(description = "Perform a soft commit") @QueryParam("softCommit") | ||
| Boolean softCommit, | ||
| @Parameter(description = "Include assigned document versions in the response") | ||
| @QueryParam("versions") | ||
| Boolean versions, | ||
| @Parameter(required = true) | ||
| @RequestBody( | ||
| required = true, | ||
| description = "JSON update content.", | ||
| extensions = | ||
| @Extension( | ||
| properties = { | ||
| @ExtensionProperty(name = GENERIC_ENTITY_PROPERTY, value = "true") | ||
| })) | ||
| InputStream requestBody) | ||
| throws Exception; | ||
|
|
||
| @POST | ||
| @Path("/xml") | ||
| @Consumes({"application/xml", "text/xml"}) | ||
| @StoreApiParameters | ||
| @Operation( | ||
| summary = "Index documents in XML format", | ||
| tags = {"update"}) | ||
| UpdateResponse updateXml( | ||
| @Parameter(description = "Commit the update immediately") @QueryParam("commit") | ||
| Boolean commit, | ||
| @Parameter(description = "Commit the update within this many milliseconds") | ||
| @QueryParam("commitWithin") | ||
| Integer commitWithin, | ||
| @Parameter(description = "Overwrite documents with the same unique key") | ||
| @QueryParam("overwrite") | ||
| Boolean overwrite, | ||
| @Parameter(description = "Perform a soft commit") @QueryParam("softCommit") | ||
| Boolean softCommit, | ||
| @Parameter(description = "Include assigned document versions in the response") | ||
| @QueryParam("versions") | ||
| Boolean versions, | ||
| @Parameter(required = true) | ||
| @RequestBody( | ||
| required = true, | ||
| description = "XML update content.", | ||
| extensions = | ||
| @Extension( | ||
| properties = { | ||
| @ExtensionProperty(name = GENERIC_ENTITY_PROPERTY, value = "true") | ||
| })) | ||
| InputStream requestBody) | ||
| throws Exception; | ||
|
|
||
| @POST | ||
| @Path("/csv") | ||
| @Consumes({"application/csv", "text/csv"}) | ||
| @StoreApiParameters | ||
| @Operation( | ||
| summary = "Index documents in CSV format", | ||
| tags = {"update"}) | ||
| UpdateResponse updateCsv( | ||
| @Parameter(description = "Commit the update immediately") @QueryParam("commit") | ||
| Boolean commit, | ||
| @Parameter(description = "Commit the update within this many milliseconds") | ||
| @QueryParam("commitWithin") | ||
| Integer commitWithin, | ||
| @Parameter(description = "Overwrite documents with the same unique key") | ||
| @QueryParam("overwrite") | ||
| Boolean overwrite, | ||
| @Parameter(description = "Perform a soft commit") @QueryParam("softCommit") | ||
| Boolean softCommit, | ||
| @Parameter(description = "Include assigned document versions in the response") | ||
| @QueryParam("versions") | ||
| Boolean versions, | ||
| @Parameter(required = true) | ||
| @RequestBody( | ||
| required = true, | ||
| description = "CSV update content.", | ||
| extensions = | ||
| @Extension( | ||
| properties = { | ||
| @ExtensionProperty(name = GENERIC_ENTITY_PROPERTY, value = "true") | ||
| })) | ||
| InputStream requestBody) | ||
| throws Exception; | ||
|
|
||
| @POST | ||
| @Path("/javabin") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i debated leaving this on /update/bin to mimic more closing v1... |
||
| @Consumes("application/javabin") | ||
| @StoreApiParameters | ||
| @Operation( | ||
| summary = "Index documents in Javabin format", | ||
| tags = {"update"}) | ||
| UpdateResponse updateJavabin( | ||
| @Parameter(description = "Commit the update immediately") @QueryParam("commit") | ||
| Boolean commit, | ||
| @Parameter(description = "Commit the update within this many milliseconds") | ||
| @QueryParam("commitWithin") | ||
| Integer commitWithin, | ||
| @Parameter(description = "Overwrite documents with the same unique key") | ||
| @QueryParam("overwrite") | ||
| Boolean overwrite, | ||
| @Parameter(description = "Perform a soft commit") @QueryParam("softCommit") | ||
| Boolean softCommit, | ||
| @Parameter(description = "Include assigned document versions in the response") | ||
| @QueryParam("versions") | ||
| Boolean versions, | ||
| @Parameter(required = true) | ||
| @RequestBody( | ||
| required = true, | ||
| description = "Javabin update content.", | ||
| extensions = | ||
| @Extension( | ||
| properties = { | ||
| @ExtensionProperty(name = GENERIC_ENTITY_PROPERTY, value = "true") | ||
| })) | ||
| InputStream requestBody) | ||
| throws Exception; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You 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 org.apache.solr.client.api.model; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| /** | ||
| * A single add/delete/delete-by-query that failed but was tolerated because the request's {@code | ||
| * maxErrors} allowed it. | ||
| */ | ||
| public class ToleratedUpdateError { | ||
|
|
||
| @JsonProperty("type") | ||
| @Schema(description = "The kind of command that failed, e.g. 'ADD', 'DELID', or 'DELQ'.") | ||
| public String type; | ||
|
|
||
| @JsonProperty("id") | ||
| @Schema(description = "The document id or delete-by-query expression that failed.") | ||
| public String id; | ||
|
|
||
| @JsonProperty("message") | ||
| @Schema(description = "The error message describing why the command failed.") | ||
| public String message; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You 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 org.apache.solr.client.api.model; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import java.util.List; | ||
|
|
||
| /** Version information returned by an update request with {@code versions=true}. */ | ||
| public class UpdateResponse extends SolrJerseyResponse { | ||
|
|
||
| @JsonProperty("adds") | ||
| @Schema(description = "Documents added and the versions assigned to them.") | ||
| public List<VersionedDocument> adds; | ||
|
|
||
| @JsonProperty("deletes") | ||
| @Schema(description = "Documents deleted and the versions assigned to their delete operations.") | ||
| public List<VersionedDocument> deletes; | ||
|
|
||
| @JsonProperty("deleteByQuery") | ||
| @Schema(description = "Delete-by-query operations and the versions assigned to them.") | ||
| public List<VersionedQuery> deleteByQuery; | ||
|
|
||
| @JsonProperty("errors") | ||
| @Schema( | ||
| description = | ||
| "Commands that failed but were tolerated because the request's maxErrors allowed it. " | ||
| + "Present only when the update chain includes a tolerant-update processor.") | ||
| public List<ToleratedUpdateError> errors; | ||
|
|
||
| @JsonProperty("maxErrors") | ||
| @Schema( | ||
| description = | ||
| "The effective maxErrors value used for this request; -1 means unlimited. Present only " | ||
| + "when the update chain includes a tolerant-update processor.") | ||
| public Integer maxErrors; | ||
|
|
||
| @JsonProperty("rf") | ||
| @Schema( | ||
| description = | ||
| "The replication factor actually achieved for this update. Present only in SolrCloud.") | ||
| public Integer rf; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You 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 org.apache.solr.client.api.model; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| /** A document identifier and the version assigned to an update operation. */ | ||
| public class VersionedDocument { | ||
|
|
||
| @JsonProperty("id") | ||
| @Schema(description = "The document's unique identifier.") | ||
| public String id; | ||
|
|
||
| @JsonProperty("version") | ||
| @Schema(description = "The version assigned to the operation.") | ||
| public long version; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You 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 org.apache.solr.client.api.model; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| /** A delete-by-query expression and the version assigned to the operation. */ | ||
| public class VersionedQuery { | ||
|
|
||
| @JsonProperty("query") | ||
| @Schema(description = "The delete-by-query expression.") | ||
| public String query; | ||
|
|
||
| @JsonProperty("version") | ||
| @Schema(description = "The version assigned to the operation.") | ||
| public long version; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -346,7 +346,7 @@ private void createCollection(CloudSolrClient cloudSolrClient, CreateParams para | |
| + " using the Configsets V2 API"); | ||
| var uploadReq = | ||
| new ConfigsetsApi.UploadConfigSet( | ||
| confName, new ByteArrayInputStream(Utils.zipDirectory(confPath))); | ||
| confName, new ByteArrayInputStream(Utils.zipDirectory(confPath)), "application/zip"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Constant instead of string? Either from Jetty or from JDK |
||
| uploadReq.process(cloudSolrClient); | ||
| } | ||
|
|
||
|
|
||
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.
Strict
@Consumesmeans JAX-RS returns 415 for anything else before the handler runs, soassume.content.type(UpdateRequestHandler:78) no longer works on v2 -- the old@EndPointversion accepted any type and let the handler resolve it. Worth deciding deliberately rather than losing it as a side effect.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.
Yeah, so the
update.contentTypefeels like some next level hacking? I am going to send you json, but I can't send a header to tell you it's json? Seems like we want to stick with how Jersey views the world as much as possible.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.
Agree,
update.contentTypeis not necessary to support in 2026, it was never a good idea with a solr-custom method of declaring content type. Let the request-param DIE, it is experimental anyway, right? :) Perfect for a spinoff JIRA/PR.