code.gitea.io/gitea@v1.22.3/modules/indexer/internal/elasticsearch/indexer.go (about)

     1  // Copyright 2023 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package elasticsearch
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"code.gitea.io/gitea/modules/indexer/internal"
    11  
    12  	"github.com/olivere/elastic/v7"
    13  )
    14  
    15  var _ internal.Indexer = &Indexer{}
    16  
    17  // Indexer represents a basic elasticsearch indexer implementation
    18  type Indexer struct {
    19  	Client *elastic.Client
    20  
    21  	url       string
    22  	indexName string
    23  	version   int
    24  	mapping   string
    25  }
    26  
    27  func NewIndexer(url, indexName string, version int, mapping string) *Indexer {
    28  	return &Indexer{
    29  		url:       url,
    30  		indexName: indexName,
    31  		version:   version,
    32  		mapping:   mapping,
    33  	}
    34  }
    35  
    36  // Init initializes the indexer
    37  func (i *Indexer) Init(ctx context.Context) (bool, error) {
    38  	if i == nil {
    39  		return false, fmt.Errorf("cannot init nil indexer")
    40  	}
    41  	if i.Client != nil {
    42  		return false, fmt.Errorf("indexer is already initialized")
    43  	}
    44  
    45  	client, err := i.initClient()
    46  	if err != nil {
    47  		return false, err
    48  	}
    49  	i.Client = client
    50  
    51  	exists, err := i.Client.IndexExists(i.VersionedIndexName()).Do(ctx)
    52  	if err != nil {
    53  		return false, err
    54  	}
    55  	if exists {
    56  		return true, nil
    57  	}
    58  
    59  	if err := i.createIndex(ctx); err != nil {
    60  		return false, err
    61  	}
    62  
    63  	return exists, nil
    64  }
    65  
    66  // Ping checks if the indexer is available
    67  func (i *Indexer) Ping(ctx context.Context) error {
    68  	if i == nil {
    69  		return fmt.Errorf("cannot ping nil indexer")
    70  	}
    71  	if i.Client == nil {
    72  		return fmt.Errorf("indexer is not initialized")
    73  	}
    74  
    75  	resp, err := i.Client.ClusterHealth().Do(ctx)
    76  	if err != nil {
    77  		return err
    78  	}
    79  	if resp.Status != "green" && resp.Status != "yellow" {
    80  		// It's healthy if the status is green, and it's available if the status is yellow,
    81  		// see https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html
    82  		return fmt.Errorf("status of elasticsearch cluster is %s", resp.Status)
    83  	}
    84  	return nil
    85  }
    86  
    87  // Close closes the indexer
    88  func (i *Indexer) Close() {
    89  	if i == nil {
    90  		return
    91  	}
    92  	i.Client = nil
    93  }