Exemplo n.º 1
0
        private async Task DownloadProjectWorkbooksAsync(TableauProject sourceProject, TableauProject destProject)
        {
            _logger?.Debug($"Downloading workbooks for project {sourceProject.Name}");

            var sourceWorkbookService = _tableauServiceFactorySource.GetService <TableauWorkbookService>();

            var sourceWorkbooks = await GetProjectWorkbooksAsync(
                sourceProject.Id, _tableauServiceFactorySource
                ).ConfigureAwait(false);

            if (!Directory.Exists(_settingsMonitor.CurrentValue.workbookDownloadPath))
            {
                Directory.CreateDirectory(_settingsMonitor.CurrentValue.workbookDownloadPath);
            }

            foreach (var sourceWorkbook in sourceWorkbooks.Values)
            {
                _logger?.Debug($"Downloading workbook '{sourceWorkbook.Name}'");
                if (!_settingsMonitor.CurrentValue.DryRun)
                {
                    var fileName = VizDatasourceService.GetValidFileName(sourceWorkbook.Name) + ".twb";
                    var fileInfo = await sourceWorkbookService.DownloadWorkbookAsync(
                        sourceWorkbook.Id,
                        _settingsMonitor.CurrentValue.workbookDownloadPath,
                        fileName
                        ).ConfigureAwait(false);

                    _logger?.Debug($"Downloaded workbook '{sourceWorkbook.Name}' to '{fileInfo.FullName}'");
                }
            }

            _logger?.Debug($"Downloaded workbooks for project {sourceProject.Name}");
        }
Exemplo n.º 2
0
        private async Task <TableauWorkbook> MigrateWorkbookAsync(
            string sourceWorkbookId,
            string destProjectId,
            string destUserId
            )
        {
            _logger?.Debug($"Migrating workbook {sourceWorkbookId}");

            var sourceWorkbookService = _tableauServiceFactorySource.GetService <TableauWorkbookService>();
            var destWorkbookService   = _tableauServiceFactoryDest.GetService <TableauWorkbookService>();

            var sourceDatasourceService = _tableauServiceFactorySource.GetService <TableauDatasourceService>();
            var destDatasourceService   = _tableauServiceFactoryDest.GetService <TableauDatasourceService>();

            var sourceBaseUri = new Uri(_settingsMonitor.CurrentValue.TableauApiSettingsSource.BaseUrl);
            var destBaseUri   = new Uri(_settingsMonitor.CurrentValue.TableauApiSettingsDestination.BaseUrl);

            var sourceServer = sourceBaseUri.Host;
            var destServer   = destBaseUri.Host;

            await _vizDatasourceService.LoadVizDatasourceReportAsync().ConfigureAwait(false);

            // get workbook metadata
            var workbook = await sourceWorkbookService.GetWorkbookAsync(
                sourceWorkbookId, true
                ).ConfigureAwait(false);

            _logger?.Debug($"Migrating workbook {workbook.Name}");

            // reassign project and owner for import to destination
            workbook.Project.Id = destProjectId;
            workbook.Owner.Id   = destUserId;

            // populate workbook connection info
            foreach (var connection in workbook.Connections)
            {
                if (connection.Type.EqualsIgnoreCase(TableauApiService.CONNECTION_TYPE_SQLPROXY))
                {
                    // published/proxy connection
                    if (!String.IsNullOrWhiteSpace(connection.ServerAddress) &&
                        !connection.ServerAddress.EqualsIgnoreCase(sourceServer) &&
                        !connection.ServerAddress.EqualsIgnoreCase("localhost"))
                    {
                        throw new Exception($"Unexpected source connection server address: {connection.ServerAddress}");
                    }

                    var datasource = await sourceDatasourceService.GetDatasourceAsync(
                        connection.Datasource.Id, true
                        ).ConfigureAwait(false);

                    var destDatasource = await destDatasourceService.FindDatasourceAsync(
                        datasource.Name, true
                        ).ConfigureAwait(false);

                    // get datasource credentials from viz datasource report (csv)
                    var vizDatasource = _vizDatasourceService.GetVizDatasource(
                        _vizDatasourceService.GetValidName(datasource.Name.Trim())
                        );

                    if (destDatasource != null)
                    {
                        _logger?.Debug($"Datasource found in destination: {destDatasource.Id}");
                    }

                    if (vizDatasource == null)
                    {
                        _logger?.Warning(
                            "Viz datasource not found for sqlproxy workbook connection {0}, skipping: {1} ({2})",
                            connection.Id,
                            _vizDatasourceService.GetValidName(datasource.Name),
                            datasource.Name
                            );
                        continue;
                    }

                    if (
                        destDatasource == null ||
                        destDatasource.Project?.Id != destProjectId ||
                        !destDatasource.Connections.Any(c => (c.ServerAddress ?? "").EqualsIgnoreCase(destServer)) &&
                        !destDatasource.Connections.Any(
                            c => (c.Username ?? "").EqualsIgnoreCase(vizDatasource.VizConnectionDetail.Username)
                            )
                        )
                    {
                        // source datasource doesn't exist in destination, publish
                        // reassign project for import to destination
                        datasource.Project.Id = destProjectId;

                        // populate datasource connection credentials
                        datasource.ConnectionCredentials = new TableauConnectionCredentials()
                        {
                            Username = vizDatasource.VizConnectionDetail.Username,
                            Password = vizDatasource.VizConnectionDetail.Password,
                            Embed    = true
                        };

                        _logger?.Debug("Publish datasource:");
                        _logger?.Debug(JsonConvert.SerializeObject(datasource));

                        // get datasource file data
                        var datasourceBytes = _vizDatasourceService.GetVizDatasourceFile(vizDatasource.Name);
                        datasourceBytes.ContentType            = "application/octet-stream";
                        datasourceBytes.ContentDispositionName = "tableau_datasource";

                        if (!_settingsMonitor.CurrentValue.DryRun)
                        {
                            destDatasource = await destDatasourceService.PublishDatasourceAsync(
                                datasource, datasourceBytes
                                ).ConfigureAwait(false);

                            // allow Tableau api to catch up to db changes
                            await Task.Delay(1000).ConfigureAwait(false);
                        }
                    }

                    connection.ConnectionCredentials = new TableauConnectionCredentials()
                    {
                        Username = vizDatasource.VizConnectionDetail.Username,
                        Password = vizDatasource.VizConnectionDetail.Password,
                        Embed    = true
                    };
                    connection.Datasource    = destDatasource;
                    connection.ServerAddress = destServer;
                }
                else if (!String.IsNullOrWhiteSpace(connection.Username))
                {
                    // embedded
                    connection.ConnectionCredentials = new TableauConnectionCredentials()
                    {
                        Username = connection.Username,
                        Password = GetConnectionPassword(connection.Username),
                        Embed    = true
                    };
                }
                else
                {
                    throw new Exception("Workbook connection not sqlproxy but missing username");
                }
            }

            // get workbook file data
            var workbookBytes = await sourceWorkbookService.DownloadWorkbookBytesAsync(
                workbook.Id
                ).ConfigureAwait(false);

            workbookBytes.ContentType            = "application/octet-stream";
            workbookBytes.ContentDispositionName = "tableau_workbook";

            var savePath = Path.Combine(
                _settingsMonitor.CurrentValue.workbookDownloadPath,
                VizDatasourceService.GetValidFileName(workbookBytes.FilePath).Replace(".twb", "_publish.twb")
                );

            workbookBytes.Bytes = Encoding.UTF8.GetBytes(
                UpdateWorkbookPublishedDatasourceConnections(
                    Encoding.UTF8.GetString(workbookBytes.Bytes),
                    sourceServer,
                    destServer
                    )
                );

            workbookBytes.Bytes = Encoding.UTF8.GetBytes(
                UpdateWorkbookPublishedDatasourceConnections(
                    Encoding.UTF8.GetString(workbookBytes.Bytes),
                    "localhost",
                    destServer
                    )
                );

            _logger?.Debug($"Saving copy of workbook to {savePath}");
            File.WriteAllBytes(savePath, workbookBytes.Bytes);

            _logger?.Debug($"Publishing workbook {workbook.Name}");

            return(!_settingsMonitor.CurrentValue.DryRun
                ? await destWorkbookService.PublishWorkbookAsync(workbook, workbookBytes).ConfigureAwait(false)
                : null);
        }