Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLR-16835: Add approximate-/select to OAS #2079

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.client.api.endpoint;

import static org.apache.solr.client.api.util.Constants.GENERIC_ENTITY_PROPERTY;
import static org.apache.solr.client.api.util.Constants.STORE_PATH_PREFIX;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import java.io.InputStream;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import org.apache.solr.client.api.model.FlexibleSolrJerseyResponse;
import org.apache.solr.client.api.util.StoreApiParameters;

/**
* V2 API implementation shim for Solr's querying or otherwise inspecting documents in a core or
* collection.
*
* <p>Due to the complexity and configurability of Solr's '/select' endpoint, this interface doesn't
* attempt to be exhaustive in describing /select inputs and outputs. Rather, it exists to give
* Solr's OAS (and the clients generated from that) an approximate view of the endpoint until its
* inputs and outputs can be understood more fully.
*/
@Path(STORE_PATH_PREFIX + "/select")
public interface SelectApi {
@GET
@StoreApiParameters
@Operation(
summary = "Query a Solr core or collection using individual query parameters",
tags = {"querying"})
FlexibleSolrJerseyResponse query(
@QueryParam("q") String query,
@QueryParam("fq") List<String> filterQueries,
@QueryParam("fl") String fieldList,
@QueryParam("rows") Integer rows);

@POST
@StoreApiParameters
@Operation(
summary = "Query a Solr core or collection using the structured request DSL",
tags = {"querying"})
// TODO Find way to bundle the request-body annotations below for re-use on other similar
// endpoints.
FlexibleSolrJerseyResponse jsonQuery(
@Parameter(required = true)
@RequestBody(
required = true,
extensions = {
@Extension(
properties = {
@ExtensionProperty(name = GENERIC_ENTITY_PROPERTY, value = "true")
})
})
InputStream structuredRequest);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import java.util.HashMap;
import java.util.Map;

/** A {@link SolrJerseyResponse} which can accept any top-level properties. */
public class FlexibleSolrJerseyResponse extends SolrJerseyResponse {

private Map<String, Object> unknownFields = new HashMap<>();

@JsonAnyGetter
public Map<String, Object> unknownProperties() {
return unknownFields;
}

@JsonAnySetter
public void setUnknownProperty(String field, Object value) {
unknownFields.put(field, value);
}
}
15 changes: 13 additions & 2 deletions solr/api/src/java/org/apache/solr/client/api/model/StoreType.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
package org.apache.solr.client.api.model;

public enum StoreType {
COLLECTION,
CORE
COLLECTION("collections"),
CORE("cores");

private final String pathString;

StoreType(String pathString) {
this.pathString = pathString;
}

@Override
public String toString() {
return pathString;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ private Constants() {
public static final String STORE_PATH_PREFIX =
"/{" + STORE_TYPE_PATH_PARAMETER + ":cores|collections}/{" + STORE_NAME_PATH_PARAMETER + "}";

public static final String GENERIC_ENTITY_PROPERTY = "genericEntity";

public static final String BINARY_CONTENT_TYPE_V2 = "application/vnd.apache.solr.javabin";
}
33 changes: 29 additions & 4 deletions solr/solrj/src/resources/java-template/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ import {{modelPackage}}.{{dataType}};
// WARNING: This class is generated from a Mustache template; any intended
// changes should be made to the underlying template and not this file directly.

/**
* Experimental SolrRequest's and SolrResponse's for {{classVarName}}, generated from an OAS.
*
* <p>See individual request and response classes for more detailed and relevant information.
*
* <p>All SolrRequest implementations rely on v2 APIs which may require a SolrClient configured to
* use the '/api' path prefix, instead of '/solr'.
*
* @lucene.experimental
*/
public class {{classname}} {

{{#operation}}
Expand Down Expand Up @@ -87,21 +97,29 @@ public class {{classname}} {
{{#requiredParams}}{{^isBodyParam}}* @param {{paramName}} Path param - {{description}}{{/isBodyParam}}
{{/requiredParams}}
*/
public {{operationIdCamelCase}}({{#requiredParams}}{{^isBodyParam}}{{^-first}}, {{/-first}}{{{dataType}}} {{paramName}}{{/isBodyParam}}{{/requiredParams}}) {
public {{operationIdCamelCase}}({{#allParams}}{{#required}}{{^isBodyParam}}{{^-first}}, {{/-first}}{{{dataType}}} {{paramName}}{{/isBodyParam}}{{#isBodyParam}}{{#vendorExtensions.x-genericEntity}}{{^-first}}, {{/-first}}{{{dataType}}} requestBody{{/vendorExtensions.x-genericEntity}}{{/isBodyParam}}{{/required}}{{/allParams}}) {
super(
SolrRequest.METHOD.valueOf("{{httpMethod}}"),
"{{{path}}}"{{#pathParams}}
.replace("{" + "{{baseName}}" + "}", {{paramName}}{{#isEnumRef}}.name(){{/isEnumRef}}){{/pathParams}}
.replace("{" + "{{baseName}}" + "}", {{paramName}}{{^isString}}.toString(){{/isString}}){{/pathParams}}
);

{{#requiredParams}}
{{#isBodyParam}}
{{#vendorExtensions.x-genericEntity}}
this.requestBody = requestBody;
addHeader("Content-type", "application/json");
{{/vendorExtensions.x-genericEntity}}
{{/isBodyParam}}
{{^isBodyParam}}
this.{{paramName}} = {{paramName}};
{{/isBodyParam}}
{{/requiredParams}}
{{#bodyParam}}
this.requestBody = new {{baseName}}();
{{^vendorExtensions.x-genericEntity}}
this.requestBody = new {{{dataType}}}();
addHeader("Content-type", "application/json");
{{/vendorExtensions.x-genericEntity}}
{{/bodyParam}}
}

Expand Down Expand Up @@ -133,7 +151,13 @@ public class {{classname}} {
{{/vars}}

@Override
@SuppressWarnings("unchecked")
public RequestWriter.ContentWriter getContentWriter(String expectedType) {
{{#vendorExtensions.x-genericEntity}}
if (requestBody instanceof String) {
return new RequestWriter.StringPayloadContentWriter((String) requestBody, expectedType);
}
{{/vendorExtensions.x-genericEntity}}
return new JacksonContentWriter(expectedType, requestBody);
}
{{/bodyParam}}
Expand All @@ -149,7 +173,8 @@ public class {{classname}} {
final ModifiableSolrParams params = new ModifiableSolrParams();
{{#queryParams}}
if ({{paramName}} != null) {
params.add("{{baseName}}", {{paramName}}{{^isString}}.toString(){{/isString}});
{{#isArray}}{{paramName}}.stream().forEach(v -> params.add("{{baseName}}", v{{^items.isString}}.toString(){{/items.isString}}));{{/isArray}}
{{^isArray}}params.add("{{baseName}}", {{paramName}}{{^isString}}.toString(){{/isString}});{{/isArray}}
}
{{/queryParams}}
return params;
Expand Down
Loading