Skip to content

Commit dd08f23

Browse files
committed
Fix cat indices API field naming compatibility across OpenSearch versions
OpenSearch 3.2.0 introduced StarTree query fields with naming like: - pri.startree.query_current - pri.startree.query_time - pri.startree.query_total OpenSearch 3.3.0+ standardized these to match other search metrics: - pri.search.startree.query_current - pri.search.startree.query_time - pri.search.startree.query_total This change implements forward-compatible field naming: - Stable fields use the corrected 3.3.0+ naming directly - V32 compatibility fields handle the temporary 3.2.0 naming - consolidateFields() provides automatic fallback for 3.2.0 compatibility - All compatibility code is marked for removal when 3.2.0 support ends Applications can use PrimarySearchStartreeQueryCurrent, PrimarySearchStartreeQueryTime, and PrimarySearchStartreeQueryTotal consistently regardless of server version. Signed-off-by: Sean Chittenden <sean.chittenden@crowdstrike.com>
1 parent 28c34bd commit dd08f23

3 files changed

Lines changed: 150 additions & 152 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
2020
- Fix OpenSearch 3.2.0+ API compatibility by adding max_last_index_request_timestamp and startree query fields across nodes stats, indices stats, and cat APIs, plus settings field to security plugin health API
2121
- Fix OpenSearch 3.3.0+ API compatibility by adding neural_search breaker, query_failed and startree_query_failed search fields, search pipeline system_generated fields across multiple APIs, plus ingestion_status field to cluster state API and jwks_uri field to security config API
2222
- Fix OpenSearch 3.4.0+ API compatibility by adding warmer fields to merges section, parallelism field to thread pool, and status_counter field across multiple APIs
23-
- Fix cat indices API field naming compatibility across OpenSearch versions by implementing field consolidation for startree query fields that changed naming format between 3.1.x and 3.2.0+
23+
- Fix cat indices API field naming compatibility across OpenSearch versions by using forward-compatible field names (PrimarySearchStartreeQuery*) that match the corrected 3.3.0+ naming, with fallback support for the temporary 3.2.0 field names
2424
- Fix cat APIs data type compatibility by changing byte fields from int to string to properly handle values like "0b"
2525
- Fix floating point precision loss in nodes stats concurrent_avg_slice_count field by changing from float32 to float64
2626

opensearchapi/api_cat-indices.go

Lines changed: 74 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -176,67 +176,61 @@ type CatIndexResp struct {
176176
SearchConcurrentAvgSliceCount *string `json:"search.concurrent_avg_slice_count"`
177177
PrimarySearchConcurrentAvgSliceCount *string `json:"pri.search.concurrent_avg_slice_count"`
178178
SearchStartreeQueryCurrent *int `json:"search.startree_query_current,string"` // Available in OpenSearch 3.2.0+
179-
// Consolidated field - populated from V31 or V32 fields
180-
PrimaryStartreeQueryCurrent *int `json:"-"`
181-
// Available in OpenSearch 3.2.0+ (format used in 3.1.x)
182-
PrimaryStartreeQueryCurrentV31 *int `json:"pri.search.startree.query_current,string"`
183-
// Available in OpenSearch 3.2.0+ (new format in 3.2.0+)
184-
PrimaryStartreeQueryCurrentV32 *int `json:"pri.startree.query_current,string"`
185-
SearchStartreeQueryTime *string `json:"search.startree_query_time"` // Available in OpenSearch 3.2.0+
186-
// Consolidated field - populated from V31 or V32 fields
187-
PrimaryStartreeQueryTime *string `json:"-"`
188-
// Available in OpenSearch 3.2.0+ (format used in 3.1.x)
189-
PrimaryStartreeQueryTimeV31 *string `json:"pri.search.startree.query_time"`
190-
// Available in OpenSearch 3.2.0+ (new format in 3.2.0+)
191-
PrimaryStartreeQueryTimeV32 *string `json:"pri.startree.query_time"`
192-
SearchStartreeQueryTotal *string `json:"search.startree_query_total"` // Available in OpenSearch 3.2.0+
193-
// Consolidated field - populated from V31 or V32 fields
194-
PrimaryStartreeQueryTotal *string `json:"-"`
195-
// Available in OpenSearch 3.2.0+ (format used in 3.1.x)
196-
PrimaryStartreeQueryTotalV31 *string `json:"pri.search.startree.query_total"`
197-
// Available in OpenSearch 3.2.0+ (new format in 3.2.0+)
198-
PrimaryStartreeQueryTotalV32 *string `json:"pri.startree.query_total"`
199-
SearchStartreeQueryFailed *int `json:"search.startree_query_failed,string"` // Available in OpenSearch 3.3.0+
200-
PrimaryStartreeQueryFailed *int `json:"pri.search.startree_query_failed,string"` // Available in OpenSearch 3.3.0+
201-
SearchScrollCurrent *int `json:"search.scroll_current,string"`
202-
PrimarySearchScrollCurrent *int `json:"pri.search.scroll_current,string"`
203-
SearchScrollTime *string `json:"search.scroll_time"`
204-
PrimarySearchScrollTime *string `json:"pri.search.scroll_time"`
205-
SearchScrollTotal *int `json:"search.scroll_total,string"`
206-
PrimarySearchScrollTotal *int `json:"pri.search.scroll_total,string"`
207-
SearchPointInTimeCurrent *string `json:"search.point_in_time_current"`
208-
PrimarySearchPointInTimeCurrent *string `json:"pri.search.point_in_time_current"`
209-
SearchPointInTimeTime *string `json:"search.point_in_time_time"`
210-
PrimarySearchPointInTimeTime *string `json:"pri.search.point_in_time_time"`
211-
SearchPointInTimeTotal *int `json:"search.point_in_time_total,string"`
212-
PrimarySearchPointInTimeTotal *int `json:"pri.search.point_in_time_total,string"`
213-
SegmentsCount *int `json:"segments.count,string"`
214-
PrimarySegmentsCount *int `json:"pri.segments.count,string"`
215-
SegmentsMemory *string `json:"segments.memory"`
216-
PrimarySegmentsMemory *string `json:"pri.segments.memory"`
217-
SegmentsIndexWriteMemory *string `json:"segments.index_writer_memory"`
218-
PrimarySegmentsIndexWriteMemory *string `json:"pri.segments.index_writer_memory"`
219-
SegmentsVersionMapMemory *string `json:"segments.version_map_memory"`
220-
PrimarySegmentsVersionMapMemory *string `json:"pri.segments.version_map_memory"`
221-
SegmentsFixedBitsetMemory *string `json:"segments.fixed_bitset_memory"`
222-
PrimarySegmentsFixedBitsetMemory *string `json:"pri.segments.fixed_bitset_memory"`
223-
WarmerCurrent *int `json:"warmer.current,string"`
224-
PrimaryWarmerCurrent *int `json:"pri.warmer.current,string"`
225-
WarmerTotal *int `json:"warmer.total,string"`
226-
PrimaryWarmerTotal *int `json:"pri.warmer.total,string"`
227-
WarmerTotalTime *string `json:"warmer.total_time"`
228-
PrimaryWarmerTotalTime *string `json:"pri.warmer.total_time"`
229-
SuggestCurrent *int `json:"suggest.current,string"`
230-
PrimarySuggestCurrent *int `json:"pri.suggest.current,string"`
231-
SuggestTime *string `json:"suggest.time"`
232-
PrimarySuggestTime *string `json:"pri.suggest.time"`
233-
SuggestTotal *int `json:"suggest.total,string"`
234-
PrimarySuggestTotal *int `json:"pri.suggest.total,string"`
235-
MemoryTotal string `json:"memory.total"`
236-
PrimaryMemoryTotal string `json:"pri.memory.total"`
237-
SearchThrottled bool `json:"search.throttled,string"`
238-
LastIndexRequestTimestamp *string `json:"last_index_request_timestamp"` // Available in OpenSearch 3.2.0+
239-
LastIndexRequestTimestampString *string `json:"last_index_request_timestamp_string"` // Available in OpenSearch 3.2.0+
179+
PrimarySearchStartreeQueryCurrent *int `json:"pri.search.startree.query_current,string"`
180+
// COMPATIBILITY: OpenSearch 3.2.0 used different field naming (pri.startree.* instead of pri.search.startree.*).
181+
// This field can be removed when 3.2.0 support is dropped, along with the consolidateFields() fallback logic.
182+
PrimarySearchStartreeQueryCurrentV32 *int `json:"pri.startree.query_current,string"`
183+
SearchStartreeQueryTime *string `json:"search.startree_query_time"` // Available in OpenSearch 3.2.0+
184+
PrimarySearchStartreeQueryTime *string `json:"pri.search.startree.query_time"`
185+
// COMPATIBILITY: OpenSearch 3.2.0 used different field naming (pri.startree.* instead of pri.search.startree.*).
186+
// This field can be removed when 3.2.0 support is dropped, along with the consolidateFields() fallback logic.
187+
PrimarySearchStartreeQueryTimeV32 *string `json:"pri.startree.query_time"`
188+
SearchStartreeQueryTotal *string `json:"search.startree_query_total"` // Available in OpenSearch 3.2.0+
189+
PrimarySearchStartreeQueryTotal *string `json:"pri.search.startree.query_total"`
190+
// COMPATIBILITY: OpenSearch 3.2.0 used different field naming (pri.startree.* instead of pri.search.startree.*).
191+
// This field can be removed when 3.2.0 support is dropped, along with the consolidateFields() fallback logic.
192+
PrimarySearchStartreeQueryTotalV32 *string `json:"pri.startree.query_total"`
193+
SearchStartreeQueryFailed *int `json:"search.startree_query_failed,string"` // Available in OpenSearch 3.3.0+
194+
PrimaryStartreeQueryFailed *int `json:"pri.search.startree_query_failed,string"` // Available in OpenSearch 3.3.0+
195+
SearchScrollCurrent *int `json:"search.scroll_current,string"`
196+
PrimarySearchScrollCurrent *int `json:"pri.search.scroll_current,string"`
197+
SearchScrollTime *string `json:"search.scroll_time"`
198+
PrimarySearchScrollTime *string `json:"pri.search.scroll_time"`
199+
SearchScrollTotal *int `json:"search.scroll_total,string"`
200+
PrimarySearchScrollTotal *int `json:"pri.search.scroll_total,string"`
201+
SearchPointInTimeCurrent *string `json:"search.point_in_time_current"`
202+
PrimarySearchPointInTimeCurrent *string `json:"pri.search.point_in_time_current"`
203+
SearchPointInTimeTime *string `json:"search.point_in_time_time"`
204+
PrimarySearchPointInTimeTime *string `json:"pri.search.point_in_time_time"`
205+
SearchPointInTimeTotal *int `json:"search.point_in_time_total,string"`
206+
PrimarySearchPointInTimeTotal *int `json:"pri.search.point_in_time_total,string"`
207+
SegmentsCount *int `json:"segments.count,string"`
208+
PrimarySegmentsCount *int `json:"pri.segments.count,string"`
209+
SegmentsMemory *string `json:"segments.memory"`
210+
PrimarySegmentsMemory *string `json:"pri.segments.memory"`
211+
SegmentsIndexWriteMemory *string `json:"segments.index_writer_memory"`
212+
PrimarySegmentsIndexWriteMemory *string `json:"pri.segments.index_writer_memory"`
213+
SegmentsVersionMapMemory *string `json:"segments.version_map_memory"`
214+
PrimarySegmentsVersionMapMemory *string `json:"pri.segments.version_map_memory"`
215+
SegmentsFixedBitsetMemory *string `json:"segments.fixed_bitset_memory"`
216+
PrimarySegmentsFixedBitsetMemory *string `json:"pri.segments.fixed_bitset_memory"`
217+
WarmerCurrent *int `json:"warmer.current,string"`
218+
PrimaryWarmerCurrent *int `json:"pri.warmer.current,string"`
219+
WarmerTotal *int `json:"warmer.total,string"`
220+
PrimaryWarmerTotal *int `json:"pri.warmer.total,string"`
221+
WarmerTotalTime *string `json:"warmer.total_time"`
222+
PrimaryWarmerTotalTime *string `json:"pri.warmer.total_time"`
223+
SuggestCurrent *int `json:"suggest.current,string"`
224+
PrimarySuggestCurrent *int `json:"pri.suggest.current,string"`
225+
SuggestTime *string `json:"suggest.time"`
226+
PrimarySuggestTime *string `json:"pri.suggest.time"`
227+
SuggestTotal *int `json:"suggest.total,string"`
228+
PrimarySuggestTotal *int `json:"pri.suggest.total,string"`
229+
MemoryTotal string `json:"memory.total"`
230+
PrimaryMemoryTotal string `json:"pri.memory.total"`
231+
SearchThrottled bool `json:"search.throttled,string"`
232+
LastIndexRequestTimestamp *string `json:"last_index_request_timestamp"` // Available in OpenSearch 3.2.0+
233+
LastIndexRequestTimestampString *string `json:"last_index_request_timestamp_string"` // Available in OpenSearch 3.2.0+
240234
}
241235

242236
// Inspect returns the Inspect type containing the raw *opensearch.Response
@@ -249,27 +243,31 @@ func (r CatIndicesResp) Inspect() Inspect {
249243
// consolidateFields consolidates version-specific fields for all indices in the response.
250244
// This method should be called after JSON unmarshaling to ensure backward compatibility
251245
// across different OpenSearch server versions that may use different field names.
246+
//
247+
// COMPATIBILITY: This entire function exists only to handle OpenSearch 3.2.0's different
248+
// field naming (pri.startree.* instead of pri.search.startree.*). This function and all
249+
// V32 compatibility fields can be removed when OpenSearch 3.2.0 support is dropped.
252250
func (r *CatIndicesResp) consolidateFields() {
253251
for i := range r.Indices {
254-
// Consolidate PrimaryStartreeQueryCurrent from V31 or V32 fields
255-
if r.Indices[i].PrimaryStartreeQueryCurrentV31 != nil && *r.Indices[i].PrimaryStartreeQueryCurrentV31 != 0 {
256-
r.Indices[i].PrimaryStartreeQueryCurrent = r.Indices[i].PrimaryStartreeQueryCurrentV31
257-
} else if r.Indices[i].PrimaryStartreeQueryCurrentV32 != nil {
258-
r.Indices[i].PrimaryStartreeQueryCurrent = r.Indices[i].PrimaryStartreeQueryCurrentV32
252+
// PrimarySearchStartreeQueryCurrent: Fallback to V32 field if stable field is nil/zero
253+
if r.Indices[i].PrimarySearchStartreeQueryCurrent == nil || *r.Indices[i].PrimarySearchStartreeQueryCurrent == 0 {
254+
if r.Indices[i].PrimarySearchStartreeQueryCurrentV32 != nil {
255+
r.Indices[i].PrimarySearchStartreeQueryCurrent = r.Indices[i].PrimarySearchStartreeQueryCurrentV32
256+
}
259257
}
260258

261-
// Consolidate PrimaryStartreeQueryTime from V31 or V32 fields
262-
if r.Indices[i].PrimaryStartreeQueryTimeV31 != nil && *r.Indices[i].PrimaryStartreeQueryTimeV31 != "" {
263-
r.Indices[i].PrimaryStartreeQueryTime = r.Indices[i].PrimaryStartreeQueryTimeV31
264-
} else if r.Indices[i].PrimaryStartreeQueryTimeV32 != nil {
265-
r.Indices[i].PrimaryStartreeQueryTime = r.Indices[i].PrimaryStartreeQueryTimeV32
259+
// PrimarySearchStartreeQueryTime: Fallback to V32 field if stable field is nil/empty
260+
if r.Indices[i].PrimarySearchStartreeQueryTime == nil || *r.Indices[i].PrimarySearchStartreeQueryTime == "" {
261+
if r.Indices[i].PrimarySearchStartreeQueryTimeV32 != nil {
262+
r.Indices[i].PrimarySearchStartreeQueryTime = r.Indices[i].PrimarySearchStartreeQueryTimeV32
263+
}
266264
}
267265

268-
// Consolidate PrimaryStartreeQueryTotal from V31 or V32 fields
269-
if r.Indices[i].PrimaryStartreeQueryTotalV31 != nil && *r.Indices[i].PrimaryStartreeQueryTotalV31 != "" {
270-
r.Indices[i].PrimaryStartreeQueryTotal = r.Indices[i].PrimaryStartreeQueryTotalV31
271-
} else if r.Indices[i].PrimaryStartreeQueryTotalV32 != nil {
272-
r.Indices[i].PrimaryStartreeQueryTotal = r.Indices[i].PrimaryStartreeQueryTotalV32
266+
// PrimarySearchStartreeQueryTotal: Fallback to V32 field if stable field is nil/empty
267+
if r.Indices[i].PrimarySearchStartreeQueryTotal == nil || *r.Indices[i].PrimarySearchStartreeQueryTotal == "" {
268+
if r.Indices[i].PrimarySearchStartreeQueryTotalV32 != nil {
269+
r.Indices[i].PrimarySearchStartreeQueryTotal = r.Indices[i].PrimarySearchStartreeQueryTotalV32
270+
}
273271
}
274272
}
275273
}

0 commit comments

Comments
 (0)