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

Feature/devtooling-1019 Bulk Contact Management within the Contact Lists resource #1506

Open
wants to merge 41 commits into
base: dev
Choose a base branch
from

Conversation

bbbco
Copy link
Contributor

@bbbco bbbco commented Jan 25, 2025

This PR resolves DEVTOOLING-1019 and makes a major shift away from managing individual contacts as individual resources to consolidating all the contacts in a contact list into a single CSV file that is user managed. These changes use the GC API's export and upload endpoints to enable bulk within the existing genesyscloud_outbound_contact_list resource and provides a seamless migration path with documentation.

Please take extra special note of the schema file, as it includes a number of strategies that I am proposing we continue in future work:

  • Bumping schema version
  • Using CustomizeDiff function for extra validations
  • Setting the hash attribute to computed and managing the computations ourselves (instead of depending on the user to set the sha calculations)
  • When managing bulk items, add a computed record count attribute to track the number of records

Also, due to the nature of this PR and to prevent confusion and/or duplication when exporting contact resources, I took the liberty of removing the contact_list_contact resource exporter in favor of this bulk exporter built into contact_list resource. I added deprecation and migration notices, and added logic to ensure the resource gets tagged in the Deprecated subcategory in the rendered docs.

I have checked this work against Amazon Q. I also used Amazon Q to help me develop extra tests across a number of different functions and libraries and ensured the tests are passing.

bbbco added 30 commits January 8, 2025 09:21
@@ -1,6 +1,10 @@
---
page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
{{ if gt (len (split .Description "[DEPRECATED]")) 1 -}}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

diagErr := util.RetryWhen(util.IsStatus404, func() (*platformclientv2.APIResponse, diag.Diagnostics) {
resp, err := cp.initiateContactListContactsExport(ctx, contactListId)
// Sleep one second before attempting to retrieve export url to give the system time to be able to generate the URL
time.Sleep(time.Second)
Copy link
Collaborator

Choose a reason for hiding this comment

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

will this delay be sufficient ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I saw in my testing that trying to retrieve the export url immediately after the export is initiated would not return. 1 second was plenty of time for the URL to be ready.

genesyscloud/validators/validators.go Show resolved Hide resolved
@@ -18,30 +17,6 @@ import (
"github.com/mypurecloud/platform-client-sdk-go/v150/platformclientv2"
)

func getAllContacts(ctx context.Context, clientConfig *platformclientv2.Configuration) (resourceExporter.ResourceIDMetaMap, diag.Diagnostics) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

the regression would fail for these , for someone who has resource_genesyscloud_outbound_contact_list_contact in their export scripts. which forces them to move to the new resource.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not quite sure what you mean here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @HemanthDogiparthi12 if I understand your concern here, you are concerned that a user that has this resource listed as a resource to export in the include filter would not get anything exported and would wonder why. They would have to then move to export the contact list resource itself instead. No other errors would occur.

This is documented in the resource docs. We can add a deprecation notice to the release as well.

Does this address your concerns? Or is there something I may be missing?

@@ -66,24 +64,14 @@ var (
}
)

func ContactExporter() *resourceExporter.ResourceExporter {
Copy link
Collaborator

Choose a reason for hiding this comment

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

the regression would fail for these , for someone who has resource_genesyscloud_outbound_contact_list_contact in their export scripts. which forces them to move to the new resource.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tested, and if someone has a genesyscloud_outbound_contact_list_contact resource in the filters, it is just ignored.

CustomizeDiff: customdiff.All(
customdiff.ComputedIf("contacts_file_content_hash", files.FileContentHashChanged("contacts_filepath", "contacts_file_content_hash")),
// This function ensures that the contacts file is a CSV file and that it includes the columns defined on the resource
func(ctx context.Context, d *schema.ResourceDiff, _ interface{}) error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we include the function definition to a different util class, instead of having it in the schema section.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

if err != nil {
_, err = url.ParseRequestURI(path)
if err == nil {
resp, err := http.Get(path)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had to refactor this function because a non-existent filepath would get to this line and barf with an error complaining about not having a protocol, which was a red herring. The real issue is that the local file didn't exist. I refactored this function so that we check if the path has a protocol and make the call first, then if not, check to ensure the filepath exists. Also added test cases.

@bbbco bbbco force-pushed the feature/DEVTOOLING-1019v2 branch from bfde88c to 97d2c87 Compare January 31, 2025 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants