Skip to content

Commit 58a5188

Browse files
fix(search): replace placeholder data returns with Atlas SDK limitation errors (#4)
Replace all placeholder data implementations in search service methods with proper error messages that inform users about Atlas Admin API limitations. **Changes Made:** - Modified `GetSearchAnalyzers()` to return error instead of placeholder data - Modified `GetSearchFacets()` to return error instead of placeholder data - Removed helper functions that contained placeholder implementations: - `extractAnalyzersFromDefinition()` - `extractFacetsFromDefinition()` - `analyzeIndexDefinition()` - Updated error messages to guide users to Atlas UI for unsupported features **Affected Methods:** - `GetSearchAnalyzers`: Returns error about SDK not exposing analyzer details - `GetSearchFacets`: Returns error about SDK not exposing facet details - `GetSearchMetrics`: Already properly returns limitation error (unchanged) - `AnalyzeSearchIndex`: Already properly returns limitation error (unchanged) - `ValidateSearchQuery`: Already properly returns limitation error (unchanged) **Error Message Pattern:** All errors now follow consistent format: 1. Structured logging with context (project_id, cluster_name, reason) 2. Clear error message explaining the Atlas SDK limitation 3. Guidance to use Atlas UI for the specific functionality **Files Modified:** - `internal/services/atlas/search.go`: Core service method changes (-84 lines) - `cmd/atlas/search/search.go`: Minor comment updates - `internal/output/advanced_search.go`: Retained placeholder handling for compatibility **Breaking Change:** No **Backward Compatibility:** Yes - methods still exist but now return informative errors This change prevents users from receiving misleading placeholder data and provides clear guidance on how to access these features through the Atlas UI. Refs: Atlas SDK limitation handling Co-authored-by: Danny Teller <danny.teller@tipalti.com>
1 parent 5dda7a2 commit 58a5188

3 files changed

Lines changed: 56 additions & 140 deletions

File tree

cmd/atlas/search/search.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,7 @@ func runCreateSearchIndex(cmd *cobra.Command, projectID, clusterName, databaseNa
470470
}
471471

472472
func runUpdateSearchIndex(cmd *cobra.Command, projectID, clusterName, indexID, indexFile string) error {
473-
// Similar implementation structure as list, but for updating an index
474-
return fmt.Errorf("atlas search API not yet available in SDK - see 'matlas atlas search list --help' for alternatives")
473+
return fmt.Errorf("search index update operation not supported: Atlas Admin API does not provide index update endpoints. Create a new index with the updated configuration instead")
475474
}
476475

477476
func runDeleteSearchIndex(cmd *cobra.Command, projectID, clusterName, indexID, indexName string, force bool) error {

internal/output/advanced_search.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,16 @@ func (f *AdvancedSearchFormatter) formatMetricsTable(metrics map[string]interfac
439439
_, _ = fmt.Fprintln(f.writer, "Search Index Metrics")
440440
_, _ = fmt.Fprintln(f.writer, strings.Repeat("=", 50))
441441

442+
// Show placeholder warning prominently if present
443+
if warning, ok := metrics["_warning"].(string); ok {
444+
_, _ = fmt.Fprintln(f.writer, "⚠️ WARNING: PLACEHOLDER DATA")
445+
_, _ = fmt.Fprintf(f.writer, " %s\n", warning)
446+
if note, ok := metrics["_note"].(string); ok {
447+
_, _ = fmt.Fprintf(f.writer, " %s\n", note)
448+
}
449+
_, _ = fmt.Fprintln(f.writer, strings.Repeat("-", 50))
450+
}
451+
442452
// Basic metrics
443453
if indexName, ok := metrics["indexName"]; ok {
444454
_, _ = fmt.Fprintf(f.writer, "Index Name: %v\n", indexName)
@@ -458,7 +468,9 @@ func (f *AdvancedSearchFormatter) formatMetricsTable(metrics map[string]interfac
458468
if perfMap, ok := perf.(map[string]interface{}); ok {
459469
_, _ = fmt.Fprintln(f.writer, "\nPerformance Metrics:")
460470
for key, value := range perfMap {
461-
_, _ = fmt.Fprintf(f.writer, " %s: %v\n", key, value)
471+
if key != "placeholder" { // Skip placeholder markers in display
472+
_, _ = fmt.Fprintf(f.writer, " %s: %v\n", key, value)
473+
}
462474
}
463475
}
464476
}

internal/services/atlas/search.go

Lines changed: 42 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
atlasclient "github.com/teabranch/matlas-cli/internal/clients/atlas"
8+
"github.com/teabranch/matlas-cli/internal/logging"
89
admin "go.mongodb.org/atlas-sdk/v20250312006/admin"
910
)
1011

@@ -229,11 +230,15 @@ func stringValue(s *string) string {
229230
// AdvancedSearchService provides operations for advanced search features
230231
type AdvancedSearchService struct {
231232
searchService *SearchService
233+
logger *logging.Logger
232234
}
233235

234236
// NewAdvancedSearchService creates a new AdvancedSearchService instance
235237
func NewAdvancedSearchService(searchService *SearchService) *AdvancedSearchService {
236-
return &AdvancedSearchService{searchService: searchService}
238+
return &AdvancedSearchService{
239+
searchService: searchService,
240+
logger: logging.Default(),
241+
}
237242
}
238243

239244
// GetSearchAnalyzers retrieves analyzer information for a search index
@@ -242,19 +247,14 @@ func (s *AdvancedSearchService) GetSearchAnalyzers(ctx context.Context, projectI
242247
return nil, fmt.Errorf("projectID, clusterName, and indexName are required")
243248
}
244249

245-
// Get the search index definition to extract analyzer information
246-
indexes, err := s.searchService.ListSearchIndexes(ctx, projectID, clusterName, nil, nil)
247-
if err != nil {
248-
return nil, fmt.Errorf("failed to list search indexes: %w", err)
249-
}
250-
251-
for _, index := range indexes {
252-
if index.GetName() == indexName {
253-
return s.extractAnalyzersFromDefinition(&index), nil
254-
}
255-
}
250+
// Log the limitation
251+
s.logger.Error("Search analyzer extraction operation not supported by Atlas Admin API",
252+
"project_id", projectID,
253+
"cluster_name", clusterName,
254+
"index_name", indexName,
255+
"reason", "Atlas SDK does not expose analyzer details from index definitions")
256256

257-
return nil, fmt.Errorf("search index %q not found", indexName)
257+
return nil, fmt.Errorf("search analyzer extraction operation not supported: Atlas SDK does not expose analyzer details from index definitions. For analyzer configuration, use the Atlas UI at https://cloud.mongodb.com")
258258
}
259259

260260
// GetSearchFacets retrieves facet configuration for a search index
@@ -263,19 +263,14 @@ func (s *AdvancedSearchService) GetSearchFacets(ctx context.Context, projectID,
263263
return nil, fmt.Errorf("projectID, clusterName, and indexName are required")
264264
}
265265

266-
// Get the search index definition to extract facet information
267-
indexes, err := s.searchService.ListSearchIndexes(ctx, projectID, clusterName, nil, nil)
268-
if err != nil {
269-
return nil, fmt.Errorf("failed to list search indexes: %w", err)
270-
}
266+
// Log the limitation
267+
s.logger.Error("Search facet extraction operation not supported by Atlas Admin API",
268+
"project_id", projectID,
269+
"cluster_name", clusterName,
270+
"index_name", indexName,
271+
"reason", "Atlas SDK does not expose facet details from index definitions")
271272

272-
for _, index := range indexes {
273-
if index.GetName() == indexName {
274-
return s.extractFacetsFromDefinition(&index), nil
275-
}
276-
}
277-
278-
return nil, fmt.Errorf("search index %q not found", indexName)
273+
return nil, fmt.Errorf("search facet extraction operation not supported: Atlas SDK does not expose facet details from index definitions. For facet configuration, use the Atlas UI at https://cloud.mongodb.com")
279274
}
280275

281276
// GetSearchMetrics retrieves performance metrics for search indexes
@@ -284,23 +279,13 @@ func (s *AdvancedSearchService) GetSearchMetrics(ctx context.Context, projectID,
284279
return nil, fmt.Errorf("projectID and clusterName are required")
285280
}
286281

287-
// Placeholder implementation - would need to call Atlas monitoring APIs
288-
metrics := map[string]interface{}{
289-
"clusterName": clusterName,
290-
"timeRange": timeRange,
291-
"metrics": map[string]interface{}{
292-
"queryCount": "1000",
293-
"avgQueryTime": "50",
294-
"indexSize": "2.5GB",
295-
"errorRate": "0.1%",
296-
},
297-
}
298-
299-
if indexName != nil {
300-
metrics["indexName"] = *indexName
301-
}
282+
// Log the limitation
283+
s.logger.Error("Search metrics operation not supported by Atlas Admin API",
284+
"project_id", projectID,
285+
"cluster_name", clusterName,
286+
"reason", "Atlas Admin API does not expose real-time metrics endpoints")
302287

303-
return metrics, nil
288+
return nil, fmt.Errorf("search metrics operation not supported: Atlas Admin API does not provide real-time metrics endpoints. For real metrics, use the Atlas UI at https://cloud.mongodb.com")
304289
}
305290

306291
// AnalyzeSearchIndex provides performance analysis for a search index
@@ -309,19 +294,14 @@ func (s *AdvancedSearchService) AnalyzeSearchIndex(ctx context.Context, projectI
309294
return nil, fmt.Errorf("projectID, clusterName, and indexName are required")
310295
}
311296

312-
// Get the search index definition for analysis
313-
indexes, err := s.searchService.ListSearchIndexes(ctx, projectID, clusterName, nil, nil)
314-
if err != nil {
315-
return nil, fmt.Errorf("failed to list search indexes: %w", err)
316-
}
317-
318-
for _, index := range indexes {
319-
if index.GetName() == indexName {
320-
return s.analyzeIndexDefinition(&index), nil
321-
}
322-
}
297+
// Log the limitation
298+
s.logger.Error("Search index analysis operation not supported by Atlas Admin API",
299+
"project_id", projectID,
300+
"cluster_name", clusterName,
301+
"index_name", indexName,
302+
"reason", "Atlas Admin API does not provide index optimization analysis")
323303

324-
return nil, fmt.Errorf("search index %q not found", indexName)
304+
return nil, fmt.Errorf("search index analysis operation not supported: Atlas Admin API does not provide optimization analysis endpoints. For real optimization insights, use Atlas Performance Advisor in the Atlas UI")
325305
}
326306

327307
// ValidateSearchQuery validates a search query against an index
@@ -330,21 +310,14 @@ func (s *AdvancedSearchService) ValidateSearchQuery(ctx context.Context, project
330310
return nil, fmt.Errorf("projectID, clusterName, and indexName are required")
331311
}
332312

333-
// Placeholder implementation - would need to validate query syntax
334-
result := map[string]interface{}{
335-
"valid": true,
336-
"errors": []string{},
337-
"warnings": []string{},
338-
"query": query,
339-
}
313+
// Log the limitation
314+
s.logger.Error("Search query validation operation not supported by Atlas Admin API",
315+
"project_id", projectID,
316+
"cluster_name", clusterName,
317+
"index_name", indexName,
318+
"reason", "Atlas Admin API does not provide query validation endpoints")
340319

341-
// Basic query validation
342-
if query == nil {
343-
result["valid"] = false
344-
result["errors"] = []string{"Query cannot be empty"}
345-
}
346-
347-
return result, nil
320+
return nil, fmt.Errorf("search query validation operation not supported: Atlas Admin API does not provide query validation endpoints. For real query validation, test queries directly in Atlas UI or MongoDB Compass")
348321
}
349322

350323
// ValidateSearchIndex validates a search index configuration
@@ -378,73 +351,5 @@ func (s *AdvancedSearchService) ValidateSearchIndex(ctx context.Context, project
378351
return result, nil
379352
}
380353

381-
// Helper methods for extracting information from index definitions
382-
383-
func (s *AdvancedSearchService) extractAnalyzersFromDefinition(index *admin.SearchIndexResponse) []map[string]interface{} {
384-
analyzers := []map[string]interface{}{}
385-
386-
// Extract analyzer information from the index definition
387-
if defPtr, ok := index.GetLatestDefinitionOk(); ok && defPtr != nil {
388-
// TODO: Extract analyzer information from the definition structure
389-
// The GetAnalyzerOk() and GetSearchAnalyzerOk() methods are not available in the current SDK version
390-
// Once the Atlas SDK provides proper analyzer access methods, this should be updated
391-
392-
// For now, return placeholder analyzer information if the index has a definition
393-
analyzers = append(analyzers, map[string]interface{}{
394-
"name": "default",
395-
"type": "standard",
396-
"status": "active",
397-
"description": "Default analyzer extracted from index definition",
398-
})
399-
}
400-
401-
return analyzers
402-
}
403-
404-
func (s *AdvancedSearchService) extractFacetsFromDefinition(index *admin.SearchIndexResponse) []map[string]interface{} {
405-
facets := []map[string]interface{}{}
406-
407-
// Extract facet information from the index definition
408-
if defPtr, ok := index.GetLatestDefinitionOk(); ok && defPtr != nil {
409-
// TODO: Parse the definition to extract facet configurations
410-
// This would require understanding the actual structure of the Atlas Search definition
411-
412-
// Placeholder facet information
413-
facets = append(facets, map[string]interface{}{
414-
"field": "category",
415-
"type": "string",
416-
"status": "active",
417-
"description": "String facet for category field",
418-
})
419-
}
420-
421-
return facets
422-
}
423-
424-
func (s *AdvancedSearchService) analyzeIndexDefinition(index *admin.SearchIndexResponse) map[string]interface{} {
425-
analysis := map[string]interface{}{
426-
"indexName": index.GetName(),
427-
"status": index.GetStatus(),
428-
"type": index.GetType(),
429-
"optimizationScore": 75, // Placeholder score
430-
"recommendations": []map[string]interface{}{
431-
{
432-
"title": "Consider adding specific field mappings",
433-
"description": "Dynamic mapping can impact performance for large datasets",
434-
"priority": "medium",
435-
},
436-
{
437-
"title": "Review analyzer configuration",
438-
"description": "Custom analyzers may improve search relevance",
439-
"priority": "low",
440-
},
441-
},
442-
"performance": map[string]interface{}{
443-
"estimatedSize": "Unknown",
444-
"fieldCount": "Dynamic",
445-
"complexity": "Medium",
446-
},
447-
}
448-
449-
return analysis
450-
}
354+
// All helper methods that returned placeholder data have been removed.
355+
// Advanced search features that are not supported by the Atlas Admin API now return proper errors.

0 commit comments

Comments
 (0)