예제 #1
0
    /// <summary>
    /// Attempts to upload a single file a Tableau Server, and then make it a published workbook
    /// </summary>
    /// <param name="localFilePath"></param>
    /// <returns></returns>
    private bool AttemptUploadSingleFile_Inner(
        string localFilePath,
        string projectId,
        CredentialManager.Credential dbCredentials)
    {
        string uploadSessionId;

        try
        {
            var fileUploader = new UploadFile(_onlineUrls, _onlineSession, localFilePath, _uploadChunkSizeBytes, _uploadChunkDelaySeconds);
            uploadSessionId = fileUploader.ExecuteRequest();
        }
        catch (Exception exFileUpload)
        {
            this.StatusLog.AddError("Unexpected error attempting to upload file " + localFilePath + ", " + exFileUpload.Message);
            throw exFileUpload;
        }

        this.StatusLog.AddStatus("File chunks upload successful. Next step, make it a published workbook", -10);
        try
        {
            string fileName   = Path.GetFileNameWithoutExtension(localFilePath);
            string uploadType = RemoveFileExtensionDot(Path.GetExtension(localFilePath).ToLower());
            var    workbook   = FinalizePublish(uploadSessionId, fileName, uploadType, projectId, dbCredentials);
            StatusLog.AddStatus("Upload content details: " + workbook.ToString(), -10);
            StatusLog.AddStatus("Success! Uploaded workbook " + Path.GetFileName(localFilePath));
        }
        catch (Exception exPublishFinalize)
        {
            this.StatusLog.AddError("Unexpected error finalizing publish of file " + localFilePath + ", " + exPublishFinalize.Message);
            LogManualAction_UploadWorkbook(localFilePath);
            throw exPublishFinalize;
        }
        return(true);     //Success
    }
예제 #2
0
    /// <summary>
    /// Attempts to upload a single file a Tableau Server, and then make it a published workbook
    /// </summary>
    /// <param name="localFilePath"></param>
    /// <returns></returns>
    private bool AttemptUploadSingleFile_Inner(
        string localFilePath,
        string projectId,
        CredentialManager.Credential dbCredentials,
        WorkbookPublishSettings publishSettings)
    {
        string uploadSessionId;

        try
        {
            var fileUploader = new UploadFile(_onlineUrls, _onlineSession, localFilePath, _uploadChunkSizeBytes, _uploadChunkDelaySeconds);
            uploadSessionId = fileUploader.ExecuteRequest();
        }
        catch (Exception exFileUpload)
        {
            this.StatusLog.AddError("Unexpected error attempting to upload file " + localFilePath + ", " + exFileUpload.Message);
            throw exFileUpload;
        }

        SiteWorkbook workbook;

        this.StatusLog.AddStatus("File chunks upload successful. Next step, make it a published workbook", -10);
        try
        {
            string fileName   = Path.GetFileNameWithoutExtension(localFilePath);
            string uploadType = RemoveFileExtensionDot(Path.GetExtension(localFilePath).ToLower());
            workbook = FinalizePublish(
                uploadSessionId,
                FileIOHelper.Undo_GenerateWindowsSafeFilename(fileName), //[2016-05-06] If the name has escapted characters, unescape them
                uploadType,
                projectId,
                dbCredentials,
                publishSettings);
            StatusLog.AddStatus("Upload content details: " + workbook.ToString(), -10);
            StatusLog.AddStatus("Success! Uploaded workbook " + Path.GetFileName(localFilePath));
        }
        catch (Exception exPublishFinalize)
        {
            this.StatusLog.AddError("Unexpected error finalizing publish of file " + localFilePath + ", " + exPublishFinalize.Message);
            LogManualAction_UploadWorkbook(localFilePath);
            throw exPublishFinalize;
        }

        //See if we want to reassign ownership of the workbook
        if (_attemptOwnershipAssignment)
        {
            try
            {
                AttemptOwnerReassignment(workbook, publishSettings, _siteUsers);
            }
            catch (Exception exOwnershipAssignment)
            {
                this.StatusLog.AddError("Unexpected error reassigning ownership of published workbook " + workbook.Name + ", " + exOwnershipAssignment.Message);
                LogManualAction_ReassignOwnership(workbook.Name);
                throw exOwnershipAssignment;
            }
        }

        return(true);     //Success
    }
예제 #3
0
        /// <summary>
        /// Attempts to upload a single file a Tableau Server, and then make it a published data source
        /// </summary>
        /// <param name="localFilePath"></param>
        /// <param name="projectId"></param>
        /// <param name="dbCredentials">If not NULL, then these are the DB credentials we want to associate with the content we are uploading</param>
        /// <returns></returns>
        private bool AttemptUploadSingleFile(
            string localFilePath,
            string projectId,
            CredentialManager.Credential dbCredentials,
            DatasourcePublishSettings publishSettings)
        {
            string uploadSessionId;

            try
            {
                var fileUploader = new UploadFile(Urls, Login, localFilePath, HttpClientFactory, UploadChunkSizeBytes, UploadChunkDelaySeconds);
                uploadSessionId = fileUploader.ExecuteRequest();
            }
            catch (Exception exFileUpload)
            {
                Login.Logger.Error("Unexpected error attempting to upload file " + localFilePath + ", " + exFileUpload.Message);
                throw exFileUpload;
            }

            SiteDatasource dataSource = null;

            Login.Logger.Information("File chunks upload successful. Next step, make it a published datasource");
            try
            {
                string fileName   = Path.GetFileNameWithoutExtension(localFilePath);
                string uploadType = RemoveFileExtensionDot(Path.GetExtension(localFilePath).ToLower());
                dataSource = FinalizePublish(
                    uploadSessionId,
                    FileIOHelper.Undo_GenerateWindowsSafeFilename(fileName), //[2016-05-06] If the name has escapted characters, unescape them
                    uploadType,
                    projectId,
                    dbCredentials);
                UploadeDatasources.Add(dataSource);
                Login.Logger.Information("Upload content details: " + dataSource.ToString());
                Login.Logger.Information("Success! Uploaded datasource " + Path.GetFileName(localFilePath));
            }
            catch (Exception exPublishFinalize)
            {
                Login.Logger.Error("Unexpected error finalizing publish of file " + localFilePath + ", " + exPublishFinalize.Message);
                throw exPublishFinalize;;
            }

            //See if we want to reassign ownership of the datasource
            if (AttemptOwnershipAssignment)
            {
                try
                {
                    AttemptOwnerReassignment(dataSource, publishSettings, SiteUsers);
                }
                catch (Exception exOwnershipAssignment)
                {
                    Login.Logger.Error("Unexpected error reassigning ownership of published datasource " + dataSource.Name + ", " + exOwnershipAssignment.Message);
                    LogManualAction_ReassignOwnership(dataSource.Name);
                    throw exOwnershipAssignment;
                }
            }

            return(true);     //Success
        }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="thisFilePath"></param>
 /// <param name="projectIdForUploads"></param>
 /// <param name="dbCredentials">If not NULL, then these are the DB credentials we want to associate with the content we are uploading</param>
 /// <param name="publishSettings">Workbook publish settings (e.g. whether to show tabs in vizs)</param>
 private bool AttemptUploadSingleFile(
     string thisFilePath,
     string projectIdForUploads,
     CredentialManager.Credential dbCredentials,
     WorkbookPublishSettings publishSettings)
 {
     return(AttemptUploadSingleFile_Inner(thisFilePath, projectIdForUploads, dbCredentials, publishSettings));
 }
예제 #5
0
        /// <summary>
        /// After a file has been uploaded in chunks, we need to make a call to COMMIT the file to server as a published Data Source
        /// </summary>
        /// <param name="uploadSessionId"></param>
        /// <param name="publishedContentName"></param>
        private SiteDatasource FinalizePublish(
            string uploadSessionId,
            string publishedContentName,
            string publishedContentType,
            string projectId,
            CredentialManager.Credential dbCredentials)
        {
            //See definition: http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Datasource%3FTocPath%3DAPI%2520Reference%7C_____29
            var sb        = new StringBuilder();
            var xmlWriter = XmlWriter.Create(sb, XmlHelper.XmlSettingsForWebRequests);

            xmlWriter.WriteStartElement("tsRequest");
            xmlWriter.WriteStartElement("datasource");
            xmlWriter.WriteAttributeString("name", publishedContentName);

            //If we have an associated database credential, write it out
            if (dbCredentials != null)
            {
                CredentialXmlHelper.WriteCredential(
                    xmlWriter,
                    dbCredentials);
            }

            xmlWriter.WriteStartElement("project"); //<project>
            xmlWriter.WriteAttributeString("id", projectId);
            xmlWriter.WriteEndElement();            //</project>
            xmlWriter.WriteEndElement();            // </datasource>
            //Currently not supporting <connectionCredentials>
            xmlWriter.WriteEndElement();            // </tsRequest>
            xmlWriter.Dispose();

            var xmlText = sb.ToString(); //Get the XML text out

            //Generate the MIME message
            var mimeGenerator = new MimeWriterXml(xmlText);

            //Create a web request to push the
            var urlFinalizeUpload = Urls.Url_FinalizeDataSourcePublish(Login, uploadSessionId, publishedContentType);

            //NOTE: The publish finalization step can take several minutes, because server needs to unpack the uploaded ZIP and file it away.
            //      For this reason, we pass in a long timeout
            var response = this.CreateAndSendMimeLoggedInRequest(urlFinalizeUpload, HttpMethod.Post, mimeGenerator);
            var xmlDoc   = GetHttpResponseAsXml(response);

            //Get all the datasource node from the response
            var xDoc          = xmlDoc.ToXDocument();
            var dataSourceXml = xDoc.Root.Descendants(XName.Get("datasource", XmlNamespace)).FirstOrDefault();

            try
            {
                return(new SiteDatasource(dataSourceXml.ToXmlNode(), XmlNamespace));
            }
            catch (Exception parseXml)
            {
                Login.Logger.Error("Data source upload, error parsing XML response " + parseXml.Message + "\r\n" + dataSourceXml.ToXmlNode());
                return(null);
            }
        }
예제 #6
0
    /// <summary>
    /// After a file has been uploaded in chunks, we need to make a call to COMMIT the file to server as a published Data Source
    /// </summary>
    /// <param name="uploadSessionId"></param>
    /// <param name="publishedContentName"></param>
    private SiteDatasource FinalizePublish(
        string uploadSessionId,
        string publishedContentName,
        string publishedContentType,
        string projectId,
        CredentialManager.Credential dbCredentials)
    {
        //See definition: http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Datasource%3FTocPath%3DAPI%2520Reference%7C_____29
        var sb        = new StringBuilder();
        var xmlWriter = XmlWriter.Create(sb, XmlHelper.XmlSettingsForWebRequests);

        xmlWriter.WriteStartElement("tsRequest");
        xmlWriter.WriteStartElement("datasource");
        xmlWriter.WriteAttributeString("name", publishedContentName);

        //If we have an associated database credential, write it out
        if (dbCredentials != null)
        {
            CredentialXmlHelper.WriteCredential(
                xmlWriter,
                dbCredentials);
        }

        xmlWriter.WriteStartElement("project"); //<project>
        xmlWriter.WriteAttributeString("id", projectId);
        xmlWriter.WriteEndElement();            //</project>
        xmlWriter.WriteEndElement();            // </datasource>
        //Currently not supporting <connectionCredentials>
        xmlWriter.WriteEndElement();            // </tsRequest>
        xmlWriter.Close();

        var xmlText = sb.ToString(); //Get the XML text out

        //Generate the MIME message
        var mimeGenerator = new MimeWriterXml(xmlText);

        //Create a web request to push the
        var urlFinalizeUpload = _onlineUrls.Url_FinalizeDataSourcePublish(_onlineSession, uploadSessionId, publishedContentType);

        //NOTE: The publish finalization step can take several minutes, because server needs to unpack the uploaded ZIP and file it away.
        //      For this reason, we pass in a long timeout
        var webRequest = this.CreateAndSendMimeLoggedInRequest(urlFinalizeUpload, "POST", mimeGenerator, TableauServerWebClient.DefaultLongRequestTimeOutMs);
        var xmlDoc     = GetWebReponseLogErrors_AsXmlDoc(webRequest, "finalize datasource publish");

        //Get all the datasource node from the response
        var nsManager     = XmlHelper.CreateTableauXmlNamespaceManager("iwsOnline");
        var dataSourceXml = xmlDoc.SelectSingleNode("//iwsOnline:datasource", nsManager);

        try
        {
            return(new SiteDatasource(dataSourceXml));
        }
        catch (Exception parseXml)
        {
            StatusLog.AddError("Data source upload, error parsing XML response " + parseXml.Message + "\r\n" + dataSourceXml.InnerXml);
            return(null);
        }
    }
예제 #7
0
    /// <summary>
    /// Makes a copy of the file; remaps the Workbook references to the server, uploads the remapped file
    /// </summary>
    /// <param name="thisFilePath"></param>
    /// <param name="projectIdForUploads"></param>
    private bool AttemptUploadSingleFile_ReferencesRemapped(
        string thisFilePath,
        string projectIdForUploads,
        CredentialManager.Credential dbCredentials,
        WorkbookPublishSettings publishSettings)
    {
        bool success = false;

        string filename        = Path.GetFileName(thisFilePath);
        string pathToRemapFile = Path.Combine(_localPathTempWorkspace, filename);

        File.Copy(thisFilePath, pathToRemapFile, true); //Copy the file

        string fileType = Path.GetExtension(filename).ToLower();

        if (fileType == ".twb")
        {
            //Remap the references in the file
            var twbRemapper = new TwbDataSourceEditor(pathToRemapFile, pathToRemapFile, _onlineUrls, this.StatusLog);
            twbRemapper.Execute();
            success = AttemptUploadSingleFile_Inner(pathToRemapFile, projectIdForUploads, dbCredentials, publishSettings);
        }
        else if (fileType == ".twbx")
        {
            //Make sure we have a directory to unzip to
            var pathUnzip = Path.Combine(_localPathTempWorkspace, "unzipped");
            if (Directory.Exists(pathUnzip))
            {
                Directory.Delete(pathUnzip, true);
            }
            Directory.CreateDirectory(pathUnzip);

            var    twbxRemapper           = new TwbxDataSourceEditor(pathToRemapFile, pathUnzip, _onlineUrls, this.StatusLog);
            string pathTwbxRemappedOutput = twbxRemapper.Execute();
            //Upload the remapped file
            success = AttemptUploadSingleFile_Inner(pathTwbxRemappedOutput, projectIdForUploads, dbCredentials, publishSettings);

            //Clean-up and delete the whole unzipped directory
            Directory.Delete(pathUnzip, true);
        }
        else
        {
            //We should never hit this... bad content
            this.StatusLog.AddError("Error Workbook upload - Expected Workbook filetype! " + filename);
        }

        //Delete the remap file
        File.Delete(pathToRemapFile);
        return(success);
    }
예제 #8
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="thisFilePath"></param>
 /// <param name="projectIdForUploads"></param>
 /// <param name="dbCredentials">If not NULL, then these are the DB credentials we want to associate with the content we are uploading</param>
 private bool AttemptUploadSingleFile(
     string thisFilePath,
     string projectIdForUploads,
     CredentialManager.Credential dbCredentials)
 {
     //Assume it's a file we should try to upload
     if (_remapWorkbookReferences)
     {
         return(AttemptUploadSingleFile_ReferencesRemapped(thisFilePath, projectIdForUploads, dbCredentials));
     }
     else
     {
         return(AttemptUploadSingleFile_Inner(thisFilePath, projectIdForUploads, dbCredentials));
     }
 }
예제 #9
0
    /// <summary>
    /// Attempts to upload a single file a Tableau Server, and then make it a published data source
    /// </summary>
    /// <param name="localFilePath"></param>
    /// <param name="projectId"></param>
    /// <param name="dbCredentials">If not NULL, then these are the DB credentials we want to associate with the content we are uploading</param>
    /// <returns></returns>
    private bool AttemptUploadSingleFile(
        string localFilePath,
        string projectId,
        CredentialManager.Credential dbCredentials)
    {
        string uploadSessionId;

        try
        {
            var fileUploader = new UploadFile(_onlineUrls, _onlineSession, localFilePath, _uploadChunkSizeBytes, _uploadChunkDelaySeconds);
            uploadSessionId = fileUploader.ExecuteRequest();
        }
        catch (Exception exFileUpload)
        {
            this.StatusLog.AddError("Unexpected error attempting to upload file " + localFilePath + ", " + exFileUpload.Message);
            throw exFileUpload;
        }

        this.StatusLog.AddStatus("File chunks upload successful. Next step, make it a published datasource", -10);
        try
        {
            string fileName   = Path.GetFileNameWithoutExtension(localFilePath);
            string uploadType = RemoveFileExtensionDot(Path.GetExtension(localFilePath).ToLower());
            var    dataSource = FinalizePublish(
                uploadSessionId,
                FileIOHelper.Undo_GenerateWindowsSafeFilename(fileName), //[2016-05-06] If the name has escapted characters, unescape them
                uploadType,
                projectId,
                dbCredentials);
            StatusLog.AddStatus("Upload content details: " + dataSource.ToString(), -10);
            StatusLog.AddStatus("Success! Uploaded datasource " + Path.GetFileName(localFilePath));
        }
        catch (Exception exPublishFinalize)
        {
            this.StatusLog.AddError("Unexpected error finalizing publish of file " + localFilePath + ", " + exPublishFinalize.Message);
            throw exPublishFinalize;;
        }
        return(true);     //Success
    }
예제 #10
0
        /// <summary>
        /// After a file has been uploaded in chunks, we need to make a call to COMMIT the file to server as a published Workbook
        /// </summary>
        /// <param name="uploadSessionId"></param>
        /// <param name="publishedContentName"></param>
        private SiteWorkbook FinalizePublish(
            string uploadSessionId,
            string publishedContentName,
            string publishedContentType,
            string projectId,
            CredentialManager.Credential dbCredentials,
            WorkbookPublishSettings publishSettings)
        {
            if (projectId == null)
            {
                projectId = "";
            }
            //See definition: http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Workbook%3FTocPath%3DAPI%2520Reference%7C_____29
            var sb = new StringBuilder();

            //Build the XML part of the MIME message we will post up to server
            var xmlWriter = XmlWriter.Create(sb, XmlHelper.XmlSettingsForWebRequests);

            xmlWriter.WriteStartElement("tsRequest");
            xmlWriter.WriteStartElement("workbook");
            xmlWriter.WriteAttributeString("name", publishedContentName);
            xmlWriter.WriteAttributeString("showTabs", XmlHelper.BoolToXmlText(publishSettings.ShowTabs));

            //If we have an associated database credential, write it out
            if (dbCredentials != null)
            {
                CredentialXmlHelper.WriteCredential(
                    xmlWriter,
                    dbCredentials);
            }

            xmlWriter.WriteStartElement("project"); //<project>
            xmlWriter.WriteAttributeString("id", projectId);
            xmlWriter.WriteEndElement();            //</project>
            xmlWriter.WriteEndElement();            // </workbook>
            xmlWriter.WriteEndElement();            // </tsRequest>
            xmlWriter.Dispose();

            var xmlText = sb.ToString(); //Get the XML text out

            //Generate the MIME message and pack the XML into it
            var mimeGenerator = new MimeWriterXml(xmlText);

            //Create a web request to POST the MIME message to server to finalize the publish
            var urlFinalizeUpload = Urls.Url_FinalizeWorkbookPublish(Login, uploadSessionId, publishedContentType);

            //NOTE: The publish finalization step can take several minutes, because server needs to unpack the uploaded ZIP and file it away.
            //      For this reason, we pass in a long timeout
            var response = CreateAndSendMimeLoggedInRequest(urlFinalizeUpload, HttpMethod.Post, mimeGenerator);

            using (response)
            {
                var xmlDoc      = GetHttpResponseAsXml(response);
                var xDoc        = xmlDoc.ToXDocument();
                var workbookXml = xDoc.Root.Descendants(XName.Get("workbook", XmlNamespace)).FirstOrDefault();
                try
                {
                    return(new SiteWorkbook(workbookXml.ToXmlNode(), XmlNamespace));
                }
                catch (Exception parseXml)
                {
                    Login.Logger.Error("Workbook upload, error parsing XML response " + parseXml.Message + "\r\n" + workbookXml.ToXmlNode().InnerXml);
                    return(null);
                }
            }
        }
예제 #11
0
 /// <summary>
 /// Writes out the credential element.  Used in Workbook and Data Source publication
 /// </summary>
 /// <param name="xmlWriter"></param>
 /// <param name="credential"></param>
 public static void WriteCredential(XmlWriter xmlWriter, CredentialManager.Credential credential)
 {
     WriteCredential(xmlWriter, credential.Name, credential.Password, credential.IsEmbedded);
 }