Skip to content

Commit c058ea5

Browse files
authored
SOLR-15751: Add v2 COLSTATUS and "segments" APIs (#2912)
COLSTATUS functionality is offered at `GET /api/collections/collName`, and segment functionality at `GET /api/cores/coreName/segments`. This also converts the APIs to JAX-RS, and creates generated SolrRequest bindings for these APIs as a result.
1 parent c2e8388 commit c058ea5

File tree

20 files changed

+1352
-583
lines changed

20 files changed

+1352
-583
lines changed

solr/CHANGES.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ New Features
150150

151151
Improvements
152152
---------------------
153-
(No changes)
153+
* SOLR-15751: The v2 API now has parity with the v1 "COLSTATUS" and "segments" APIs, which can be used to fetch detailed information about
154+
specific collections or cores. Collection information can be fetched by a call to `GET /api/collections/collectionName`, and core
155+
information with a call to `GET /api/cores/coreName/segments`. (Jason Gerlowski)
154156

155157
Optimizations
156158
---------------------
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.endpoint;
18+
19+
import io.swagger.v3.oas.annotations.Operation;
20+
import io.swagger.v3.oas.annotations.Parameter;
21+
import jakarta.ws.rs.GET;
22+
import jakarta.ws.rs.Path;
23+
import jakarta.ws.rs.PathParam;
24+
import jakarta.ws.rs.QueryParam;
25+
import org.apache.solr.client.api.model.CollectionStatusResponse;
26+
27+
/**
28+
* V2 API definition for fetching collection metadata
29+
*
30+
* <p>This API (GET /v2/collections/collectionName) is analogous to the v1
31+
* /admin/collections?action=COLSTATUS command.
32+
*/
33+
@Path("/collections/{collectionName}")
34+
public interface CollectionStatusApi {
35+
36+
// TODO Query parameters currently match those offered by the v1
37+
// /admin/collections?action=COLSTATUS. Should param names be updated/clarified?
38+
@GET
39+
@Operation(
40+
summary = "Fetches metadata about the specified collection",
41+
tags = {"collections"})
42+
CollectionStatusResponse getCollectionStatus(
43+
@Parameter(description = "The name of the collection return metadata for", required = true)
44+
@PathParam("collectionName")
45+
String collectionName,
46+
@Parameter(description = SegmentsApi.CORE_INFO_PARAM_DESC) @QueryParam("coreInfo")
47+
Boolean coreInfo,
48+
@Parameter(
49+
description =
50+
"Boolean flag to include metadata and statistics about the segments used by each shard leader. Implicitly set to true by 'fieldInfo' and 'sizeInfo'")
51+
@QueryParam("segments")
52+
Boolean segments,
53+
@Parameter(
54+
description =
55+
SegmentsApi.FIELD_INFO_PARAM_DESC
56+
+ " Implicitly sets the 'segments' flag to 'true'")
57+
@QueryParam("fieldInfo")
58+
Boolean fieldInfo,
59+
@Parameter(description = SegmentsApi.RAW_SIZE_PARAM_DESC) @QueryParam("rawSize")
60+
Boolean rawSize,
61+
@Parameter(description = SegmentsApi.RAW_SIZE_SUMMARY_DESC) @QueryParam("rawSizeSummary")
62+
Boolean rawSizeSummary,
63+
@Parameter(description = SegmentsApi.RAW_SIZE_DETAILS_DESC) @QueryParam("rawSizeDetails")
64+
Boolean rawSizeDetails,
65+
@Parameter(description = SegmentsApi.RAW_SIZE_SAMPLING_PERCENT_DESC)
66+
@QueryParam("rawSizeSamplingPercent")
67+
Float rawSizeSamplingPercent,
68+
@Parameter(
69+
description =
70+
SegmentsApi.SIZE_INFO_PARAM_DESC
71+
+ ". Implicitly sets the 'segment' flag to 'true'")
72+
@QueryParam("sizeInfo")
73+
Boolean sizeInfo)
74+
throws Exception;
75+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.endpoint;
18+
19+
import io.swagger.v3.oas.annotations.Operation;
20+
import io.swagger.v3.oas.annotations.Parameter;
21+
import jakarta.ws.rs.GET;
22+
import jakarta.ws.rs.Path;
23+
import jakarta.ws.rs.QueryParam;
24+
import org.apache.solr.client.api.model.GetSegmentDataResponse;
25+
import org.apache.solr.client.api.util.CoreApiParameters;
26+
27+
/**
28+
* V2 API definition for fetching metadata about a core's segments
29+
*
30+
* <p>This API (GET /v2/cores/coreName/segments) is analogous to the v1
31+
* /solr/coreName/admin/segments API
32+
*/
33+
@Path("/cores/{coreName}/segments")
34+
public interface SegmentsApi {
35+
36+
String CORE_INFO_PARAM_DESC =
37+
"Boolean flag to include metadata (e.g. index an data directories, IndexWriter configuration, etc.) about each shard leader's core";
38+
String FIELD_INFO_PARAM_DESC =
39+
"Boolean flag to include statistics about the indexed fields present on each shard leader.";
40+
String RAW_SIZE_PARAM_DESC =
41+
"Boolean flag to include simple estimates of the disk size taken up by each field (e.g. \"id\", \"_version_\") and by each index data structure (e.g. 'storedFields', 'docValues_numeric').";
42+
String RAW_SIZE_SUMMARY_DESC =
43+
"Boolean flag to include more involved estimates of the disk size taken up by index data structures, on a per-field basis (e.g. how much data does the \"id\" field contribute to 'storedField' index files). More detail than 'rawSize', less detail than 'rawSizeDetails'.";
44+
String RAW_SIZE_DETAILS_DESC =
45+
"Boolean flag to include detailed statistics about the disk size taken up by various fields and data structures. More detail than 'rawSize' and 'rawSizeSummary'.";
46+
String RAW_SIZE_SAMPLING_PERCENT_DESC =
47+
"Percentage (between 0 and 100) of data to read when estimating index size and statistics. Defaults to 5.0 (i.e. 5%).";
48+
String SIZE_INFO_PARAM_DESC =
49+
"Boolean flag to include information about the largest index files for each Lucene segment.";
50+
51+
@GET
52+
@CoreApiParameters
53+
@Operation(
54+
summary = "Fetches metadata about the segments in use by the specified core",
55+
tags = {"segments"})
56+
GetSegmentDataResponse getSegmentData(
57+
@Parameter(description = CORE_INFO_PARAM_DESC) @QueryParam("coreInfo") Boolean coreInfo,
58+
@Parameter(description = FIELD_INFO_PARAM_DESC) @QueryParam("fieldInfo") Boolean fieldInfo,
59+
@Parameter(description = RAW_SIZE_PARAM_DESC) @QueryParam("rawSize") Boolean rawSize,
60+
@Parameter(description = RAW_SIZE_SUMMARY_DESC) @QueryParam("rawSizeSummary")
61+
Boolean rawSizeSummary,
62+
@Parameter(description = RAW_SIZE_DETAILS_DESC) @QueryParam("rawSizeDetails")
63+
Boolean rawSizeDetails,
64+
@Parameter(description = RAW_SIZE_SAMPLING_PERCENT_DESC) @QueryParam("rawSizeSamplingPercent")
65+
Float rawSizeSamplingPercent,
66+
@Parameter(description = SIZE_INFO_PARAM_DESC) @QueryParam("sizeInfo") Boolean sizeInfo)
67+
throws Exception;
68+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.model;
18+
19+
import com.fasterxml.jackson.annotation.JsonAnyGetter;
20+
import com.fasterxml.jackson.annotation.JsonAnySetter;
21+
import com.fasterxml.jackson.annotation.JsonFormat;
22+
import com.fasterxml.jackson.annotation.JsonProperty;
23+
import java.util.Date;
24+
import java.util.HashMap;
25+
import java.util.List;
26+
import java.util.Map;
27+
28+
/**
29+
* Response of the CollectionStatusApi.getCollectionStatus() API
30+
*
31+
* <p>Note that the corresponding v1 API has a slightly different response format. Users should not
32+
* attempt to convert a v1 response into this type.
33+
*/
34+
public class CollectionStatusResponse extends SolrJerseyResponse {
35+
36+
@JsonProperty public String name;
37+
@JsonProperty public Integer znodeVersion;
38+
39+
// TODO - consider 'Instant' once SOLR-17608 is finished
40+
@JsonProperty
41+
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
42+
public Date creationTimeMillis;
43+
44+
@JsonProperty public CollectionMetadata properties;
45+
@JsonProperty public Integer activeShards;
46+
@JsonProperty public Integer inactiveShards;
47+
@JsonProperty public List<String> schemaNonCompliant;
48+
49+
@JsonProperty public Map<String, ShardMetadata> shards;
50+
51+
// Always present in response
52+
public static class CollectionMetadata {
53+
@JsonProperty public String configName;
54+
@JsonProperty public Integer nrtReplicas;
55+
@JsonProperty public Integer pullReplicas;
56+
@JsonProperty public Integer tlogReplicas;
57+
@JsonProperty public Map<String, String> router;
58+
@JsonProperty public Integer replicationFactor;
59+
60+
private Map<String, Object> unknownFields = new HashMap<>();
61+
62+
@JsonAnyGetter
63+
public Map<String, Object> unknownProperties() {
64+
return unknownFields;
65+
}
66+
67+
@JsonAnySetter
68+
public void setUnknownProperty(String field, Object value) {
69+
unknownFields.put(field, value);
70+
}
71+
}
72+
73+
// Always present in response
74+
public static class ShardMetadata {
75+
@JsonProperty public String state; // TODO Make this an enum?
76+
@JsonProperty public String range;
77+
@JsonProperty public ReplicaSummary replicas;
78+
@JsonProperty public LeaderSummary leader;
79+
}
80+
81+
// Always present in response
82+
public static class ReplicaSummary {
83+
@JsonProperty public Integer total;
84+
@JsonProperty public Integer active;
85+
@JsonProperty public Integer down;
86+
@JsonProperty public Integer recovering;
87+
88+
@JsonProperty("recovery_failed")
89+
public Integer recoveryFailed;
90+
}
91+
92+
// Always present in response unless otherwise specified
93+
public static class LeaderSummary {
94+
@JsonProperty public String coreNode;
95+
@JsonProperty public String core;
96+
@JsonProperty public Boolean leader;
97+
98+
@JsonProperty("node_name")
99+
public String nodeName;
100+
101+
@JsonProperty("base_url")
102+
public String baseUrl;
103+
104+
@JsonProperty public String state; // TODO Make this an enum?
105+
@JsonProperty public String type; // TODO Make this an enum?
106+
107+
@JsonProperty("force_set_state")
108+
public Boolean forceSetState;
109+
110+
// Present with coreInfo=true || sizeInfo=true unless otherwise specified
111+
@JsonProperty public SegmentInfo segInfos;
112+
113+
private Map<String, Object> unknownFields = new HashMap<>();
114+
115+
@JsonAnyGetter
116+
public Map<String, Object> unknownProperties() {
117+
return unknownFields;
118+
}
119+
120+
@JsonAnySetter
121+
public void setUnknownProperty(String field, Object value) {
122+
unknownFields.put(field, value);
123+
}
124+
}
125+
126+
// Present with segments=true || coreInfo=true || sizeInfo=true || fieldInfo=true unless otherwise
127+
// specified
128+
129+
/**
130+
* Same properties as {@link GetSegmentDataResponse}, but uses a different class to avoid
131+
* inheriting "responseHeader", etc.
132+
*/
133+
public static class SegmentInfo {
134+
@JsonProperty public GetSegmentDataResponse.SegmentSummary info;
135+
136+
@JsonProperty public Map<String, Object> runningMerges;
137+
138+
// Present with segments=true || sizeInfo=true || fieldInfo=true
139+
@JsonProperty public Map<String, GetSegmentDataResponse.SingleSegmentData> segments;
140+
141+
// Present with rawSize=true
142+
@JsonProperty public GetSegmentDataResponse.RawSize rawSize;
143+
144+
// Present only with fieldInfo=true
145+
@JsonProperty public List<String> fieldInfoLegend;
146+
}
147+
}

0 commit comments

Comments
 (0)