package
0.15.1
Repository: https://github.com/cisco-open/go-lanai.git
Documentation: pkg.go.dev

# README

Open Search

Configuration

data:
  opensearch:
    addresses:
      - "http://localhost:9200"
    username: "admin"
    password: "admin"
    tls:
      enable: false
      config:
        type: #this value can either be "file" or "vault"
        min-version: #optional, if omitted, the default value is "tls10"

        # vault type related properties begin
        path:
        role:
        cn:
        ip-sans:
        alt-names:
        ttl:
        min-renew-interval:
        # vault type related properties end

        # file type related properties begin
        ca-cert-file:
        cert-file:
        key-file:
        key-pass:
        # file type related properties end

Testing

When using the opensearch package, developers are encouraged to use WithOpenSearchPlayback, which wraps httpvcr to test. Examples can be found in the go-lanai/pkg/test/opensearchtest/.

When tests are run WithOpenSearchPlayback, it will generate a yml file in a ./testdata directory that stores the outgoing requests and corresponding responses and mock them when the test suite is not in RecordMode.

BodyModifiers can be used to change expected requests/responses - like time.

The vcr will also preappend(with test_) any index names that are passed as options to the Repo[T] interface.

Check out the example test below.

package main

import (
    "testing"
    "github.com/cisco-open/go-lanai/test/dbtest"
    "github.com/cisco-open/go-lanai/test/suitetest"
    "github.com/cisco-open/go-lanai/test"
    "github.com/cisco-open/go-lanai/test/apptest"
    "go.uber.org/fx"
    "github.com/onsi/gomega"
    "github.com/opensearch-project/opensearch-go/opensearchapi"
    "github.com/cisco-open/go-lanai/pkg/opensearch"
    "context"
)

// To enable record mode, uncomment the block of code below
//func TestMain(m *testing.M) {
//	suitetest.RunTests(m,
//		dbtest.EnableDBRecordMode(),
//	)
//}

type FakeService struct {
	Repo opensearch.Repo[someModel]
}

type fakeServiceDI struct {
	fx.In
	Client opensearch.OpenClient
}

func NewFakeService(di fakeServiceDI) FakeService {
	return FakeService{
		Repo: opensearch.NewRepo(&someModel{}, di.Client),
	}
}

type opensearchDI struct {
	fx.In
	FakeService   FakeService
	Properties    *opensearch.Properties
	BodyModifiers *MatcherBodyModifiers
}

func TestScopeController(t *testing.T) {
	di := &opensearchDI{}
	test.RunTest(context.Background(), t,
		apptest.Bootstrap(),
		WithOpenSearchPlayback(
			SetRecordMode(ModeCommandline),
			SetRecordDelay(time.Millisecond*1500), // Used to ensure enough time for db changes to take place
		),
		apptest.WithTimeout(time.Minute),
		apptest.WithModules(opensearch.Module),
		apptest.WithFxOptions(
			fx.Provide(NewFakeService),
		),
		apptest.WithProperties(
			"data.logging.level: debug",
			"log.levels.data: debug",
		),
		apptest.WithDI(di),
		//test.SubTestSetup(SetupOpenSearchTest(di)),
		test.GomegaSubTest(SubTestTemplateAndAlias(di), "SubTestNewBulkIndexer"),
	)
}


func SubTestTemplateAndAlias(di *opensearchDI) test.GomegaSubTestFunc {
	return func(ctx context.Context, t *testing.T, g *gomega.WithT) {
		fakeNewIndexName := "generic_events_1"
		fakeIndexAlias := "generic_event"
		fakeTemplateName := "test_template"
		indexTemplate := map[string]interface{}{
			"index_patterns": []string{"*generic_events*"}, // Pattern needs to accomodate "test_" append
			"template": map[string]interface{}{
				"settings": map[string]interface{}{
					"number_of_shards":   4,
					"number_of_replicas": 4,
				},
			},
			"version": 1,
			"_meta": map[string]interface{}{
				"description": "some description",
			},
		}
		indexMapping := map[string]interface{}{
			"mappings": map[string]interface{}{
				"properties": map[string]interface{}{
					"SubType": map[string]interface{}{
						"type": "text",
					},
				},
			},
		}
		

		// Create a Template
		err := di.FakeService.Repo.IndicesPutIndexTemplate(ctx, fakeTemplateName, indexTemplate)
		if err != nil {
			t.Fatalf("unable to create index template")
		}

		// Create an Index with template pattern
		err = di.FakeService.Repo.IndicesCreate(ctx, fakeNewIndexName, indexMapping)
		if err != nil {
			t.Fatalf("unable to create index")
		}

		// Create an Alias for the template
		err = di.FakeService.Repo.IndicesPutAlias(ctx, []string{fakeNewIndexName}, fakeIndexAlias)
		if err != nil {
			t.Fatalf("unable to create alias ")
		}

		// Get the new index using the Alias and check the obj
		resp, err := di.FakeService.Repo.IndicesGet(ctx, fakeIndexAlias)
		if err != nil {
			t.Fatalf("unable to get indices information using alias ")
		}

		// This test proves that the index template works against the newly created indices
		g.Expect(resp.Settings.Index.NumberOfShards).To(gomega.Equal("4"))

		// Test Cleanup
		// Delete Alias
		err = di.FakeService.Repo.IndicesDeleteAlias(ctx, []string{fakeNewIndexName}, []string{fakeIndexAlias})
		if err != nil {
			t.Fatalf("unable to delete indices alias ")
		}
		// Delete Index Template
		err = di.FakeService.Repo.IndicesDeleteIndexTemplate(ctx, fakeTemplateName)
		if err != nil {
			t.Fatalf("unable to delete index template ")
		}
		// Delete index
		err = di.FakeService.Repo.IndicesDelete(ctx, []string{fakeNewIndexName})
		if err != nil {
			t.Fatalf("unable to delete index ")
		}
	}
}

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
NewRepo will return a OpenSearch repository for any model type T.
No description provided by the author
UnmarshalResponse will take the response, read the body out of it and then place the bytes that were read back into the body so it can be used again after this call.
No description provided by the author
No description provided by the author

# Constants

Will add a document if it doesn't exist or return an error.
Will delete a document if it exists or return a `not_found`.
Will add in a document and will override any duplicate (based on ID).
Will update an existing document if it exists or return an error.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
FxGroup defines the FX group for the OpenSearch.
No description provided by the author
No description provided by the author

# Variables

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

AfterContext is the context given to a AfterHook Options will be in the form *[]func(request *Request){} example: options := make([]func(request *opensearchapi.SearchRequest), 0) AfterContext{Options: &options} Resp and Err can be modified before they are returned out of Request of OpenClientImpl example being OpenClientImpl.Search.
AfterHookBase provides a way to create an AfterHook, similar to AfterHookFunc.
BeforeContext is the context given to a BeforeHook Options will be in the form *[]func(request *Request){}, example: options := make([]func(request *opensearchapi.SearchRequest), 0) BeforeContext{Options: &options}.
BeforeHookBase provides a way to create an BeforeHook, similar to BeforeHookFunc, but in a way that implements the Identifier interface so that it can be removed using the RemoveBeforeHook function.
No description provided by the author
IndicesDetail response follows opensearch spec [format] https://opensearch.org/docs/latest/opensearch/rest-api/index-apis/get-index/#response-body-fields.
No description provided by the author
No description provided by the author
No description provided by the author
SearchResponse modeled after https://opensearch.org/docs/latest/opensearch/rest-api/search/#response-body.
No description provided by the author
Tracer will provide some opensearch.HookContainer to provide tracing.

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

AfterHookFunc provides a way to easily create a AfterHook - however hooks created in this manner are not able to be deleted from the hook slice.
No description provided by the author
BulkAction is intended to be used as an enum type for bulk actions [REF]: https://opensearch.org/docs/1.2/opensearch/rest-api/document-apis/bulk/#request-body.
CommandType lets the hooks know what command is being run.
No description provided by the author