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

Merged
merged 42 commits into from
Feb 6, 2025
Merged
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
216cdf4
Init
bbbco Jan 8, 2025
e6fd222
Updates
bbbco Jan 9, 2025
ace6f6a
Updates
bbbco Jan 15, 2025
18c9b69
Use contactlist proxy for contact list contacts
bbbco Jan 16, 2025
20fd65e
It compiles!
bbbco Jan 17, 2025
7577f91
Merge branch 'dev' into feature/DEVTOOLING-1019
bbbco Jan 17, 2025
f11b4de
Add handling for exporting
bbbco Jan 17, 2025
4a61ab3
Address a few syntax issues
bbbco Jan 17, 2025
ed65a38
Some updates
bbbco Jan 17, 2025
1d147e5
It builds, compiles, and passes tests
bbbco Jan 21, 2025
1e57d4e
Merge branch 'dev' into feature/DEVTOOLING-1019
bbbco Jan 21, 2025
18da2da
Merge branch 'dev' into feature/DEVTOOLING-1019
bbbco Jan 22, 2025
3db08f0
Get export working
bbbco Jan 22, 2025
962fb98
Initial updates to merge resource into the contact list resource
bbbco Jan 23, 2025
fad679f
Refactor contact list resource to allow bulk uploads of contact list …
bbbco Jan 23, 2025
969cc1d
Updates to ensure valid CSV file is passed in
bbbco Jan 24, 2025
c5a3ad1
Remove superfoluous extra resource that has now been assimilated into…
bbbco Jan 24, 2025
cdd6c76
Remove exporter functionality from outbound_contact_list_contact reso…
bbbco Jan 24, 2025
7c02784
Support generating deprecated resource subcategories: https://develop…
bbbco Jan 24, 2025
4a8b593
Everything works with functional tests
bbbco Jan 24, 2025
e67dc4f
Trim whitespace tweak
bbbco Jan 24, 2025
5a51b84
Add retry functionality for export
bbbco Jan 24, 2025
82e5959
Merge branch 'dev' into feature/DEVTOOLING-1019v2
bbbco Jan 24, 2025
3ab33d3
Handle responses from downloadoropen() so they can be retried if 400
bbbco Jan 24, 2025
4fc9263
Amazon Q suggestions
bbbco Jan 25, 2025
0b6e643
Amazon Q updates
bbbco Jan 25, 2025
fbe9bb4
Amazon Q recommendations for documentation
bbbco Jan 25, 2025
50b12da
Fix perm issue
bbbco Jan 25, 2025
d259487
Amazon Q analysis
bbbco Jan 25, 2025
ef1e9d5
Extra comment
bbbco Jan 25, 2025
1c12039
Sleep a bit before retrying to export/download
bbbco Jan 25, 2025
5405465
Add export initiate/get retries
bbbco Jan 25, 2025
dccba09
Updates per PR
bbbco Jan 29, 2025
011fe8b
GetTestDataPath updates
bbbco Jan 29, 2025
9ee9553
Make test data organization more consistent
bbbco Jan 30, 2025
bce0de9
Merge branch 'dev' into feature/DEVTOOLING-1019v2
bbbco Jan 30, 2025
234b222
Harden some tests
bbbco Jan 31, 2025
97d2c87
Merge branch 'dev' into feature/DEVTOOLING-1019v2
bbbco Jan 31, 2025
5b1383b
Fix journey tests
bbbco Jan 31, 2025
9aa9455
Fix Journey tests
bbbco Jan 31, 2025
385e576
Journey test fix again
bbbco Feb 1, 2025
7280e94
Merge branch 'dev' into feature/DEVTOOLING-1019v2
bbbco Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Handle responses from downloadoropen() so they can be retried if 400
bbbco committed Jan 24, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 3ab33d338b7da96dfb87ee34c33a5a071e2b166a
Original file line number Diff line number Diff line change
@@ -177,7 +177,7 @@ func (d *grammarLanguageDownloader) downloadFileData(fileType FileType) error {
func (d *grammarLanguageDownloader) downloadLanguageFileAndUpdateConfigMap(url string) error {
d.fileUrl = url
d.setExportFileName()
if err := files.DownloadExportFile(d.exportFilesFolderPath, d.exportFileName, d.fileUrl); err != nil {
if _, err := files.DownloadExportFile(d.exportFilesFolderPath, d.exportFileName, d.fileUrl); err != nil {
return err
}
d.updatePathsInExportConfigMap()
Original file line number Diff line number Diff line change
@@ -199,7 +199,7 @@ func ArchitectPromptAudioResolver(promptId, exportDirectory, subDirectory string

for _, data := range audioDataList {
log.Printf("Downloading file '%s' from mediaUri", path.Join(fullPath, data.FileName))
if err := files.DownloadExportFile(fullPath, data.FileName, data.MediaUri); err != nil {
if _, err := files.DownloadExportFile(fullPath, data.FileName, data.MediaUri); err != nil {
return err
}
log.Println("Successfully downloaded file")
Original file line number Diff line number Diff line change
@@ -194,18 +194,18 @@ func ContactsExporterResolver(resourceId, exportDirectory, subDirectory string,
exportFileName := fmt.Sprintf("%s.csv", contactListName)

fullDirectoryPath := path.Join(exportDirectory, subDirectory)
if err := os.MkdirAll(fullDirectoryPath, os.ModePerm); err != nil {
if err := os.MkdirAll(fullDirectoryPath, 0600); err != nil {
return err
}

ctx := context.Background()
diagErr := util.RetryWhen(util.IsStatus400, func() (*platformclientv2.APIResponse, diag.Diagnostics) {
url, _, err := cp.getContactListContactsExportUrl(ctx, contactListId)
url, resp, err := cp.getContactListContactsExportUrl(ctx, contactListId)
if err != nil {
return nil, diag.FromErr(err)
return resp, diag.FromErr(err)
}
if err := files.DownloadExportFileWithAccessToken(fullDirectoryPath, exportFileName, url, sdkConfig.AccessToken); err != nil {
return nil, diag.FromErr(err)
if resp, err = files.DownloadExportFileWithAccessToken(fullDirectoryPath, exportFileName, url, sdkConfig.AccessToken); err != nil {
return resp, diag.FromErr(err)
}
return nil, nil
})
@@ -214,7 +214,9 @@ func ContactsExporterResolver(resourceId, exportDirectory, subDirectory string,
return fmt.Errorf(`Error retrieving exported contacts: %v`, diagErr)
}

// amazonq-ignore-next-line
fullCurrentPath := path.Join(fullDirectoryPath, exportFileName)
// amazonq-ignore-next-line
fullRelativePath := path.Join(subDirectory, exportFileName)
configMap["contacts_filepath"] = fullRelativePath
configMap["contacts_id_name"] = "inin-outbound-id"
Original file line number Diff line number Diff line change
@@ -585,12 +585,13 @@ func TestContactListContactsExporterResolver(t *testing.T) {

// Mock the file download function
origDownloadFile := files.DownloadExportFileWithAccessToken
files.DownloadExportFileWithAccessToken = func(directory, filename, url, accessToken string) error {
files.DownloadExportFileWithAccessToken = func(directory, filename, url, accessToken string) (*platformclientv2.APIResponse, error) {
fullPath := path.Join(directory, filename)
if err := os.MkdirAll(directory, os.ModePerm); err != nil {
return err
return nil, err
}
return os.WriteFile(fullPath, []byte("test content"), 0644)
os.WriteFile(fullPath, []byte("test content"), 0644)
return nil, nil
}
defer func() { files.DownloadExportFileWithAccessToken = origDownloadFile }()

@@ -683,8 +684,8 @@ func TestContactListContactsExporterResolver(t *testing.T) {
}

// Mock download failure
files.DownloadExportFileWithAccessToken = func(directory, filename, url, accessToken string) error {
return fmt.Errorf("download failed")
files.DownloadExportFileWithAccessToken = func(directory, filename, url, accessToken string) (*platformclientv2.APIResponse, error) {
return nil, fmt.Errorf("download failed")
}

err := ContactsExporterResolver("test-id", tempDir, subDir, configMap, mockMeta, mockResource)
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ func responsemanagementResponseassetResolver(responseAssetId, exportDirectory, s
fileName := fmt.Sprintf("%s-%s%s", baseName, responseAssetId, filepath.Ext(*data.Name))
exportFilename := path.Join(subDirectory, fileName)

if err := files.DownloadExportFile(fullPath, fileName, *data.ContentLocation); err != nil {
if _, err := files.DownloadExportFile(fullPath, fileName, *data.ContentLocation); err != nil {
return err
}
configMap["filename"] = exportFilename
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ func ScriptResolver(scriptId, exportDirectory, subDirectory string, configMap ma
return err
}

if err := files.DownloadExportFile(fullPath, exportFileName, url); err != nil {
if _, err := files.DownloadExportFile(fullPath, exportFileName, url); err != nil {
return err
}

17 changes: 11 additions & 6 deletions genesyscloud/util/files/util_files.go
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/mypurecloud/platform-client-sdk-go/v150/platformclientv2"
)

type S3Uploader struct {
@@ -214,38 +215,42 @@ func DownloadOrOpenFile(path string) (io.Reader, *os.File, error) {
// without actually downloading files.
var DownloadExportFile = downloadExportFile

func downloadExportFile(directory, fileName, uri string) error {
func downloadExportFile(directory, fileName, uri string) (*platformclientv2.APIResponse, error) {
return downloadExportFileWithAccessToken(directory, fileName, uri, "")
}

var DownloadExportFileWithAccessToken = downloadExportFileWithAccessToken

func downloadExportFileWithAccessToken(directory, fileName, uri, accessToken string) error {
func downloadExportFileWithAccessToken(directory, fileName, uri, accessToken string) (*platformclientv2.APIResponse, error) {
client := &http.Client{}

req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return err
return nil, err
}

if accessToken != "" {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
}

resp, err := client.Do(req)
apiResp, apiErr := platformclientv2.NewAPIResponse(resp, nil)
if err != nil {
return err
return apiResp, err
}
if apiErr != nil {
return apiResp, apiErr
}
defer resp.Body.Close()

out, err := os.Create(path.Join(directory, fileName))
if err != nil {
return err
return apiResp, err
}
defer out.Close()

_, err = io.Copy(out, resp.Body)
return err
return apiResp, err
}

// Hash file content, used in stateFunc for "filepath" type attributes