diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py index 50b517aae59..554c664559d 100755 --- a/dev-tools/scripts/smokeTestRelease.py +++ b/dev-tools/scripts/smokeTestRelease.py @@ -606,7 +606,7 @@ def verifyUnpacked(java, artifact, unpackPath, gitRevision, version, testArgs): expected_src_root_folders = ['buildSrc', 'dev-docs', 'dev-tools', 'gradle', 'help', 'solr'] expected_src_root_files = ['build.gradle', 'gradlew', 'gradlew.bat', 'settings.gradle', 'versions.lock', 'versions.props'] expected_src_solr_files = ['build.gradle'] - expected_src_solr_folders = ['benchmark', 'bin', 'modules', 'core', 'docker', 'documentation', 'example', 'licenses', 'packaging', 'distribution', 'prometheus-exporter', 'server', 'solr-ref-guide', 'solrj', 'solrj-streaming', 'solrj-zookeeper', 'test-framework', 'webapp', '.gitignore', '.gitattributes'] + expected_src_solr_folders = ['benchmark', 'bin', 'modules', 'api', 'core', 'docker', 'documentation', 'example', 'licenses', 'packaging', 'distribution', 'prometheus-exporter', 'server', 'solr-ref-guide', 'solrj', 'solrj-streaming', 'solrj-zookeeper', 'test-framework', 'webapp', '.gitignore', '.gitattributes'] is_in_list(in_root_folder, expected_src_root_folders) is_in_list(in_root_folder, expected_src_root_files) is_in_list(in_solr_folder, expected_src_solr_folders) diff --git a/gradle/maven/defaults-maven.gradle b/gradle/maven/defaults-maven.gradle index 936de2c0988..8d0ef8f2a43 100644 --- a/gradle/maven/defaults-maven.gradle +++ b/gradle/maven/defaults-maven.gradle @@ -24,6 +24,7 @@ configure(rootProject) { ext { published = [ + ":solr:api", ":solr:core", ":solr:solrj", ":solr:solrj-streaming", diff --git a/gradle/solr/packaging.gradle b/gradle/solr/packaging.gradle index b1993ab8194..bb3fd5703ab 100644 --- a/gradle/solr/packaging.gradle +++ b/gradle/solr/packaging.gradle @@ -58,6 +58,7 @@ configure(allprojects.findAll {project -> project.path.startsWith(":solr:modules dependencies { solrPlatformLibs project(":solr:core") solrPlatformLibs project(":solr:solrj") + solrPlatformLibs project(":solr:api") solrPlatformLibs project(":solr:solrj-zookeeper") // libExt has logging libs, which we don't want. Lets users decide what they want. solrPlatformLibs project(path: ":solr:server", configuration: 'libExt') diff --git a/gradle/validation/spotless.gradle b/gradle/validation/spotless.gradle index 3239ac4b1a3..a8cb41e0f39 100644 --- a/gradle/validation/spotless.gradle +++ b/gradle/validation/spotless.gradle @@ -26,18 +26,32 @@ configure(project(":solr").subprojects) { prj -> plugins.withType(JavaPlugin) { prj.apply plugin: 'com.diffplug.spotless' - spotless { - java { - toggleOffOn() // obviously, only to be used sparingly. + ext { + spotlessJavaSetup = (Action){ + it.toggleOffOn() // obviously, only to be used sparingly. // TODO: Work out how to support multiple different header files (we have // classes in the codebase that have original headers). We currently use // Apache RAT to enforce headers so this is of lesser priority. // - // licenseHeaderFile file("${resources}/asl-header.txt"), '^(\\s*package)' + // it.licenseHeaderFile(file("${resources}/asl-header.txt"), '^(\\s*package)') + it.setLineEndings(Enum.valueOf(rootProject.buildscript.classLoader.loadClass("com.diffplug.spotless.LineEnding"), "UNIX")) + it.endWithNewline() + it.googleJavaFormat('1.15.0') - lineEndings 'UNIX' - endWithNewline() - googleJavaFormat('1.15.0') + it.custom('Refuse wildcard imports', { line -> + // Wildcard imports can't be resolved by spotless itself. + // This will require the developer themselves to adhere to best practices. + if (line =~ /\nimport .*\*;/) { + throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") + } + line + }) + } + } + + spotless { + java { + prj.ext.spotlessJavaSetup.execute(it) // Apply to all Java sources target "src/**/*.java" @@ -62,14 +76,6 @@ configure(project(":solr").subprojects) { prj -> target "modules/**/examples/*.java" break } - - custom 'Refuse wildcard imports', { - // Wildcard imports can't be resolved by spotless itself. - // This will require the developer themselves to adhere to best practices. - if (it =~ /\nimport .*\*;/) { - throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") - } - } } } diff --git a/settings.gradle b/settings.gradle index 65235015950..f0a1ff11538 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,6 +26,7 @@ rootProject.name = "solr-root" includeBuild("dev-tools/solr-missing-doclet") +include "solr:api" include "solr:solrj" include "solr:solrj-zookeeper" include "solr:solrj-streaming" diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index b4c7f498832..bbc85e009f4 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -84,6 +84,11 @@ Improvements a HTTP 503 status. Switched to 510 so that CloudSolrClient will auto-retry it and probably succeed. (David Smiley, Alex Deparvu) +* SOLR-16825: Solr now offers `SolrRequest` implementations for a subset of its v2 APIs. These implementations + are experimental and should be used with caution, but may be preferable to their v1 counterparts in some + circumstances as they are generated and more likely to remain up-to-date with future API changes. + (Jason Gerlowski, David Smiley, Houston Putman) + Optimizations --------------------- diff --git a/solr/api/build.gradle b/solr/api/build.gradle new file mode 100644 index 00000000000..f61977993af --- /dev/null +++ b/solr/api/build.gradle @@ -0,0 +1,61 @@ +/* + * 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. + */ + +plugins { + id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.2' +} + +apply plugin: 'java-library' + +description = 'API - Interfaces and classes used to represent Solrs APIs' + +ext { + openApiSpecDir = "${buildDir}/generated/openapi" + openApiSpecFile = "${project.openApiSpecDir}/openapi.json" +} + +configurations { + openapiSpec { + canBeConsumed = true + canBeResolved = false + } +} + +resolve { + classpath = sourceSets.main.runtimeClasspath + outputDir = file(project.openApiSpecDir) + prettyPrint = true +} + +dependencies { + runtimeOnly 'org.slf4j:slf4j-api' + + implementation 'jakarta.ws.rs:jakarta.ws.rs-api' + implementation 'com.fasterxml.jackson.core:jackson-annotations' + api 'io.swagger.core.v3:swagger-annotations' + implementation 'org.semver4j:semver4j' + + testImplementation project(':solr:test-framework') + testImplementation project(':solr:api') + testImplementation 'org.apache.lucene:lucene-test-framework' +} + +artifacts { + openapiSpec resolve.outputDir, { + builtBy resolve + } +} diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/AddReplicaPropertyApi.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/AddReplicaPropertyApi.java new file mode 100644 index 00000000000..d29ee057502 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/AddReplicaPropertyApi.java @@ -0,0 +1,60 @@ +/* + * 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.BINARY_CONTENT_TYPE_V2; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.AddReplicaPropertyRequestBody; +import org.apache.solr.client.api.model.SolrJerseyResponse; + +@Path("/collections/{collName}/shards/{shardName}/replicas/{replicaName}/properties/{propName}") +public interface AddReplicaPropertyApi { + + @PUT + @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2}) + @Operation( + summary = "Adds a property to the specified replica", + tags = {"replicas"}) + public SolrJerseyResponse addReplicaProperty( + @Parameter( + description = "The name of the collection the replica belongs to.", + required = true) + @PathParam("collName") + String collName, + @Parameter(description = "The name of the shard the replica belongs to.", required = true) + @PathParam("shardName") + String shardName, + @Parameter(description = "The replica, e.g., `core_node1`.", required = true) + @PathParam("replicaName") + String replicaName, + @Parameter(description = "The name of the property to add.", required = true) + @PathParam("propName") + String propertyName, + @RequestBody( + description = "The value of the replica property to create or update", + required = true) + AddReplicaPropertyRequestBody requestBody) + throws Exception; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/DeleteAliasApi.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/DeleteAliasApi.java new file mode 100644 index 00000000000..24759ead2ad --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/DeleteAliasApi.java @@ -0,0 +1,45 @@ +/* + * 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.BINARY_CONTENT_TYPE_V2; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import javax.ws.rs.DELETE; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.SolrJerseyResponse; + +@Path("/aliases/{aliasName}") +public interface DeleteAliasApi { + + @DELETE + @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2}) + @Operation( + summary = "Deletes an alias by its name", + tags = {"aliases"}) + SolrJerseyResponse deleteAlias( + @Parameter(description = "The name of the alias to delete", required = true) + @PathParam("aliasName") + String aliasName, + @QueryParam("async") String asyncId) + throws Exception; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/DeleteCollectionApi.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/DeleteCollectionApi.java new file mode 100644 index 00000000000..9e28e7b1722 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/DeleteCollectionApi.java @@ -0,0 +1,47 @@ +/* + * 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.BINARY_CONTENT_TYPE_V2; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import javax.ws.rs.DELETE; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; + +@Path("/collections/{collectionName}") +public interface DeleteCollectionApi { + + @DELETE + @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2}) + @Operation( + summary = "Deletes a collection from SolrCloud", + tags = {"collections"}) + SubResponseAccumulatingJerseyResponse deleteCollection( + @Parameter(description = "The name of the collection to be deleted.", required = true) + @PathParam("collectionName") + String collectionName, + @QueryParam("followAliases") Boolean followAliases, + @Parameter(description = "An ID to track the request asynchronously") @QueryParam("async") + String asyncId) + throws Exception; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/package-info.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/package-info.java new file mode 100644 index 00000000000..377e217fda9 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/package-info.java @@ -0,0 +1,19 @@ +/* + * 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. + */ + +/** Interfaces representing individual Solr v2 APIs. */ +package org.apache.solr.client.api.endpoint; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/AddReplicaPropertyRequestBody.java b/solr/api/src/java/org/apache/solr/client/api/model/AddReplicaPropertyRequestBody.java new file mode 100644 index 00000000000..f78c7bebd9c --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/AddReplicaPropertyRequestBody.java @@ -0,0 +1,41 @@ +/* + * 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 org.apache.solr.client.api.util.ReflectWritable; + +public class AddReplicaPropertyRequestBody implements ReflectWritable { + public AddReplicaPropertyRequestBody() {} + + public AddReplicaPropertyRequestBody(String value) { + this.value = value; + } + + @Schema(description = "The value to assign to the property.", required = true) + @JsonProperty("value") + public String value; + + @Schema( + description = + "If `true`, then setting this property in one replica will remove the property from all other replicas in that shard. The default is `false`.\\nThere is one pre-defined property `preferredLeader` for which `shardUnique` is forced to `true` and an error returned if `shardUnique` is explicitly set to `false`.", + defaultValue = "false") + @JsonProperty("shardUnique") + public Boolean shardUnique; +} diff --git a/solr/core/src/java/org/apache/solr/jersey/AsyncJerseyResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/AsyncJerseyResponse.java similarity index 95% rename from solr/core/src/java/org/apache/solr/jersey/AsyncJerseyResponse.java rename to solr/api/src/java/org/apache/solr/client/api/model/AsyncJerseyResponse.java index af08d227172..08651598d9d 100644 --- a/solr/core/src/java/org/apache/solr/jersey/AsyncJerseyResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/AsyncJerseyResponse.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.solr.jersey; +package org.apache.solr.client.api.model; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/solr/core/src/java/org/apache/solr/jersey/ErrorInfo.java b/solr/api/src/java/org/apache/solr/client/api/model/ErrorInfo.java similarity index 74% rename from solr/core/src/java/org/apache/solr/jersey/ErrorInfo.java rename to solr/api/src/java/org/apache/solr/client/api/model/ErrorInfo.java index 24ca06d64ff..1a6ca071642 100644 --- a/solr/core/src/java/org/apache/solr/jersey/ErrorInfo.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/ErrorInfo.java @@ -6,7 +6,7 @@ * (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 + * 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, @@ -15,19 +15,23 @@ * limitations under the License. */ -package org.apache.solr.jersey; +package org.apache.solr.client.api.model; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import java.util.Map; -import org.apache.solr.common.SolrException; +import org.apache.solr.client.api.util.ReflectWritable; /** * A value type representing an error. * *

Based on the fields exposed in responses from Solr's v1/requestHandler API. */ -public class ErrorInfo implements JacksonReflectMapWriter { +public class ErrorInfo implements ReflectWritable { + + public static final String ROOT_ERROR_CLASS = "root-error-class"; + public static final String ERROR_CLASS = "error-class"; + @JsonProperty("metadata") public ErrorMetadata metadata; @@ -43,11 +47,11 @@ public class ErrorInfo implements JacksonReflectMapWriter { @JsonProperty("code") public Integer code; - public static class ErrorMetadata implements JacksonReflectMapWriter { - @JsonProperty(SolrException.ERROR_CLASS) + public static class ErrorMetadata implements ReflectWritable { + @JsonProperty(ERROR_CLASS) public String errorClass; - @JsonProperty(SolrException.ROOT_ERROR_CLASS) + @JsonProperty(ROOT_ERROR_CLASS) public String rootErrorClass; } } diff --git a/solr/core/src/java/org/apache/solr/jersey/SolrJerseyResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/SolrJerseyResponse.java similarity index 86% rename from solr/core/src/java/org/apache/solr/jersey/SolrJerseyResponse.java rename to solr/api/src/java/org/apache/solr/client/api/model/SolrJerseyResponse.java index 770fc1eec53..59e528c91f8 100644 --- a/solr/core/src/java/org/apache/solr/jersey/SolrJerseyResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/SolrJerseyResponse.java @@ -6,7 +6,7 @@ * (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 + * 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, @@ -15,13 +15,14 @@ * limitations under the License. */ -package org.apache.solr.jersey; +package org.apache.solr.client.api.model; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.HashMap; import java.util.Map; +import org.apache.solr.client.api.util.ReflectWritable; /** * Base response-body POJO to be used by Jersey resources. @@ -29,7 +30,7 @@ *

Contains fields common to all Solr API responses, particularly the 'responseHeader' and * 'error' fields. */ -public class SolrJerseyResponse implements JacksonReflectMapWriter { +public class SolrJerseyResponse implements ReflectWritable { @JsonProperty("responseHeader") public ResponseHeader responseHeader = new ResponseHeader(); @@ -37,7 +38,7 @@ public class SolrJerseyResponse implements JacksonReflectMapWriter { @JsonProperty("error") public ErrorInfo error; - public static class ResponseHeader implements JacksonReflectMapWriter { + public static class ResponseHeader implements ReflectWritable { @JsonProperty("status") public int status; diff --git a/solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java b/solr/api/src/java/org/apache/solr/client/api/model/SubResponseAccumulatingJerseyResponse.java similarity index 98% rename from solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java rename to solr/api/src/java/org/apache/solr/client/api/model/SubResponseAccumulatingJerseyResponse.java index a0f0dbfb0e2..5031f86c3a5 100644 --- a/solr/core/src/java/org/apache/solr/jersey/SubResponseAccumulatingJerseyResponse.java +++ b/solr/api/src/java/org/apache/solr/client/api/model/SubResponseAccumulatingJerseyResponse.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.solr.jersey; +package org.apache.solr.client.api.model; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/solr/api/src/java/org/apache/solr/client/api/model/package-info.java b/solr/api/src/java/org/apache/solr/client/api/model/package-info.java new file mode 100644 index 00000000000..4264373269c --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/model/package-info.java @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/** + * POJOs representing various inputs and outputs of the v2 APIs described in {@link + * org.apache.solr.client.api.endpoint} + */ +package org.apache.solr.client.api.model; diff --git a/solr/api/src/java/org/apache/solr/client/api/package-info.java b/solr/api/src/java/org/apache/solr/client/api/package-info.java new file mode 100644 index 00000000000..aa44ba957da --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/package-info.java @@ -0,0 +1,19 @@ +/* + * 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. + */ + +/** Root package for interfaces and POJOs used to describe Solr's v2 APIs */ +package org.apache.solr.client.api; diff --git a/solr/api/src/java/org/apache/solr/client/api/util/ApiMetadata.java b/solr/api/src/java/org/apache/solr/client/api/util/ApiMetadata.java new file mode 100644 index 00000000000..11a70a916d3 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/util/ApiMetadata.java @@ -0,0 +1,31 @@ +/* + * 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.util; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.info.License; + +@OpenAPIDefinition( + info = + @Info( + title = "v2 API", + description = "OpenAPI spec for Solr's v2 API endpoints", + license = @License(name = "ASL 2.0"), + version = SolrVersion.LATEST_STRING)) +public class ApiMetadata {} diff --git a/solr/api/src/java/org/apache/solr/client/api/util/Constants.java b/solr/api/src/java/org/apache/solr/client/api/util/Constants.java new file mode 100644 index 00000000000..1dbd6e61a6c --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/util/Constants.java @@ -0,0 +1,26 @@ +/* + * 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.util; + +public class Constants { + private Constants() { + /* Private ctor prevents instantiation */ + } + + public static final String BINARY_CONTENT_TYPE_V2 = "application/vnd.apache.solr.javabin"; +} diff --git a/solr/api/src/java/org/apache/solr/client/api/util/ReflectWritable.java b/solr/api/src/java/org/apache/solr/client/api/util/ReflectWritable.java new file mode 100644 index 00000000000..bad94276747 --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/util/ReflectWritable.java @@ -0,0 +1,27 @@ +/* + * 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.util; + +/** + * A marker interface used by v2 POJOs to indicate they contain annotations that can be written out + * via reflection. + * + *

Used primarily by custom serialization/deserialization codepaths that don't natively recognize + * (e.g.) Jackson annotations. + */ +public interface ReflectWritable {} diff --git a/solr/core/src/java/org/apache/solr/util/SolrVersion.java b/solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java similarity index 90% rename from solr/core/src/java/org/apache/solr/util/SolrVersion.java rename to solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java index 6661e9e891c..434bbea9596 100644 --- a/solr/core/src/java/org/apache/solr/util/SolrVersion.java +++ b/solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java @@ -14,10 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.solr.util; +package org.apache.solr.client.api.util; import java.util.Locale; -import org.apache.solr.common.SolrException; import org.semver4j.Semver; /** @@ -45,6 +44,14 @@ public static SolrVersion forIntegers(int major, int minor, int patch) { return new SolrVersion(new Semver(String.format(Locale.ROOT, "%d.%d.%d", major, minor, patch))); } + /** + * Compares two versions v1 and v2. Returns negative if v1 isLessThan v2, positive if v1 + * isGreaterThan v2 and 0 if equal. + */ + public static int compareVersions(String v1, String v2) { + return new Semver(v1).compareTo(new Semver(v2)); + } + /** Return version as plain SemVer string, e.g. "9.0.1" */ @Override public String toString() { @@ -118,13 +125,4 @@ public boolean equals(Object other) { } return compareTo((SolrVersion) other) == 0; } - - public static class InvalidSemVerExpressionException extends SolrException { - public InvalidSemVerExpressionException(Exception exception, String expression) { - super( - ErrorCode.BAD_REQUEST, - String.format(Locale.ROOT, "Invalid SemVer expression: %s", expression), - exception); - } - } } diff --git a/solr/api/src/java/org/apache/solr/client/api/util/package-info.java b/solr/api/src/java/org/apache/solr/client/api/util/package-info.java new file mode 100644 index 00000000000..c7634ce945c --- /dev/null +++ b/solr/api/src/java/org/apache/solr/client/api/util/package-info.java @@ -0,0 +1,19 @@ +/* + * 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. + */ + +/** Utilities for working with Solr api interfaces and model classes. */ +package org.apache.solr.client.api.util; diff --git a/solr/core/src/test/org/apache/solr/util/TestSolrVersion.java b/solr/api/src/test/org/apache/solr/util/TestSolrVersion.java similarity index 97% rename from solr/core/src/test/org/apache/solr/util/TestSolrVersion.java rename to solr/api/src/test/org/apache/solr/util/TestSolrVersion.java index 1a43e7cab71..ff55514e4ab 100644 --- a/solr/core/src/test/org/apache/solr/util/TestSolrVersion.java +++ b/solr/api/src/test/org/apache/solr/util/TestSolrVersion.java @@ -17,6 +17,7 @@ package org.apache.solr.util; import org.apache.solr.SolrTestCase; +import org.apache.solr.client.api.util.SolrVersion; import org.semver4j.SemverException; public class TestSolrVersion extends SolrTestCase { diff --git a/solr/core/build.gradle b/solr/core/build.gradle index 83f48e2f223..d868164cd75 100644 --- a/solr/core/build.gradle +++ b/solr/core/build.gradle @@ -15,20 +15,10 @@ * limitations under the License. */ -plugins { - id 'io.swagger.core.v3.swagger-gradle-plugin' version '2.2.2' -} - apply plugin: 'java-library' description = 'Apache Solr Core' -resolve { - classpath = sourceSets.main.runtimeClasspath - outputDir = file("build/generated/openapi") - prettyPrint = true -} - dependencies { // Spotbugs Annotations are only needed for old findbugs // annotation usage like in Zookeeper during compilation time. @@ -54,6 +44,7 @@ dependencies { // We export logging api with dependencies, which is useful for all modules api 'org.slf4j:slf4j-api' + api project(':solr:api') api project(':solr:solrj') api project(':solr:solrj-zookeeper') api project(':solr:solrj-streaming') @@ -142,9 +133,6 @@ dependencies { // required for instantiating a Zookeeper server (for embedding ZK or running tests) runtimeOnly ('org.xerial.snappy:snappy-java') - // For Package Manager - implementation 'org.semver4j:semver4j' - implementation('com.jayway.jsonpath:json-path', { exclude group: "net.minidev", module: "json-smart" }) diff --git a/solr/core/src/java/org/apache/solr/api/JerseyResource.java b/solr/core/src/java/org/apache/solr/api/JerseyResource.java index e96216e170e..6a304654e27 100644 --- a/solr/core/src/java/org/apache/solr/api/JerseyResource.java +++ b/solr/core/src/java/org/apache/solr/api/JerseyResource.java @@ -22,9 +22,9 @@ import java.util.function.Supplier; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.core.Context; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.jersey.CatchAllExceptionMapper; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.servlet.HttpSolrCall; /** diff --git a/solr/core/src/java/org/apache/solr/cli/SimplePostTool.java b/solr/core/src/java/org/apache/solr/cli/SimplePostTool.java index 11478366711..d15650e1636 100644 --- a/solr/core/src/java/org/apache/solr/cli/SimplePostTool.java +++ b/solr/core/src/java/org/apache/solr/cli/SimplePostTool.java @@ -65,9 +65,9 @@ import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.apache.solr.client.api.util.SolrVersion; import org.apache.solr.common.util.Utils; import org.apache.solr.util.RTimer; -import org.apache.solr.util.SolrVersion; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; diff --git a/solr/core/src/java/org/apache/solr/cli/VersionTool.java b/solr/core/src/java/org/apache/solr/cli/VersionTool.java index 1b0e1fa4644..f5e84e6c1f8 100644 --- a/solr/core/src/java/org/apache/solr/cli/VersionTool.java +++ b/solr/core/src/java/org/apache/solr/cli/VersionTool.java @@ -21,7 +21,7 @@ import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; -import org.apache.solr.util.SolrVersion; +import org.apache.solr.client.api.util.SolrVersion; public class VersionTool extends ToolBase { diff --git a/solr/core/src/java/org/apache/solr/handler/IncrementalShardBackup.java b/solr/core/src/java/org/apache/solr/handler/IncrementalShardBackup.java index 74128375ad0..c4de4807588 100644 --- a/solr/core/src/java/org/apache/solr/handler/IncrementalShardBackup.java +++ b/solr/core/src/java/org/apache/solr/handler/IncrementalShardBackup.java @@ -29,6 +29,7 @@ import org.apache.commons.math3.util.Precision; import org.apache.lucene.index.IndexCommit; import org.apache.lucene.store.Directory; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.common.SolrException; import org.apache.solr.core.DirectoryFactory; @@ -39,7 +40,6 @@ import org.apache.solr.core.backup.ShardBackupId; import org.apache.solr.core.backup.ShardBackupMetadata; import org.apache.solr.core.backup.repository.BackupRepository; -import org.apache.solr.jersey.SolrJerseyResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java index f49ef231f9e..9f6d09bab22 100644 --- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -66,6 +66,7 @@ import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.RateLimiter; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.params.CommonParams; @@ -91,7 +92,6 @@ import org.apache.solr.handler.IndexFetcher.IndexFetchResult; import org.apache.solr.handler.admin.api.CoreReplicationAPI; import org.apache.solr.handler.api.V2ApiUtils; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.metrics.MetricsMap; import org.apache.solr.metrics.SolrMetricsContext; import org.apache.solr.request.SolrQueryRequest; diff --git a/solr/core/src/java/org/apache/solr/handler/SnapShooter.java b/solr/core/src/java/org/apache/solr/handler/SnapShooter.java index 184d2aeb0c2..4f2beb51983 100644 --- a/solr/core/src/java/org/apache/solr/handler/SnapShooter.java +++ b/solr/core/src/java/org/apache/solr/handler/SnapShooter.java @@ -35,6 +35,7 @@ import java.util.function.Consumer; import org.apache.lucene.index.IndexCommit; import org.apache.lucene.store.Directory; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.util.NamedList; @@ -47,7 +48,6 @@ import org.apache.solr.core.backup.repository.LocalFileSystemRepository; import org.apache.solr.core.snapshots.SolrSnapshotMetaDataManager; import org.apache.solr.handler.api.V2ApiUtils; -import org.apache.solr.jersey.SolrJerseyResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java b/solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java index 2f5407416c4..bfd939c43b4 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/BackupCoreOp.java @@ -25,7 +25,6 @@ import org.apache.solr.core.backup.ShardBackupId; import org.apache.solr.handler.admin.api.BackupCoreAPI; import org.apache.solr.handler.api.V2ApiUtils; -import org.apache.solr.jersey.SolrJerseyResponse; class BackupCoreOp implements CoreAdminHandler.CoreAdminOp { @@ -53,7 +52,7 @@ public void execute(CoreAdminHandler.CallInfo it) throws Exception { new BackupCoreAPI( it.handler.coreContainer, it.req, it.rsp, it.handler.coreAdminAsyncTracker); try { - SolrJerseyResponse response = backupCoreAPI.createBackup(cname, backupCoreRequestBody); + final var response = backupCoreAPI.createBackup(cname, backupCoreRequestBody); NamedList namedList = new SimpleOrderedMap<>(); V2ApiUtils.squashIntoNamedListWithoutHeader(namedList, response); it.rsp.addResponse(namedList); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java index 23a0d094ed6..4b63e0c5138 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java @@ -122,6 +122,8 @@ import org.apache.solr.api.AnnotatedApi; import org.apache.solr.api.Api; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.AddReplicaPropertyRequestBody; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.response.RequestStatusState; @@ -160,7 +162,7 @@ import org.apache.solr.core.snapshots.CollectionSnapshotMetaData; import org.apache.solr.core.snapshots.SolrSnapshotManager; import org.apache.solr.handler.RequestHandlerBase; -import org.apache.solr.handler.admin.api.AddReplicaPropertyAPI; +import org.apache.solr.handler.admin.api.AddReplicaProperty; import org.apache.solr.handler.admin.api.AdminAPIBase; import org.apache.solr.handler.admin.api.AliasPropertyAPI; import org.apache.solr.handler.admin.api.BalanceReplicasAPI; @@ -173,8 +175,8 @@ import org.apache.solr.handler.admin.api.CreateCollectionSnapshotAPI; import org.apache.solr.handler.admin.api.CreateReplicaAPI; import org.apache.solr.handler.admin.api.CreateShardAPI; -import org.apache.solr.handler.admin.api.DeleteAliasAPI; -import org.apache.solr.handler.admin.api.DeleteCollectionAPI; +import org.apache.solr.handler.admin.api.DeleteAlias; +import org.apache.solr.handler.admin.api.DeleteCollection; import org.apache.solr.handler.admin.api.DeleteCollectionBackupAPI; import org.apache.solr.handler.admin.api.DeleteCollectionSnapshotAPI; import org.apache.solr.handler.admin.api.DeleteNodeAPI; @@ -199,7 +201,6 @@ import org.apache.solr.handler.admin.api.SplitShardAPI; import org.apache.solr.handler.admin.api.SyncShardAPI; import org.apache.solr.handler.api.V2ApiUtils; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.logging.MDCLoggingContext; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; @@ -543,8 +544,8 @@ public enum CollectionOperation implements CollectionOp { DELETE, (req, rsp, h) -> { final RequiredSolrParams requiredParams = req.getParams().required(); - final DeleteCollectionAPI deleteCollectionAPI = - new DeleteCollectionAPI(h.coreContainer, req, rsp); + final DeleteCollection deleteCollectionAPI = + new DeleteCollection(h.coreContainer, req, rsp); final SolrJerseyResponse deleteCollResponse = deleteCollectionAPI.deleteCollection( requiredParams.get(NAME), @@ -623,7 +624,7 @@ public enum CollectionOperation implements CollectionOp { DELETEALIAS_OP( DELETEALIAS, (req, rsp, h) -> { - final DeleteAliasAPI deleteAliasAPI = new DeleteAliasAPI(h.coreContainer, req, rsp); + final DeleteAlias deleteAliasAPI = new DeleteAlias(h.coreContainer, req, rsp); final SolrJerseyResponse response = deleteAliasAPI.deleteAlias( req.getParams().required().get(NAME), req.getParams().get(ASYNC)); @@ -988,8 +989,7 @@ public Map execute( ADDREPLICAPROP, (req, rsp, h) -> { final RequiredSolrParams requiredParams = req.getParams().required(); - final AddReplicaPropertyAPI.AddReplicaPropertyRequestBody requestBody = - new AddReplicaPropertyAPI.AddReplicaPropertyRequestBody(); + final var requestBody = new AddReplicaPropertyRequestBody(); requestBody.value = requiredParams.get(PROPERTY_VALUE_PROP); requestBody.shardUnique = req.getParams().getBool(SHARD_UNIQUE); final String propName = requiredParams.get(PROPERTY_PROP); @@ -998,8 +998,8 @@ public Map execute( ? propName.substring(PROPERTY_PREFIX.length()) : propName; - final AddReplicaPropertyAPI addReplicaPropertyAPI = - new AddReplicaPropertyAPI(h.coreContainer, req, rsp); + final AddReplicaProperty addReplicaPropertyAPI = + new AddReplicaProperty(h.coreContainer, req, rsp); final SolrJerseyResponse addReplicaPropResponse = addReplicaPropertyAPI.addReplicaProperty( requiredParams.get(COLLECTION_PROP), @@ -1364,15 +1364,15 @@ public Boolean registerV2() { public Collection> getJerseyResources() { return List.of( CreateReplicaAPI.class, - AddReplicaPropertyAPI.class, + AddReplicaProperty.class, BalanceShardUniqueAPI.class, CreateAliasAPI.class, CreateCollectionAPI.class, CreateCollectionBackupAPI.class, CreateShardAPI.class, - DeleteAliasAPI.class, + DeleteAlias.class, DeleteCollectionBackupAPI.class, - DeleteCollectionAPI.class, + DeleteCollection.class, DeleteReplicaAPI.class, DeleteReplicaPropertyAPI.class, DeleteShardAPI.class, diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperReadAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperReadAPI.java index a56c5b7deed..c2f244e93d8 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperReadAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperReadAPI.java @@ -36,6 +36,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.impl.BinaryResponseParser; import org.apache.solr.client.solrj.impl.XMLResponseParser; import org.apache.solr.common.SolrException; @@ -47,7 +48,6 @@ import org.apache.solr.jersey.ExperimentalResponse; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.RawResponseWriter; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaProperty.java similarity index 68% rename from solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java rename to solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaProperty.java index 30936638ce5..c3f29f90b00 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaPropertyAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/AddReplicaProperty.java @@ -16,7 +16,6 @@ */ package org.apache.solr.handler.admin.api; -import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2; import static org.apache.solr.cloud.Overseer.QUEUE_OPERATION; import static org.apache.solr.cloud.api.collections.CollectionHandlingUtils.SHARD_UNIQUE; import static org.apache.solr.common.cloud.ZkStateReader.COLLECTION_PROP; @@ -28,18 +27,13 @@ import static org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT; import static org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.parameters.RequestBody; import java.util.HashMap; import java.util.Locale; import java.util.Map; import javax.inject.Inject; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; +import org.apache.solr.client.api.endpoint.AddReplicaPropertyApi; +import org.apache.solr.client.api.model.AddReplicaPropertyRequestBody; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.cloud.overseer.SliceMutator; import org.apache.solr.common.SolrException; @@ -47,9 +41,7 @@ import org.apache.solr.common.params.CollectionParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; @@ -58,39 +50,24 @@ * *

This API is analogous to the v1 /admin/collections?action=ADDREPLICAPROP command. */ -@Path("/collections/{collName}/shards/{shardName}/replicas/{replicaName}/properties/{propName}") -public class AddReplicaPropertyAPI extends AdminAPIBase { +public class AddReplicaProperty extends AdminAPIBase implements AddReplicaPropertyApi { @Inject - public AddReplicaPropertyAPI( + public AddReplicaProperty( CoreContainer coreContainer, SolrQueryRequest solrQueryRequest, SolrQueryResponse solrQueryResponse) { super(coreContainer, solrQueryRequest, solrQueryResponse); } - @PUT - @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2}) + @Override @PermissionName(COLL_EDIT_PERM) public SolrJerseyResponse addReplicaProperty( - @Parameter( - description = "The name of the collection the replica belongs to.", - required = true) - @PathParam("collName") - String collName, - @Parameter(description = "The name of the shard the replica belongs to.", required = true) - @PathParam("shardName") - String shardName, - @Parameter(description = "The replica, e.g., `core_node1`.", required = true) - @PathParam("replicaName") - String replicaName, - @Parameter(description = "The name of the property to add.", required = true) - @PathParam("propName") - String propertyName, - @RequestBody( - description = "The value of the replica property to create or update", - required = true) - AddReplicaPropertyRequestBody requestBody) + String collName, + String shardName, + String replicaName, + String propertyName, + AddReplicaPropertyRequestBody requestBody) throws Exception { if (requestBody == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Missing required request body"); @@ -153,24 +130,4 @@ public ZkNodeProps createRemoteMessage( return new ZkNodeProps(remoteMessage); } - - public static class AddReplicaPropertyRequestBody implements JacksonReflectMapWriter { - - public AddReplicaPropertyRequestBody() {} - - public AddReplicaPropertyRequestBody(String value) { - this.value = value; - } - - @Schema(description = "The value to assign to the property.", required = true) - @JsonProperty("value") - public String value; - - @Schema( - description = - "If `true`, then setting this property in one replica will remove the property from all other replicas in that shard. The default is `false`.\\nThere is one pre-defined property `preferredLeader` for which `shardUnique` is forced to `true` and an error returned if `shardUnique` is explicitly set to `false`.", - defaultValue = "false") - @JsonProperty("shardUnique") - public Boolean shardUnique; - } } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java b/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java index 17890115d2b..cfb7df038e3 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java @@ -21,6 +21,7 @@ import java.util.Map; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ClusterState; @@ -28,7 +29,6 @@ import org.apache.solr.common.params.CollectionParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.logging.MDCLoggingContext; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java index 02d2f7024c5..baeb6ddc7ac 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/AliasPropertyAPI.java @@ -39,6 +39,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.Aliases; @@ -49,7 +50,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java index 833149cb07b..8f57c58f2d9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/BackupCoreAPI.java @@ -31,6 +31,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; @@ -41,7 +42,6 @@ import org.apache.solr.handler.SnapShooter; import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicasAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicasAPI.java index 0a92fcea962..53e23886585 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicasAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceReplicasAPI.java @@ -35,6 +35,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams.CollectionAction; @@ -42,7 +43,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceShardUniqueAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceShardUniqueAPI.java index 64f31ac2e59..62324f208c3 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceShardUniqueAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/BalanceShardUniqueAPI.java @@ -34,6 +34,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.cloud.overseer.SliceMutator; import org.apache.solr.common.SolrException; import org.apache.solr.common.annotation.JsonProperty; @@ -44,7 +45,6 @@ import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CollectionPropertyAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CollectionPropertyAPI.java index 5302571dcad..a50e2895d52 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CollectionPropertyAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CollectionPropertyAPI.java @@ -28,12 +28,12 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.CollectionProperties; import org.apache.solr.core.CoreContainer; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreAdminAPIBase.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreAdminAPIBase.java index a5d9431cc7f..6a4130e9132 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreAdminAPIBase.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreAdminAPIBase.java @@ -18,11 +18,11 @@ import java.util.function.Supplier; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.handler.api.V2ApiUtils; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.logging.MDCLoggingContext; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplicationAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplicationAPI.java index f2c4ac60cd6..9049a4adc7e 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplicationAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreReplicationAPI.java @@ -29,10 +29,10 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.core.SolrCore; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreSnapshotAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreSnapshotAPI.java index b5e028b8cf7..634c1f105b9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CoreSnapshotAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CoreSnapshotAPI.java @@ -37,6 +37,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import org.apache.lucene.index.IndexCommit; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.core.CoreContainer; @@ -47,7 +48,6 @@ import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateAliasAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateAliasAPI.java index 95f191c485a..ad3f300b7c9 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateAliasAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateAliasAPI.java @@ -47,6 +47,8 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.RoutedAliasTypes; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.util.SolrIdentifierValidator; @@ -65,8 +67,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.util.TimeZoneUtils; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java index 1ff34e69ff7..a33c4a51f3b 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java @@ -61,6 +61,7 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.request.beans.V2ApiConstants; import org.apache.solr.client.solrj.util.SolrIdentifierValidator; @@ -79,7 +80,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.apache.zookeeper.CreateMode; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionBackupAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionBackupAPI.java index 4a5f1991fde..5dd9fd96e09 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionBackupAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionBackupAPI.java @@ -43,6 +43,8 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkNodeProps; @@ -54,8 +56,6 @@ import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; import org.apache.solr.jersey.SolrJacksonMapper; -import org.apache.solr.jersey.SolrJerseyResponse; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.apache.zookeeper.common.StringUtils; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionSnapshotAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionSnapshotAPI.java index b331af1aa7c..e619ccf442b 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionSnapshotAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionSnapshotAPI.java @@ -35,6 +35,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.AsyncJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.SolrZkClient; @@ -44,7 +45,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.snapshots.SolrSnapshotManager; import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.jersey.AsyncJerseyResponse; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; import org.apache.solr.request.SolrQueryRequest; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplicaAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplicaAPI.java index 76043bff05c..c119f27db60 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplicaAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateReplicaAPI.java @@ -51,6 +51,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; @@ -60,7 +61,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShardAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShardAPI.java index 3f39404f45a..41be6e672d7 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShardAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateShardAPI.java @@ -47,6 +47,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.util.SolrIdentifierValidator; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ClusterState; @@ -59,7 +60,6 @@ import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAliasAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAlias.java similarity index 87% rename from solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAliasAPI.java rename to solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAlias.java index 4b9a4480507..2c577453c93 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAliasAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteAlias.java @@ -17,7 +17,6 @@ package org.apache.solr.handler.admin.api; -import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2; import static org.apache.solr.cloud.Overseer.QUEUE_OPERATION; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; import static org.apache.solr.common.params.CommonParams.NAME; @@ -27,34 +26,30 @@ import java.util.HashMap; import java.util.Map; import javax.inject.Inject; -import javax.ws.rs.DELETE; -import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.endpoint.DeleteAliasApi; +import org.apache.solr.client.api.model.AsyncJerseyResponse; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.jersey.AsyncJerseyResponse; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; -@Path("/aliases/{aliasName}") -public class DeleteAliasAPI extends AdminAPIBase { +public class DeleteAlias extends AdminAPIBase implements DeleteAliasApi { @Inject - public DeleteAliasAPI( + public DeleteAlias( CoreContainer coreContainer, SolrQueryRequest solrQueryRequest, SolrQueryResponse solrQueryResponse) { super(coreContainer, solrQueryRequest, solrQueryResponse); } - @DELETE - @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2}) + @Override @PermissionName(COLL_EDIT_PERM) public SolrJerseyResponse deleteAlias( @PathParam("aliasName") String aliasName, @QueryParam("async") String asyncId) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollection.java similarity index 84% rename from solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionAPI.java rename to solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollection.java index 2c38da38a87..812f7255ad2 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollection.java @@ -16,7 +16,6 @@ */ package org.apache.solr.handler.admin.api; -import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2; import static org.apache.solr.cloud.Overseer.QUEUE_OPERATION; import static org.apache.solr.common.params.CollectionAdminParams.FOLLOW_ALIASES; import static org.apache.solr.common.params.CommonAdminParams.ASYNC; @@ -27,18 +26,14 @@ import java.util.HashMap; import java.util.Map; import javax.inject.Inject; -import javax.ws.rs.DELETE; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.endpoint.DeleteCollectionApi; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; @@ -48,26 +43,20 @@ *

This API (DELETE /v2/collections/collectionName) is equivalent to the v1 * /admin/collections?action=DELETE command. */ -@Path("collections/") -public class DeleteCollectionAPI extends AdminAPIBase { +public class DeleteCollection extends AdminAPIBase implements DeleteCollectionApi { @Inject - public DeleteCollectionAPI( + public DeleteCollection( CoreContainer coreContainer, SolrQueryRequest solrQueryRequest, SolrQueryResponse solrQueryResponse) { super(coreContainer, solrQueryRequest, solrQueryResponse); } - @DELETE - @Path("{collectionName}") - @Produces({"application/json", "application/xml", BINARY_CONTENT_TYPE_V2}) + @Override @PermissionName(COLL_EDIT_PERM) public SubResponseAccumulatingJerseyResponse deleteCollection( - @PathParam("collectionName") String collectionName, - @QueryParam("followAliases") Boolean followAliases, - @QueryParam("async") String asyncId) - throws Exception { + String collectionName, Boolean followAliases, String asyncId) throws Exception { final SubResponseAccumulatingJerseyResponse response = instantiateJerseyResponse(SubResponseAccumulatingJerseyResponse.class); final CoreContainer coreContainer = fetchAndValidateZooKeeperAwareCoreContainer(); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionBackupAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionBackupAPI.java index 4edc0ec9c6f..48a482dce3e 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionBackupAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionBackupAPI.java @@ -44,6 +44,8 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.SolrJerseyResponse; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkNodeProps; @@ -55,8 +57,6 @@ import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; import org.apache.solr.jersey.SolrJacksonMapper; -import org.apache.solr.jersey.SolrJerseyResponse; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionSnapshotAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionSnapshotAPI.java index e591e7aed7e..d77a91cafca 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionSnapshotAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteCollectionSnapshotAPI.java @@ -36,13 +36,13 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.AsyncJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.jersey.AsyncJerseyResponse; import org.apache.solr.jersey.PermissionName; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteNodeAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteNodeAPI.java index 868e2b93273..5416793ddba 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteNodeAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteNodeAPI.java @@ -34,6 +34,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; @@ -43,7 +44,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaAPI.java index fab78e3ac3a..143acf95134 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaAPI.java @@ -40,6 +40,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; @@ -48,7 +49,6 @@ import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaPropertyAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaPropertyAPI.java index 933d31e640d..bce721ce087 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaPropertyAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteReplicaPropertyAPI.java @@ -30,6 +30,7 @@ import javax.inject.Inject; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; @@ -37,7 +38,6 @@ import org.apache.solr.common.params.SolrParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.admin.CollectionsHandler; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteShardAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteShardAPI.java index afa4abe92cd..593e6ed5e81 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteShardAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/DeleteShardAPI.java @@ -34,12 +34,12 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ForceLeaderAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ForceLeaderAPI.java index fd32b52a1f7..b0881a34bac 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ForceLeaderAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ForceLeaderAPI.java @@ -32,6 +32,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.cloud.ZkController; import org.apache.solr.cloud.ZkShardTerms; import org.apache.solr.common.SolrException; @@ -42,7 +43,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.slf4j.Logger; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaAPI.java index 3a966866727..b474a9c80c2 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaAPI.java @@ -27,10 +27,10 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.schema.IndexSchema; import org.apache.solr.security.PermissionNameProvider; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaFieldAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaFieldAPI.java index 2ad7db4d863..d90512decc1 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaFieldAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaFieldAPI.java @@ -29,6 +29,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.SolrClassLoader; @@ -37,7 +38,6 @@ import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.core.PluginInfo; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.pkg.PackageListeningClassLoader; import org.apache.solr.schema.IndexSchema; import org.apache.solr.security.PermissionNameProvider; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaZkVersionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaZkVersionAPI.java index 56a22f77783..9a97af7b3eb 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaZkVersionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetSchemaZkVersionAPI.java @@ -29,10 +29,10 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.cloud.ZkSolrResourceLoader; import org.apache.solr.core.SolrCore; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.schema.ManagedIndexSchema; import org.apache.solr.schema.ZkIndexSchemaReader; import org.apache.solr.security.PermissionNameProvider; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/InstallCoreDataAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/InstallCoreDataAPI.java index 53c47824f13..c0cd11b3451 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/InstallCoreDataAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/InstallCoreDataAPI.java @@ -27,6 +27,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.cloud.ZkController; import org.apache.solr.common.SolrException; @@ -37,7 +38,6 @@ import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.slf4j.Logger; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardDataAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardDataAPI.java index d1c1faf0f36..fa400835a4f 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardDataAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/InstallShardDataAPI.java @@ -29,6 +29,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.cloud.api.collections.InstallShardDataCmd; import org.apache.solr.common.SolrException; @@ -42,7 +43,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.slf4j.Logger; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListAliasesAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListAliasesAPI.java index 0f7103e5155..0e2626e9668 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ListAliasesAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ListAliasesAPI.java @@ -31,11 +31,11 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.cloud.Aliases; import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.core.CoreContainer; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionBackupsAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionBackupsAPI.java index 89827b9ac03..3ec3c599e0d 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionBackupsAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionBackupsAPI.java @@ -38,6 +38,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.core.CoreContainer; @@ -48,7 +49,6 @@ import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; import org.apache.solr.jersey.SolrJacksonMapper; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionSnapshotsAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionSnapshotsAPI.java index b3fa81fb2c0..47f9194b046 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionSnapshotsAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionSnapshotsAPI.java @@ -29,12 +29,12 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.AsyncJerseyResponse; import org.apache.solr.common.cloud.SolrZkClient; import org.apache.solr.common.util.CollectionUtil; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.snapshots.CollectionSnapshotMetaData; import org.apache.solr.core.snapshots.SolrSnapshotManager; -import org.apache.solr.jersey.AsyncJerseyResponse; import org.apache.solr.jersey.PermissionName; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionsAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionsAPI.java index df4fc547bf2..e03b05a6f70 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionsAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ListCollectionsAPI.java @@ -29,10 +29,10 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.cloud.DocCollection; import org.apache.solr.core.CoreContainer; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicasAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicasAPI.java index da1188ef89d..6f353707504 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicasAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/MigrateReplicasAPI.java @@ -36,6 +36,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkNodeProps; @@ -44,7 +45,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/NodeLoggingAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/NodeLoggingAPI.java index 742a53d2d95..a6ffbdd2f4b 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/NodeLoggingAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/NodeLoggingAPI.java @@ -35,12 +35,12 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrException; import org.apache.solr.core.CoreContainer; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.logging.LogWatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCollectionAPI.java index 009ee727969..22c2abdaca3 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCollectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCollectionAPI.java @@ -33,13 +33,13 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.slf4j.Logger; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCollectionAPI.java index c63c518426b..2fd2d7fb405 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCollectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCollectionAPI.java @@ -34,6 +34,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; @@ -41,7 +42,6 @@ import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNodeAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNodeAPI.java index dc4fca1707d..e2e63760ab7 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNodeAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReplaceNodeAPI.java @@ -36,6 +36,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.common.cloud.ZkNodeProps; import org.apache.solr.common.params.CollectionParams; @@ -44,7 +45,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java index acd9ccf3a03..18caed1933a 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCollectionAPI.java @@ -46,6 +46,8 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; +import org.apache.solr.client.api.model.SubResponseAccumulatingJerseyResponse; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.util.SolrIdentifierValidator; import org.apache.solr.common.SolrException; @@ -56,8 +58,6 @@ import org.apache.solr.handler.admin.CollectionsHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; -import org.apache.solr.jersey.SubResponseAccumulatingJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCoreAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCoreAPI.java index 11243630cf7..03358880450 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCoreAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RestoreCoreAPI.java @@ -27,6 +27,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.Slice; @@ -39,7 +40,6 @@ import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.jersey.JacksonReflectMapWriter; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/SyncShardAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/SyncShardAPI.java index 07488e3c5ed..1b7b44b0dea 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/SyncShardAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/SyncShardAPI.java @@ -30,6 +30,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; @@ -41,7 +42,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.handler.api.V2ApiUtils; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; diff --git a/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java b/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java index 454a1bcbde6..2fa0ae4ed3f 100644 --- a/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java +++ b/solr/core/src/java/org/apache/solr/handler/api/V2ApiUtils.java @@ -20,12 +20,14 @@ import static org.apache.solr.client.solrj.impl.BinaryResponseParser.BINARY_CONTENT_TYPE_V2; import static org.apache.solr.common.params.CommonParams.WT; -import java.io.IOException; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import java.util.Map; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.MapWriter.EntryWriter; import org.apache.solr.common.util.NamedList; -import org.apache.solr.jersey.JacksonReflectMapWriter; +import org.apache.solr.common.util.Utils; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; @@ -55,39 +57,34 @@ public static void flattenToCommaDelimitedString( } /** - * Convert a JacksonReflectMapWriter (typically a {@link - * org.apache.solr.jersey.SolrJerseyResponse}) into the NamedList on a SolrQueryResponse, omitting - * the response header + * Convert a JacksonReflectMapWriter (typically a {@link SolrJerseyResponse}) into the NamedList + * on a SolrQueryResponse, omitting the response header * * @param rsp the response to attach the resulting NamedList to * @param mw the input object to be converted into a NamedList */ - public static void squashIntoSolrResponseWithoutHeader( - SolrQueryResponse rsp, JacksonReflectMapWriter mw) { - squashIntoNamedList(rsp.getValues(), mw, true); + public static void squashIntoSolrResponseWithoutHeader(SolrQueryResponse rsp, Object mw) { + squashObjectIntoNamedList(rsp.getValues(), mw, true); } /** - * Convert a JacksonReflectMapWriter (typically a {@link - * org.apache.solr.jersey.SolrJerseyResponse}) into the NamedList on a SolrQueryResponse, - * including the response header + * Convert a JacksonReflectMapWriter (typically a {@link SolrJerseyResponse}) into the NamedList + * on a SolrQueryResponse, including the response header * * @param rsp the response to attach the resulting NamedList to * @param mw the input object to be converted into a NamedList */ - public static void squashIntoSolrResponseWithHeader( - SolrQueryResponse rsp, JacksonReflectMapWriter mw) { - squashIntoNamedList(rsp.getValues(), mw, false); + public static void squashIntoSolrResponseWithHeader(SolrQueryResponse rsp, Object mw) { + squashObjectIntoNamedList(rsp.getValues(), mw, false); } - public static void squashIntoNamedList( - NamedList destination, JacksonReflectMapWriter mw) { - squashIntoNamedList(destination, mw, false); + public static void squashIntoNamedList(NamedList destination, Object mw) { + squashObjectIntoNamedList(destination, mw, false); } public static void squashIntoNamedListWithoutHeader( - NamedList destination, JacksonReflectMapWriter mw) { - squashIntoNamedList(destination, mw, true); + NamedList destination, Object toSquash) { + squashObjectIntoNamedList(destination, toSquash, true); } public static String getMediaTypeFromWtParam( @@ -106,23 +103,29 @@ public static String getMediaTypeFromWtParam( } } - private static void squashIntoNamedList( - NamedList destination, JacksonReflectMapWriter mw, boolean trimHeader) { - try { - mw.writeMap( - new EntryWriter() { - @Override - public EntryWriter put(CharSequence key, Object value) { - var kStr = key.toString(); - if (trimHeader && kStr.equals("responseHeader")) { - return null; - } - destination.add(kStr, value); - return this; // returning "this" means we can't use a lambda :-( + public static void squashObjectIntoNamedList( + NamedList destination, Object o, boolean trimHeader) { + final var ew = + new EntryWriter() { + @Override + public EntryWriter put(CharSequence key, Object value) { + var kStr = key.toString(); + if (trimHeader && kStr.equals("responseHeader")) { + return null; } - }); - } catch (IOException e) { - throw new RuntimeException(e); // impossible - } + destination.add(kStr, value); + return this; // returning "this" means we can't use a lambda :-( + } + }; + Utils.reflectWrite( + ew, + o, + // TODO Should we be lenient here and accept both the Jackson and our homegrown annotation? + field -> field.getAnnotation(JsonProperty.class) != null, + JsonAnyGetter.class, + field -> { + final JsonProperty prop = field.getAnnotation(JsonProperty.class); + return prop.value().isEmpty() ? field.getName() : prop.value(); + }); } } diff --git a/solr/core/src/java/org/apache/solr/handler/configsets/ListConfigSetsAPI.java b/solr/core/src/java/org/apache/solr/handler/configsets/ListConfigSetsAPI.java index 978f290d763..58dcdfec5e9 100644 --- a/solr/core/src/java/org/apache/solr/handler/configsets/ListConfigSetsAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/configsets/ListConfigSetsAPI.java @@ -28,9 +28,9 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.core.CoreContainer; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; /** * V2 API for adding or updating a single file within a configset. diff --git a/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java b/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java index 6dfec0fe1ba..d3886ae8727 100644 --- a/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java +++ b/solr/core/src/java/org/apache/solr/jersey/CatchAllExceptionMapper.java @@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.SolrException; import org.apache.solr.handler.RequestHandlerBase; import org.apache.solr.handler.api.V2ApiUtils; diff --git a/solr/core/src/java/org/apache/solr/jersey/ExperimentalResponse.java b/solr/core/src/java/org/apache/solr/jersey/ExperimentalResponse.java index 657e3652064..7824b7bc314 100644 --- a/solr/core/src/java/org/apache/solr/jersey/ExperimentalResponse.java +++ b/solr/core/src/java/org/apache/solr/jersey/ExperimentalResponse.java @@ -18,6 +18,7 @@ package org.apache.solr.jersey; import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.solr.client.api.model.SolrJerseyResponse; /** * {@link SolrJerseyResponse} implementation with a warning field indicating that the format may diff --git a/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java b/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java index bd4283c2dcf..6bb4b07c439 100644 --- a/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java +++ b/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java @@ -17,16 +17,12 @@ package org.apache.solr.jersey; -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.annotations.info.License; import java.util.Map; import org.apache.solr.common.params.SolrParams; import org.apache.solr.core.SolrCore; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.schema.IndexSchema; -import org.apache.solr.util.SolrVersion; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider; import org.glassfish.jersey.process.internal.RequestScoped; @@ -36,13 +32,6 @@ * JAX-RS "application" configurations for Solr's {@link org.apache.solr.core.CoreContainer} and * {@link SolrCore} instances */ -@OpenAPIDefinition( - info = - @Info( - title = "v2 API", - description = "OpenAPI spec for Solr's v2 API endpoints", - license = @License(name = "ASL 2.0"), - version = SolrVersion.LATEST_STRING)) public class JerseyApplications { public static class CoreContainerApp extends ResourceConfig { diff --git a/solr/core/src/java/org/apache/solr/jersey/MessageBodyWriters.java b/solr/core/src/java/org/apache/solr/jersey/MessageBodyWriters.java index 274f6b19fca..49fd716d09f 100644 --- a/solr/core/src/java/org/apache/solr/jersey/MessageBodyWriters.java +++ b/solr/core/src/java/org/apache/solr/jersey/MessageBodyWriters.java @@ -54,7 +54,7 @@ public class MessageBodyWriters { @Produces(MediaType.APPLICATION_XML) public static class XmlMessageBodyWriter extends BaseMessageBodyWriter - implements MessageBodyWriter { + implements MessageBodyWriter { @Override public QueryResponseWriter createResponseWriter() { return new XMLResponseWriter(); @@ -68,7 +68,7 @@ public String getSupportedMediaType() { @Produces(BINARY_CONTENT_TYPE_V2) public static class JavabinMessageBodyWriter extends BaseMessageBodyWriter - implements MessageBodyWriter { + implements MessageBodyWriter { @Override public QueryResponseWriter createResponseWriter() { return new BinaryResponseWriter(); @@ -82,7 +82,7 @@ public String getSupportedMediaType() { @Produces(RawResponseWriter.CONTENT_TYPE) public static class RawMessageBodyWriter extends BaseMessageBodyWriter - implements MessageBodyWriter { + implements MessageBodyWriter { @Override public QueryResponseWriter createResponseWriter() { return new RawResponseWriter(); @@ -96,7 +96,7 @@ public String getSupportedMediaType() { @Produces(CONTENT_TYPE_TEXT_UTF8) public static class CsvMessageBodyWriter extends BaseMessageBodyWriter - implements MessageBodyWriter { + implements MessageBodyWriter { @Override public QueryResponseWriter createResponseWriter() { return new CSVResponseWriter(); @@ -108,8 +108,7 @@ public String getSupportedMediaType() { } } - public abstract static class BaseMessageBodyWriter - implements MessageBodyWriter { + public abstract static class BaseMessageBodyWriter implements MessageBodyWriter { @Context protected ResourceContext resourceContext; private final QueryResponseWriter responseWriter = createResponseWriter(); @@ -126,7 +125,7 @@ public boolean isWriteable( @Override public void writeTo( - JacksonReflectMapWriter reflectMapWriter, + Object toWrite, Class type, Type genericType, Annotation[] annotations, @@ -141,7 +140,7 @@ public void writeTo( final SolrQueryResponse solrQueryResponse = (SolrQueryResponse) requestContext.getProperty(SOLR_QUERY_RESPONSE); - V2ApiUtils.squashIntoSolrResponseWithHeader(solrQueryResponse, reflectMapWriter); + V2ApiUtils.squashIntoSolrResponseWithHeader(solrQueryResponse, toWrite); QueryResponseWriterUtil.writeQueryResponse( entityStream, responseWriter, solrQueryRequest, solrQueryResponse, mediaType.toString()); } diff --git a/solr/core/src/java/org/apache/solr/jersey/PostRequestDecorationFilter.java b/solr/core/src/java/org/apache/solr/jersey/PostRequestDecorationFilter.java index b7ecd64720c..43215fefa42 100644 --- a/solr/core/src/java/org/apache/solr/jersey/PostRequestDecorationFilter.java +++ b/solr/core/src/java/org/apache/solr/jersey/PostRequestDecorationFilter.java @@ -26,6 +26,7 @@ import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.core.SolrCore; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestHandler; diff --git a/solr/core/src/java/org/apache/solr/jersey/PostRequestLoggingFilter.java b/solr/core/src/java/org/apache/solr/jersey/PostRequestLoggingFilter.java index f2d35e93573..4ce9490c115 100644 --- a/solr/core/src/java/org/apache/solr/jersey/PostRequestLoggingFilter.java +++ b/solr/core/src/java/org/apache/solr/jersey/PostRequestLoggingFilter.java @@ -38,6 +38,7 @@ import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.util.CollectionUtil; import org.apache.solr.common.util.StrUtils; import org.apache.solr.core.SolrCore; diff --git a/solr/core/src/java/org/apache/solr/jersey/RequestContextKeys.java b/solr/core/src/java/org/apache/solr/jersey/RequestContextKeys.java index f300ffa4bbb..bf28cc0db71 100644 --- a/solr/core/src/java/org/apache/solr/jersey/RequestContextKeys.java +++ b/solr/core/src/java/org/apache/solr/jersey/RequestContextKeys.java @@ -21,6 +21,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.container.ContainerRequestContext; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.params.SolrParams; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.PluginBag; diff --git a/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java b/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java index a6e8b03919e..c50bb53d37c 100644 --- a/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java +++ b/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java @@ -30,6 +30,7 @@ import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.core.PluginBag; import org.apache.solr.handler.RequestHandlerBase; import org.apache.solr.request.SolrQueryRequest; diff --git a/solr/core/src/java/org/apache/solr/packagemanager/PackageManager.java b/solr/core/src/java/org/apache/solr/packagemanager/PackageManager.java index beefd88653d..a8387b4c669 100644 --- a/solr/core/src/java/org/apache/solr/packagemanager/PackageManager.java +++ b/solr/core/src/java/org/apache/solr/packagemanager/PackageManager.java @@ -38,6 +38,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import org.apache.solr.cli.SolrCLI; +import org.apache.solr.client.api.util.SolrVersion; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; @@ -61,7 +62,6 @@ import org.apache.solr.packagemanager.SolrPackage.Manifest; import org.apache.solr.packagemanager.SolrPackage.Plugin; import org.apache.solr.pkg.SolrPackageLoader; -import org.apache.solr.util.SolrVersion; import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -870,7 +870,7 @@ public SolrPackageInstance getPackageInstance(String packageName, String version if (pkg.version.equals(version)) { return pkg; } - if (PackageUtils.compareVersions(latest.version, pkg.version) <= 0) { + if (SolrVersion.compareVersions(latest.version, pkg.version) <= 0) { latest = pkg; } } @@ -918,20 +918,12 @@ public void deploy( } Manifest manifest = packageInstance.manifest; - try { - if (!SolrVersion.LATEST.satisfies(manifest.versionConstraint)) { - PackageUtils.printRed( - "Version incompatible! Solr version: " - + SolrVersion.LATEST - + ", package version constraint: " - + manifest.versionConstraint); - System.exit(1); - } - } catch (SolrVersion.InvalidSemVerExpressionException ex) { + if (!SolrVersion.LATEST.satisfies(manifest.versionConstraint)) { PackageUtils.printRed( - "Error in version constraint given in package manifest: " - + manifest.versionConstraint - + ". It does not a valid SemVer expression."); + "Version incompatible! Solr version: " + + SolrVersion.LATEST + + ", package version constraint: " + + manifest.versionConstraint); System.exit(1); } diff --git a/solr/core/src/java/org/apache/solr/packagemanager/PackageUtils.java b/solr/core/src/java/org/apache/solr/packagemanager/PackageUtils.java index 97379a3a114..9d330b49bb8 100644 --- a/solr/core/src/java/org/apache/solr/packagemanager/PackageUtils.java +++ b/solr/core/src/java/org/apache/solr/packagemanager/PackageUtils.java @@ -53,7 +53,6 @@ import org.apache.solr.filestore.PackageStoreAPI; import org.apache.solr.packagemanager.SolrPackage.Manifest; import org.apache.solr.util.SolrJacksonAnnotationInspector; -import org.semver4j.Semver; public class PackageUtils { @@ -226,14 +225,6 @@ public static String resolve( return str; } - /** - * Compares two versions v1 and v2. Returns negative if v1 isLessThan v2, positive if v1 - * isGreaterThan v2 and 0 if equal. - */ - public static int compareVersions(String v1, String v2) { - return new Semver(v1).compareTo(new Semver(v2)); - } - public static String BLACK = "\u001B[30m"; public static String RED = "\u001B[31m"; public static String GREEN = "\u001B[32m"; diff --git a/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java b/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java index a480683eba6..8ef29ba5552 100644 --- a/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java +++ b/solr/core/src/java/org/apache/solr/packagemanager/RepositoryManager.java @@ -37,6 +37,7 @@ import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; +import org.apache.solr.client.api.util.SolrVersion; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; @@ -287,7 +288,7 @@ private SolrPackageRelease getPackageRelease(String packageName, String version) return getLastPackageRelease(pkg); } for (SolrPackageRelease release : pkg.versions) { - if (PackageUtils.compareVersions(version, release.version) == 0) { + if (SolrVersion.compareVersions(version, release.version) == 0) { return release; } } @@ -310,7 +311,7 @@ private SolrPackageRelease getLastPackageRelease(SolrPackage pkg) { if (latest == null) { latest = release; } else { - if (PackageUtils.compareVersions(latest.version, release.version) < 0) { + if (SolrVersion.compareVersions(latest.version, release.version) < 0) { latest = release; } } @@ -329,7 +330,7 @@ public boolean hasPackageUpdate(String packageName) { } String installedVersion = packageManager.getPackageInstance(packageName, null).version; SolrPackageRelease last = getLastPackageRelease(packageName); - return last != null && PackageUtils.compareVersions(last.version, installedVersion) > 0; + return last != null && SolrVersion.compareVersions(last.version, installedVersion) > 0; } /** diff --git a/solr/core/src/java/org/apache/solr/security/PublicKeyAPI.java b/solr/core/src/java/org/apache/solr/security/PublicKeyAPI.java index 94ee5b099ac..46483462e5f 100644 --- a/solr/core/src/java/org/apache/solr/security/PublicKeyAPI.java +++ b/solr/core/src/java/org/apache/solr/security/PublicKeyAPI.java @@ -26,8 +26,8 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import org.apache.solr.api.JerseyResource; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.jersey.PermissionName; -import org.apache.solr.jersey.SolrJerseyResponse; /** * V2 API for fetching the public key of the receiving node. diff --git a/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java b/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java index 8859c9a3a58..6cd261bc0f2 100644 --- a/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java +++ b/solr/core/src/java/org/apache/solr/servlet/CoreContainerProvider.java @@ -58,6 +58,7 @@ import org.apache.http.client.HttpClient; import org.apache.lucene.store.MMapDirectory; import org.apache.lucene.util.VectorUtil; +import org.apache.solr.client.api.util.SolrVersion; import org.apache.solr.cloud.ZkController; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; @@ -75,7 +76,6 @@ import org.apache.solr.metrics.SolrMetricManager.ResolutionStrategy; import org.apache.solr.metrics.SolrMetricProducer; import org.apache.solr.servlet.RateLimitManager.Builder; -import org.apache.solr.util.SolrVersion; import org.apache.solr.util.StartupLoggingUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/solr/core/src/java/org/apache/solr/servlet/ResponseUtils.java b/solr/core/src/java/org/apache/solr/servlet/ResponseUtils.java index 9471b64befe..337243e25e6 100644 --- a/solr/core/src/java/org/apache/solr/servlet/ResponseUtils.java +++ b/solr/core/src/java/org/apache/solr/servlet/ResponseUtils.java @@ -19,9 +19,9 @@ import java.io.PrintWriter; import java.io.StringWriter; import org.apache.solr.api.ApiBag; +import org.apache.solr.client.api.model.ErrorInfo; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.NamedList; -import org.apache.solr.jersey.ErrorInfo; import org.slf4j.Logger; /** Response helper methods. */ @@ -50,9 +50,9 @@ public static int getErrorInfo(Throwable ex, NamedList info, Logger log) if (errorMetadata == null) { errorMetadata = new NamedList<>(); } - errorMetadata.add(SolrException.ERROR_CLASS, ex.getClass().getName()); + errorMetadata.add(ErrorInfo.ERROR_CLASS, ex.getClass().getName()); errorMetadata.add( - SolrException.ROOT_ERROR_CLASS, SolrException.getRootCause(ex).getClass().getName()); + ErrorInfo.ROOT_ERROR_CLASS, SolrException.getRootCause(ex).getClass().getName()); info.add("metadata", errorMetadata); if (ex instanceof ApiBag.ExceptionWithErrObject) { ApiBag.ExceptionWithErrObject exception = (ApiBag.ExceptionWithErrObject) ex; diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java index 01ca69ed6d3..501d22b130c 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/AddReplicaPropertyAPITest.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Optional; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.client.api.model.AddReplicaPropertyRequestBody; import org.apache.solr.cloud.OverseerSolrResponse; import org.apache.solr.cloud.api.collections.DistributedCollectionConfigSetCommandRunner; import org.apache.solr.common.SolrException; @@ -41,11 +42,11 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; -/** Unit tests for {@link AddReplicaPropertyAPI} */ +/** Unit tests for {@link AddReplicaProperty} */ public class AddReplicaPropertyAPITest extends SolrTestCaseJ4 { - private static final AddReplicaPropertyAPI.AddReplicaPropertyRequestBody ANY_REQ_BODY = - new AddReplicaPropertyAPI.AddReplicaPropertyRequestBody("anyValue"); + private static final AddReplicaPropertyRequestBody ANY_REQ_BODY = + new AddReplicaPropertyRequestBody("anyValue"); private CoreContainer mockCoreContainer; private DistributedCollectionConfigSetCommandRunner mockCommandRunner; @@ -53,7 +54,7 @@ public class AddReplicaPropertyAPITest extends SolrTestCaseJ4 { private SolrQueryResponse queryResponse; private ArgumentCaptor messageCapturer; - private AddReplicaPropertyAPI addReplicaPropApi; + private AddReplicaProperty addReplicaPropApi; @BeforeClass public static void ensureWorkingMockito() { @@ -76,8 +77,7 @@ public void setUp() throws Exception { queryResponse = new SolrQueryResponse(); messageCapturer = ArgumentCaptor.forClass(ZkNodeProps.class); - addReplicaPropApi = - new AddReplicaPropertyAPI(mockCoreContainer, mockQueryRequest, queryResponse); + addReplicaPropApi = new AddReplicaProperty(mockCoreContainer, mockQueryRequest, queryResponse); } @Test diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java index 2dcaf14d183..dc93c29b487 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteAliasAPITest.java @@ -25,18 +25,17 @@ import org.apache.solr.SolrTestCaseJ4; import org.junit.Test; -/** Unit tests for {@link DeleteAliasAPI}. */ +/** Unit tests for {@link DeleteAlias}. */ public class DeleteAliasAPITest extends SolrTestCaseJ4 { @Test public void testConstructsValidRemoteMessage() { - Map props = - DeleteAliasAPI.createRemoteMessage("aliasName", null).getProperties(); + Map props = DeleteAlias.createRemoteMessage("aliasName", null).getProperties(); assertEquals(2, props.size()); assertEquals("deletealias", props.get(QUEUE_OPERATION)); assertEquals("aliasName", props.get(NAME)); - props = DeleteAliasAPI.createRemoteMessage("aliasName", "asyncId").getProperties(); + props = DeleteAlias.createRemoteMessage("aliasName", "asyncId").getProperties(); assertEquals(3, props.size()); assertEquals("deletealias", props.get(QUEUE_OPERATION)); assertEquals("aliasName", props.get(NAME)); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteCollectionAPITest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteCollectionAPITest.java index a87dad3c900..60f2dccff19 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteCollectionAPITest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/DeleteCollectionAPITest.java @@ -29,15 +29,14 @@ import org.hamcrest.MatcherAssert; import org.junit.Test; -/** Unit tests for {@link DeleteCollectionAPI} */ +/** Unit tests for {@link DeleteCollection} */ public class DeleteCollectionAPITest extends SolrTestCaseJ4 { @Test public void testConstructsValidOverseerMessage() { // Only required properties provided { - final ZkNodeProps message = - DeleteCollectionAPI.createRemoteMessage("someCollName", null, null); + final ZkNodeProps message = DeleteCollection.createRemoteMessage("someCollName", null, null); final Map rawMessage = message.getProperties(); assertEquals(2, rawMessage.size()); MatcherAssert.assertThat(rawMessage.keySet(), containsInAnyOrder(QUEUE_OPERATION, NAME)); @@ -48,7 +47,7 @@ public void testConstructsValidOverseerMessage() { // Optional properties ('followAliases' and 'async') also provided { final ZkNodeProps message = - DeleteCollectionAPI.createRemoteMessage("someCollName", Boolean.TRUE, "someAsyncId"); + DeleteCollection.createRemoteMessage("someCollName", Boolean.TRUE, "someAsyncId"); final Map rawMessage = message.getProperties(); assertEquals(4, rawMessage.size()); MatcherAssert.assertThat( diff --git a/solr/core/src/test/org/apache/solr/jersey/JacksonReflectMapWriterTest.java b/solr/core/src/test/org/apache/solr/jersey/JacksonReflectMapWriterTest.java index 12c31f62f53..7e1ed6d8da7 100644 --- a/solr/core/src/test/org/apache/solr/jersey/JacksonReflectMapWriterTest.java +++ b/solr/core/src/test/org/apache/solr/jersey/JacksonReflectMapWriterTest.java @@ -21,9 +21,8 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.solr.SolrTestCaseJ4; -import org.apache.solr.common.util.NamedList; +import org.apache.solr.client.api.model.SolrJerseyResponse; import org.apache.solr.common.util.Utils; -import org.apache.solr.handler.api.V2ApiUtils; import org.junit.Test; /** @@ -64,27 +63,4 @@ public void testJacksonDeserializationHandlesUnknownProperties() throws IOExcept assertEquals(123, response.responseHeader.status); assertEquals("someVal", response.responseHeader.unknownProperties().get("someUnexpectedField")); } - - @Test - public void testMapConversionHandlesUnknownProperties() { - final SolrJerseyResponse response = new SolrJerseyResponse(); - response.responseHeader.status = 123; - response.responseHeader.setUnknownProperty("someField", "someVal"); - response.responseHeader.setUnknownProperty("someNonStringField", 456); - final NamedList destination = new NamedList<>(); - - V2ApiUtils.squashIntoNamedList(destination, response); - assertEquals( - response.responseHeader, - destination.get( - "responseHeader")); // ResponseHeader copied as-is to NL since its a serializable type - final String jsonOutput = Utils.toJSONString(destination); - - assertTrue( - "Expected JSON " + jsonOutput + " to contain different value", - jsonOutput.contains("\"someField\":\"someVal\"")); - assertTrue( - "Expected JSON " + jsonOutput + " to contain different value", - jsonOutput.contains("\"someNonStringField\":456")); - } } diff --git a/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc b/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc index be9c83b970c..447bb1b8d56 100644 --- a/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc +++ b/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc @@ -428,7 +428,7 @@ classify(model(modelCollection, field="text_t") ---- -In the example above the `classify expression` is retrieving the model using the `model` function. +In the example above the `classify expression` is retrieving the model using the `api` function. It is then classifying tuples returned by the `search` function. The `text_t` field is used for the text classification and the analyzer for the `text_t` field in the Solr schema is used to analyze the text and extract the features. diff --git a/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc b/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc index 45e0b6db726..3808a812f4c 100644 --- a/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc +++ b/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc @@ -310,8 +310,8 @@ knnSearch(collection1, == model -The `model` function retrieves and caches logistic regression text classification models that are stored in a SolrCloud collection. -The `model` function is designed to work with models that are created by the <>, but can also be used to retrieve text classification models trained outside of Solr, as long as they conform to the specified format. +The `api` function retrieves and caches logistic regression text classification models that are stored in a SolrCloud collection. +The `api` function is designed to work with models that are created by the <>, but can also be used to retrieve text classification models trained outside of Solr, as long as they conform to the specified format. After the model is retrieved it can be used by the xref:stream-decorator-reference.adoc#classify[classify function] to classify documents. A single model tuple is fetched and returned based on the *id* parameter. @@ -320,14 +320,14 @@ If more then one iteration of the named model is stored in the index, the highes === Caching with model -The `model` function has an internal LRU (least-recently-used) cache so models do not have to be retrieved with each invocation of the `model` function. +The `api` function has an internal LRU (least-recently-used) cache so models do not have to be retrieved with each invocation of the `api` function. The time to cache for each model ID can be passed as a parameter to the function call. Retrieving a cached model does not reset the time for expiring the model ID in the cache. === Model Storage The storage format of the models in Solr is below. -The `train` function outputs the format below so you only need to know schema details if you plan to use the `model` function with logistic regression models trained outside of Solr. +The `train` function outputs the format below so you only need to know schema details if you plan to use the `api` function with logistic regression models trained outside of Solr. * `name_s` (Single value, String, Stored): The name of the model. * `iteration_i` (Single value, Integer, Stored): The iteration number of the model. diff --git a/solr/solrj/build.gradle b/solr/solrj/build.gradle index 3d9e791ff51..e6bdf9caa0f 100644 --- a/solr/solrj/build.gradle +++ b/solr/solrj/build.gradle @@ -15,12 +15,22 @@ * limitations under the License. */ +plugins { + id "org.openapi.generator" version "6.6.0" +} apply plugin: 'java-library' +apply plugin: 'com.diffplug.spotless' + +import com.diffplug.gradle.spotless.JavaExtension + description = 'Solrj - Solr Java Client' dependencies { + implementation 'com.fasterxml.jackson.core:jackson-databind' + implementation 'com.fasterxml.jackson.core:jackson-annotations' + implementation project(":solr:api") implementation 'org.slf4j:slf4j-api' runtimeOnly 'org.slf4j:jcl-over-slf4j' @@ -62,7 +72,6 @@ dependencies { testImplementation 'org.hamcrest:hamcrest' testImplementation 'commons-io:commons-io' - testImplementation 'com.fasterxml.jackson.core:jackson-databind' testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor' testImplementation 'org.eclipse.jetty.toolchain:jetty-servlet-api' @@ -85,3 +94,73 @@ dependencies { testImplementation 'org.apache.commons:commons-lang3' testImplementation 'io.dropwizard.metrics:metrics-core' } + +/** + * Java Code Generation for Solr API + */ + +evaluationDependsOn(":solr:api") + +configurations { + openApiSpecFile { + canBeConsumed = false + } +} + +ext { + generatedCodeDir = "${buildDir}/generated/" + javaTemplateDir = "${projectDir}/src/resources/java-template" +} + +dependencies { + openApiSpecFile(project(path: ":solr:api", configuration: "openapiSpec")) +} + +/** + * Code Generation task + */ +openApiGenerate { + generatorName = "java" + inputSpec = project(":solr:api").openApiSpecFile + + // Add 'debugModels: ""' or 'debugOperations: ""' to get the JSON input to mustache templating for those components + globalProperties.set([apis: "", models: "false"]) + templateDir = project.javaTemplateDir + apiPackage = "org.apache.solr.client.solrj.request" + outputDir = project.generatedCodeDir + generateApiTests = false + generateModelTests = false + generateApiDocumentation = false + generateModelDocumentation = false + additionalProperties = ["modelPackage": "org.apache.solr.client.api.model"] +} + +tasks.openApiGenerate.dependsOn configurations.openApiSpecFile + +def generatedFiles = files("${project.generatedCodeDir}/src/main/java") { + builtBy tasks.openApiGenerate +} + +/** + * Setup Spotless (Code formatting) for the generated java files + */ +def generatedExt = new JavaExtension(spotless) +project.spotlessJavaSetup.execute(generatedExt) +generatedExt.target(generatedFiles) +def generatedSpotlessTask = generatedExt.createIndependentApplyTask("generatedSpotless") +generatedSpotlessTask.group("build") +generatedSpotlessTask.description("Apply formatting for generated code") + +tasks.openApiGenerate.finalizedBy generatedSpotlessTask + +/** + * Add the Generated code to the SolrJ Source paths + */ + +sourceSets { + main { + java { + srcDir generatedFiles + } + } +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/JacksonContentWriter.java b/solr/solrj/src/java/org/apache/solr/client/solrj/JacksonContentWriter.java new file mode 100644 index 00000000000..8ba0c29fa6b --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/JacksonContentWriter.java @@ -0,0 +1,46 @@ +/* + * 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.solrj; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.OutputStream; +import org.apache.solr.client.solrj.request.RequestWriter; + +public class JacksonContentWriter implements RequestWriter.ContentWriter { + + public static final ObjectMapper DEFAULT_MAPPER = new ObjectMapper(); + + private final Object toWrite; + private final String contentType; + + public JacksonContentWriter(String contentType, Object toWrite) { + this.contentType = contentType; + this.toWrite = toWrite; + } + + @Override + public void write(OutputStream os) throws IOException { + DEFAULT_MAPPER.writeValue(os, toWrite); + } + + @Override + public String getContentType() { + return contentType; + } +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/JacksonParsingResponse.java b/solr/solrj/src/java/org/apache/solr/client/solrj/JacksonParsingResponse.java new file mode 100644 index 00000000000..3e95da59657 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/JacksonParsingResponse.java @@ -0,0 +1,44 @@ +/* + * 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.solrj; + +import java.io.InputStream; +import org.apache.solr.client.solrj.response.SimpleSolrResponse; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.ObjectReleaseTracker; + +public class JacksonParsingResponse extends SimpleSolrResponse { + + private final Class typeParam; + + public JacksonParsingResponse(Class typeParam) { + this.typeParam = typeParam; + } + + public T getParsed() { + final NamedList resp = getResponse(); + final var stream = (InputStream) resp.get("stream"); + try { + final T parsedVal = JacksonContentWriter.DEFAULT_MAPPER.readValue(stream, typeParam); + assert ObjectReleaseTracker.release(stream); + return parsedVal; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/solr/solrj/src/java/org/apache/solr/common/DelegateMapWriter.java b/solr/solrj/src/java/org/apache/solr/common/DelegateMapWriter.java new file mode 100644 index 00000000000..9fe01b09b14 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/common/DelegateMapWriter.java @@ -0,0 +1,46 @@ +/* + * 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.common; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.IOException; +import org.apache.solr.common.util.Utils; + +public class DelegateMapWriter implements MapWriter { + + private final Object delegate; + + public DelegateMapWriter(Object delegate) { + this.delegate = delegate; + } + + @Override + public void writeMap(EntryWriter ew) throws IOException { + Utils.reflectWrite( + ew, + delegate, + // TODO Should we be lenient here and accept both the Jackson and our homegrown annotation? + field -> field.getAnnotation(JsonProperty.class) != null, + JsonAnyGetter.class, + field -> { + final JsonProperty prop = field.getAnnotation(JsonProperty.class); + return prop.value().isEmpty() ? field.getName() : prop.value(); + }); + } +} diff --git a/solr/solrj/src/java/org/apache/solr/common/SolrException.java b/solr/solrj/src/java/org/apache/solr/common/SolrException.java index e96bf302796..2bcab2cab3a 100644 --- a/solr/solrj/src/java/org/apache/solr/common/SolrException.java +++ b/solr/solrj/src/java/org/apache/solr/common/SolrException.java @@ -16,6 +16,9 @@ */ package org.apache.solr.common; +import static org.apache.solr.client.api.model.ErrorInfo.ERROR_CLASS; +import static org.apache.solr.client.api.model.ErrorInfo.ROOT_ERROR_CLASS; + import java.util.Map; import org.apache.solr.common.util.NamedList; import org.slf4j.Logger; @@ -24,8 +27,6 @@ /** */ public class SolrException extends RuntimeException { - public static final String ROOT_ERROR_CLASS = "root-error-class"; - public static final String ERROR_CLASS = "error-class"; private final Map mdcContext; /** diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java index aaf955b0aac..488aa8e8427 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/JavaBinCodec.java @@ -42,7 +42,9 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.Predicate; +import org.apache.solr.client.api.util.ReflectWritable; import org.apache.solr.common.ConditionalKeyMapWriter; +import org.apache.solr.common.DelegateMapWriter; import org.apache.solr.common.EnumFieldValue; import org.apache.solr.common.IteratorWriter; import org.apache.solr.common.IteratorWriter.ItemWriter; @@ -391,6 +393,10 @@ public boolean writeKnownType(Object val) throws IOException { writeMap((MapWriter) val); return true; } + if (val instanceof ReflectWritable) { + writeMap(new DelegateMapWriter(val)); + return true; + } if (val instanceof Map) { writeMap((Map) val); return true; diff --git a/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java b/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java index 3ec8df2168b..c42240aeed5 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/TextWriter.java @@ -34,6 +34,8 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.LongAccumulator; import java.util.concurrent.atomic.LongAdder; +import org.apache.solr.client.api.util.ReflectWritable; +import org.apache.solr.common.DelegateMapWriter; import org.apache.solr.common.EnumFieldValue; import org.apache.solr.common.IteratorWriter; import org.apache.solr.common.MapSerializable; @@ -85,6 +87,8 @@ default void writeVal(String name, Object val, boolean raw) throws IOException { writeIterator(name, (IteratorWriter) val, raw); } else if (val instanceof MapWriter) { writeMap(name, (MapWriter) val); + } else if (val instanceof ReflectWritable) { + writeMap(name, new DelegateMapWriter(val)); } else if (val instanceof MapSerializable) { // todo find a better way to reuse the map more efficiently writeMap(name, ((MapSerializable) val).toMap(new LinkedHashMap<>()), false, true); diff --git a/solr/solrj/src/resources/java-template/api.mustache b/solr/solrj/src/resources/java-template/api.mustache new file mode 100644 index 00000000000..872e16f509d --- /dev/null +++ b/solr/solrj/src/resources/java-template/api.mustache @@ -0,0 +1,152 @@ +/* + * 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 {{package}}; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.response.SimpleSolrResponse; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.client.solrj.JacksonParsingResponse; +import org.apache.solr.client.solrj.JacksonContentWriter; +import org.apache.solr.client.solrj.request.RequestWriter.ContentWriter; +import org.apache.solr.client.solrj.impl.InputStreamResponseParser; +import org.apache.solr.client.solrj.ResponseParser; +{{#operations}} +{{#operation}} +{{#imports}} +import {{modelPackage}}.{{.}}; +{{/imports}} +{{/operation}} + +// WARNING: This class is generated from a Mustache template; any intended +// changes should be made to the underlying template and not this file directly. + +public class {{classname}} { + + {{#operation}} + public static class {{operationIdCamelCase}}Response extends JacksonParsingResponse<{{returnType}}> { + public {{operationIdCamelCase}}Response() { + super({{returnType}}.class); + } + } + + public static class {{operationIdCamelCase}} extends SolrRequest<{{operationIdCamelCase}}Response> { + {{#requiredParams}} + {{#isBodyParam}} + private final {{{dataType}}} requestBody; + {{/isBodyParam}} + {{^isBodyParam}} + private final {{{dataType}}} {{paramName}}; + {{/isBodyParam}} + {{/requiredParams}} + {{#optionalParams}} + private {{{dataType}}} {{paramName}}; + {{/optionalParams}} + + /** + * Create a {{operationIdCamelCase}} request object. + * + {{#requiredParams}}{{^isBodyParam}}* @param {{paramName}} Path param - {{description}}{{/isBodyParam}} + {{/requiredParams}} + */ + public {{operationIdCamelCase}}({{#requiredParams}}{{^isBodyParam}}{{^-first}}, {{/-first}}{{{dataType}}} {{paramName}}{{/isBodyParam}}{{/requiredParams}}) { + super( + SolrRequest.METHOD.valueOf("{{httpMethod}}"), + "{{{path}}}"{{#pathParams}} + .replace("{" + "{{baseName}}" + "}", {{paramName}}){{/pathParams}} + ); + + {{#requiredParams}} + {{^isBodyParam}} + this.{{paramName}} = {{paramName}}; + {{/isBodyParam}} + {{#isBodyParam}} + this.requestBody = new {{baseName}}(); + addHeader("Content-type", "application/json"); + {{/isBodyParam}} + {{/requiredParams}} + } + + {{#optionalParams}} + {{#description}} + /** + * @param {{paramName}} {{description}} + */ + {{/description}} + public void {{schema.setter}}({{dataType}} {{paramName}}) { + this.{{paramName}} = {{paramName}}; + } + + {{/optionalParams}} + + {{#bodyParam}} + {{#vars}} + // TODO find a way to add required parameters in the request body to the class constructor + {{#description}} + /** + * @param {{baseName}} {{description}} + */ + {{/description}} + public void {{setter}}({{dataType}} {{baseName}}) { + this.requestBody.{{baseName}} = {{baseName}}; + } + {{/vars}} + + @Override + public RequestWriter.ContentWriter getContentWriter(String expectedType) { + return new JacksonContentWriter(expectedType, requestBody); + } + {{/bodyParam}} + + // TODO Hardcode this for now, but in reality we'll want to parse this out of the Operation data somehow + @Override + public String getRequestType() { + return SolrRequestType.ADMIN.toString(); + } + + @Override + public SolrParams getParams() { + final ModifiableSolrParams params = new ModifiableSolrParams(); + {{#queryParams}} + if ({{paramName}} != null) { + params.add("{{baseName}}", {{paramName}}{{^isString}}.toString(){{/isString}}); + } + {{/queryParams}} + return params; + } + + @Override + protected {{operationIdCamelCase}}Response createResponse(SolrClient client) { + return new {{operationIdCamelCase}}Response(); + } + + @Override + public ResponseParser getResponseParser() { + return new InputStreamResponseParser("json"); + } + } + {{/operation}} +} +{{/operations}}