public TableauMigrationService(
            IOptionsMonitor <TableauMigrationSettings> settingsMonitor,
            ITableauApiServiceSource tableauApiServiceSource,
            ITableauApiServiceDestination tableauApiServiceDestination,
            IVizDatasourceService vizDatasourceService,
            ILogger logger = null
            )
        {
            _settingsMonitor              = settingsMonitor ?? throw new ArgumentNullException("Missing Tableau Migration settings");
            _tableauApiServiceSource      = tableauApiServiceSource;
            _tableauApiServiceDestination = tableauApiServiceDestination;
            _vizDatasourceService         = vizDatasourceService;
            _logger = logger;

            _settingsMonitor.CurrentValue.DefaultOwnerUsername =
                _settingsMonitor.CurrentValue.DefaultOwnerUsername ?? "";

            _tableauServiceFactorySource = new TableauServiceFactory(_tableauApiServiceSource, _logger);
            _tableauServiceFactoryDest   = new TableauServiceFactory(_tableauApiServiceDestination, _logger);

            _tableauApiServiceSource.SignInAsync().Wait();
            _tableauApiServiceDestination.SignInAsync().Wait();

            // ensure case-insensitive connection credential lookup
            _settingsMonitor.CurrentValue.EmbeddedConnectionCredentials = new Dictionary <string, string>(
                _settingsMonitor.CurrentValue.EmbeddedConnectionCredentials,
                StringComparer.OrdinalIgnoreCase
                );
        }
        private static async Task <Dictionary <string, TableauWorkbook> > GetProjectWorkbooksAsync(
            string projectId,
            ITableauServiceFactory serviceFactory
            )
        {
            var workbookService = serviceFactory.GetService <TableauWorkbookService>();

            var projectWorkbooks = new Dictionary <string, TableauWorkbook>();

            var workbooks = await workbookService.GetWorkbooksAsync().ConfigureAwait(false);

            return(workbooks.Where(w => w.Project.Id == projectId).ToDictionary(w => w.Id, w => w));
        }
        private static async Task <Dictionary <string, TableauDatasource> > GetProjectDatasourcesAsync(
            string projectId,
            ITableauServiceFactory serviceFactory
            )
        {
            var datasourceService = serviceFactory.GetService <TableauDatasourceService>();

            var projectDatasources = new Dictionary <string, TableauDatasource>();

            var datasources = await datasourceService.GetDatasourcesAsync().ConfigureAwait(false);

            return(datasources.Where(d => d.Project.Id == projectId).ToDictionary(w => w.Id, w => w));
        }
        private static async Task <Dictionary <string, TableauGroup> > GetProjectGroups(
            string projectId,
            ITableauServiceFactory serviceFactory
            )
        {
            var groupService      = serviceFactory.GetService <TableauGroupService>();
            var permissionService = serviceFactory.GetService <TableauPermissionService>();

            var projectGroups = new Dictionary <string, TableauGroup>();

            // get groups defined in project permissions as well as default permissions for datasources, workbooks
            var permissions = new List <TableauPermission>();

            permissions.Add(
                await permissionService.GetPermissionsAsync(
                    ResourceType.Project, projectId
                    ).ConfigureAwait(false)
                );
            permissions.Add(
                await permissionService.GetDefaultPermissionsAsync(
                    projectId, ResourceType.Datasource
                    ).ConfigureAwait(false)
                );
            permissions.Add(
                await permissionService.GetDefaultPermissionsAsync(
                    projectId, ResourceType.Workbook
                    ).ConfigureAwait(false)
                );

            foreach (var permission in permissions)
            {
                if (permission.GranteeCapabilities == null)
                {
                    continue;
                }
                foreach (var granteeCapability in permission.GranteeCapabilities)
                {
                    if (granteeCapability.GranteeType == GranteeType.Group)
                    {
                        var group = await groupService.GetGroupAsync(granteeCapability.GranteeId).ConfigureAwait(false);

                        projectGroups[granteeCapability.GranteeId] = group;
                    }
                }
            }

            return(projectGroups);
        }
        private static async Task <Dictionary <string, TableauUser> > GetGroupUsersWithDomain(
            string groupId,
            ITableauServiceFactory serviceFactory
            )
        {
            var groupUsers = new Dictionary <string, TableauUser>();

            var userService = serviceFactory.GetService <TableauUserService>();
            var users       = await userService.GetUsersAsync(groupId).ConfigureAwait(false);

            foreach (var user in users)
            {
                // get all users in group individually so user's domain is included if specified (slandron)
                groupUsers.Add(user.Id, await userService.GetUserAsync(user.Id).ConfigureAwait(false));
            }
            return(groupUsers);
        }
        private static async Task <Dictionary <string, TableauUser> > GetProjectUsersWithDomain(
            string projectId,
            ITableauServiceFactory serviceFactory
            )
        {
            var userService       = serviceFactory.GetService <TableauUserService>();
            var groupService      = serviceFactory.GetService <TableauGroupService>();
            var permissionService = serviceFactory.GetService <TableauPermissionService>();

            var projectUsers = new Dictionary <string, TableauUser>();

            // get users defined in project permissions as well as default permissions for datasources, workbooks
            var permissions = new List <TableauPermission>();

            permissions.Add(
                await permissionService.GetPermissionsAsync(
                    ResourceType.Project, projectId
                    ).ConfigureAwait(false)
                );
            permissions.Add(
                await permissionService.GetDefaultPermissionsAsync(
                    projectId, ResourceType.Datasource
                    ).ConfigureAwait(false)
                );
            permissions.Add(
                await permissionService.GetDefaultPermissionsAsync(
                    projectId, ResourceType.Workbook
                    ).ConfigureAwait(false)
                );

            foreach (var permission in permissions)
            {
                if (permission.GranteeCapabilities == null)
                {
                    continue;
                }
                foreach (var granteeCapability in permission.GranteeCapabilities)
                {
                    if (granteeCapability.GranteeType == GranteeType.Group)
                    {
                        // get all users in group individually so user's domain is included if specified (slandron)
                        var members = await userService.GetUsersAsync(
                            granteeCapability.GranteeId
                            ).ConfigureAwait(false);

                        foreach (var member in members)
                        {
                            if (projectUsers.ContainsKey(member.Id))
                            {
                                continue;
                            }
                            projectUsers.Add(
                                member.Id,
                                await userService.GetUserAsync(member.Id).ConfigureAwait(false)
                                );
                        }
                    }

                    if (granteeCapability.GranteeType == GranteeType.User &&
                        !projectUsers.ContainsKey(granteeCapability.GranteeId))
                    {
                        projectUsers.Add(
                            granteeCapability.GranteeId,
                            await userService.GetUserAsync(granteeCapability.GranteeId).ConfigureAwait(false)
                            );
                    }
                }
            }

            return(projectUsers);
        }