Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Updates search_index resource with new SDK #1848

Merged
merged 14 commits into from
Jan 18, 2024

Conversation

lantoli
Copy link
Member

@lantoli lantoli commented Jan 17, 2024

Description

Updates search_index resource with new SDK.

  • Status added to documentation
  • Testing improved
  • Synonyms, Analyzers, Mapping_Fields can be updated to empty
  • Checked read-only fields: IndexD, Status

Link to any related issue(s): https://jira.mongodb.org/browse/CLOUDP-222718

Type of change:

  • Bug fix (non-breaking change which fixes an issue). Please, add the "bug" label to the PR.
  • New feature (non-breaking change which adds functionality). Please, add the "enhancement" label to the PR.
  • Breaking change (fix or feature that would cause existing functionality to not work as expected). Please, add the "breaking change" label to the PR.
  • This change requires a documentation update
  • Documentation fix/enhancement

Required Checklist:

  • I have signed the MongoDB CLA
  • I have read the contribution guidelines
  • I have checked that this change does not generate any credentials and that they are NOT accidentally logged anywhere.
  • I have added tests that prove my fix is effective or that my feature works per HashiCorp requirements
  • I have added any necessary documentation (if appropriate)
  • I have run make fmt and formatted my code
  • If changes include deprecations or removals, I defined an isolated PR with a relevant title as it will be used in the auto-generated changelog.

Further comments

@lantoli lantoli marked this pull request as ready for review January 17, 2024 16:05
@lantoli lantoli requested a review from a team as a code owner January 17, 2024 16:05
@@ -36,17 +36,21 @@ func IntGreatThan(value int) resource.CheckResourceAttrWithFunc {
}
}

func JSONEquals[T any](value T) resource.CheckResourceAttrWithFunc {
func JSONEquals(expected string) resource.CheckResourceAttrWithFunc {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to make it easier to use

internal/service/searchindex/resource_search_index.go Outdated Show resolved Hide resolved
@@ -396,38 +391,39 @@ func flattenSearchIndexSynonyms(synonyms []admin.SearchSynonymMappingDefinition)

func marshalSearchIndex(fields any) (string, error) {
bytes, err := json.Marshal(fields)
return string(bytes), err
str := string(bytes)
if str == "[]" || str == "{}" { // empty JSON array or object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: why was this check added in these changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because now some fields can be empty arrays or objects instead of nil pointer

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, seems a little hacky to include in this function. Maybe we can check when calling this function that the input parameter is non empty? That way it is clear when the terraform attribute will be left empty.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's really the same idea as we're already doing in the unmarshal functions like:
if str == "" {
return fields, nil
}

not sure about checking this in each caller as we really want always this functionality, i.e. empty arrays to be serialized to empty strings

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it to only check for empty arrays that it's the real need:

if str == "[]" { // empty JSON array serialized to empty string

there is no need to check for empty objects here as it's a local function, in a generic utiliy function it could make sense

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into the usages I struggle to understand why this is now needed vs the previous implementation, taking into account that the input of this function are using the .Get of the SDK to pass a slice (not pointer). Just want to make sure we have no change in behaviour.

Copy link
Member Author

@lantoli lantoli Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the prev. implementation empty arrays were nil but now they are len 0 arrays so they serialize to "[]" when we want to serialize to "".

if we don't do that we get this error:

 Step 1/1 error:  After applying this test step, the plan was not empty.
...
# mongodbatlas_search_index.test will be updated in-place
          ~ resource "mongodbatlas_search_index" "test" {
              - analyzers        = jsonencode([])
...
 resource_search_index_test.go:231: Step 2/2 error: Check failed: Check 2/2 error: mongodbatlas_search_index.test: Attribute 'analyzers' expected "", got "[]"
FAIL

@@ -320,15 +319,39 @@ func resourceMongoDBAtlasSearchIndexRead(ctx context.Context, d *schema.Resource
return diag.Errorf("error setting `analyzer` for search index (%s): %s", d.Id(), err)
}

if analyzers := searchIndex.GetAnalyzers(); len(analyzers) > 0 {
if searchIndex.Type != nil && *searchIndex.Type == vectorSearch {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we changing the order and logic of the if statements here?

Copy link
Member Author

@lantoli lantoli Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now we want to have empty arrays (instead of nil pointers) so for instance they're updated correctly. but depending on the vector type some arrays can't not be sent even empty. basically here we're doing the same logic as we do in Create.

the order is not important, at the end we need to set all fields in any order, the important part is to do different sets depending on the search type

Copy link
Member Author

@lantoli lantoli Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at the end I've returned to the original order and logic following @AgustinBettati advice and using len > 0 again :-)

@@ -396,38 +391,39 @@ func flattenSearchIndexSynonyms(synonyms []admin.SearchSynonymMappingDefinition)

func marshalSearchIndex(fields any) (string, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit test?

Copy link
Member Author

@lantoli lantoli Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a strong opinion but don't know if they add big value here as in other cases because they're local functions that are simple wrappers to json functionality

}

func testAccSearchIndexConfigSynonyms(projectIDStr, indexName, databaseName, clusterNameStr, clusterTerraformStr string) string {
func configSynonyms(projectIDStr, indexName, databaseName, clusterNameStr, clusterTerraformStr string, has bool) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe a better name for has? Unless I am missing something obvious here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's fine I'll rename to configWithSynonyms to be consistent with other functions

@@ -159,7 +152,7 @@ func TestAccSearchIndexRS_withSynonyms(t *testing.T) {
CheckDestroy: acc.CheckDestroySearchIndex,
Steps: []resource.TestStep{
{
Config: testAccSearchIndexConfigSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr),
Config: configSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, true),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nit: but for a good reading style we (not just you) should avoid passing bool values directtly to methods and instead use bool vars that has meaningful names.

Suggested change
Config: configSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, true),
Config: configSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, hasOrIsSomething),

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i hear you. here being configWithSynonyms I thought it could be understood. WDYT about defining constansts:
withSynonyms = true
withoutSynonyms = true

and call like:

configWithSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, withSynonyms),

configWithSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, withoutSynonyms),

or being he function already with "synoyms" on it, what about constant to call:

configWithSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, with),

configWithSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, without),

i see it a bit redundant but maybe it's clearer

),
},
{
Config: configWithSynonyms(clusterInfo.ProjectIDStr, indexName, databaseName, clusterInfo.ClusterNameStr, clusterInfo.ClusterTerraformStr, without),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcosuma using with / without instead of true / false

website/docs/r/search_index.html.markdown Outdated Show resolved Hide resolved
@@ -396,38 +391,39 @@ func flattenSearchIndexSynonyms(synonyms []admin.SearchSynonymMappingDefinition)

func marshalSearchIndex(fields any) (string, error) {
bytes, err := json.Marshal(fields)
return string(bytes), err
str := string(bytes)
if str == "[]" || str == "{}" { // empty JSON array or object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, seems a little hacky to include in this function. Maybe we can check when calling this function that the input parameter is non empty? That way it is clear when the terraform attribute will be left empty.

Copy link
Member

@AgustinBettati AgustinBettati left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lantoli lantoli merged commit f558d61 into master Jan 18, 2024
33 checks passed
@lantoli lantoli deleted the CLOUDP-222718_search_index branch January 18, 2024 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants