/// <summary> /// Adds tags to an existing workbook. /// </summary> /// <param name="workbookId">The Workbook ID of the workbook to add tags to.</param> /// <param name="tags">A list of tags to add to the workbook.</param> public void AddTagsToWorkbook(string workbookId, ISet <string> tags) { if (tags.Count == 0) { return; } var uri = Endpoints.GetAddTagsToWorkbookUri(baseUri, GetSiteId(), workbookId); // Copy tags into tag array type. tagType[] tagArray = new tagType[tags.Count]; for (int i = 0; i < tags.Count; i++) { tagType tag = new tagType { label = tags.ToList()[i] }; tagArray[i] = tag; } // Construct payload. tsRequest requestPayload = new tsRequest { Item = new tagListType { tag = tagArray } }; // Issue request. var errorMessage = "Failed to add tags to workbook"; ApiRequest request = new ApiRequest(uri, HttpMethod.Put, GetAuthToken(), headers: null, body: requestPayload.SerializeBody()); request.IssueRequest(errorMessage); }
public workbookType FinishUploadAndPublishWorkbook(PublishWorkbookRequest publishRequest, fileUploadType session) { var uri = Endpoints.GetFinishPublishWorkbookUri(baseUri, publishRequest.SiteId, publishRequest.OverwriteExistingWorkbook, session.uploadSessionId, Path.GetExtension(publishRequest.FilePath).Replace(".", "")); tsRequest requestPayload = new tsRequest { Item = new workbookType { name = Path.GetFileNameWithoutExtension(publishRequest.FilePath), //showTabs = publishRequest.ShowSheetsAsTabs, //showTabsSpecified = publishRequest.ShowSheetsAsTabs, project = new projectType { id = publishRequest.ProjectId }, } }; var boundaryString = Guid.NewGuid().ToString().Replace("-", ""); string contentType = String.Format("multipart/mixed; boundary={0}", boundaryString); byte[] requestBody = PublishRequestBuilder.BuildFinishUploadBody(publishRequest.FilePath, requestPayload, boundaryString); ApiRequest apiRequest = new ApiRequest(uri, HttpMethod.Post, GetAuthToken(), headers: null, contentType: contentType, body: requestBody, timeoutSeconds: publishRequest.PublishingTimeoutSeconds); // Issue request. var errorMessage = String.Format("Failed to finish multipart publish workbook '{0}'", publishRequest.WorkbookName); tsResponse response = apiRequest.IssueRequest(errorMessage); return(response.GetWorkbook()); }
/// <summary> /// Creates a new project with the given name and description. /// </summary> /// <param name="projectName">The name of the project to create.</param> /// <param name="projectDescription">The description of the project to create.</param> /// <returns>The Project ID of the project that was created.</returns> public string CreateProject(string projectName, string projectDescription = Constants.DefaultCreatedProjectDescription) { // Get Site ID for the site we'll create a project in and use it to construct endpoint uri. var uri = Endpoints.GetCreateProjectUri(baseUri, GetSiteId()); // Construct payload. tsRequest requestPayload = new tsRequest { Item = new projectType { name = projectName, description = projectDescription } }; // Issue request. var errorMessage = String.Format("Failed to create project '{0}' on site '{1}'", projectName, siteName); ApiRequest request = new ApiRequest(uri, HttpMethod.Post, GetAuthToken(), headers: null, body: requestPayload.SerializeBody()); tsResponse response = request.IssueRequest(errorMessage); // Return ID of created project. projectType createdProject = response.GetProject(); return(createdProject.id); }
/// <summary> /// Sets the default project permissions on a given project. /// </summary> /// <param name="projectId">The id of the project to set default permissions on.</param> /// <param name="groupId">The id of the group to add capabilities for.</param> /// <param name="permissionMapping">A mapping of the permissions to set.</param> public void AddDefaultProjectPermissions(string projectId, string groupId, IDictionary <capabilityTypeName, capabilityTypeMode> permissionMapping) { Uri uri = Endpoints.GetAddDefaultPermissionsWorkbookUri(baseUri, GetSiteId(), projectId); // Construct payload. tsRequest requestPayload = new tsRequest { Item = new permissionsType { granteeCapabilities = new[] { new granteeCapabilitiesType { Item = new groupType { id = groupId }, capabilities = permissionMapping.Select(permission => new capabilityType { name = permission.Key, mode = permission.Value }).ToArray() } } } }; // Issue request. var errorMessage = String.Format("Failed to set default workbook permissions for project in site '{0}'", siteName); ApiRequest request = new ApiRequest(uri, HttpMethod.Put, GetAuthToken(), headers: null, body: requestPayload.SerializeBody()); request.IssueRequest(errorMessage); }
/// <summary> /// Authenticates the user with Tableau Server. /// </summary> /// <returns>The auth token for the authenticated user's session.</returns> public string Authenticate() { var uri = Endpoints.GetSignInUri(baseUri); // Construct payload. tsRequest requestPayload = new tsRequest { Item = new tableauCredentialsType { name = userName, password = password, site = new siteType { contentUrl = GetSiteAsContentUrl() } } }; // Issue request. var errorMessage = String.Format("Failed to authenticate user '{0}'", userName); ApiRequest request = new ApiRequest(uri, HttpMethod.Post, authToken: null, headers: null, body: requestPayload.SerializeBody()); tsResponse response = request.IssueRequest(errorMessage); // Extract authentication token. tableauCredentialsType credentials = response.GetTableauCredentials(); return(credentials.token); }
public static byte[] BuildFinishUploadBody(string workbookFilePath, tsRequest requestMetadata, string boundaryString) { using (MemoryStream rs = new MemoryStream()) { // Compose the prefix to the actual workbook data. StringBuilder prefix = new StringBuilder(); prefix.Append(BuildPayloadHeader(boundaryString)); prefix.AppendLine(requestMetadata.SerializeBodyToString()); prefix.AppendLine(String.Format("--{0}--", boundaryString)); byte[] prefixBytes = Encoding.UTF8.GetBytes(prefix.ToString()); rs.Write(prefixBytes, 0, prefixBytes.Length); return(rs.ToArray()); } }
/// <summary> /// Retrieves the project details for a given project id. /// </summary> /// <param name="projectId">The ID of the project to query.</param> /// <returns>Project details associated with a given project id, or null if no match is found.</returns> public projectType GetProjectById(string projectId) { Uri uri = Endpoints.GetUpdateProjectUri(baseUri, GetSiteId(), projectId); // Construct payload. tsRequest requestPayload = new tsRequest { Item = new projectType() }; // Issue request. var errorMessage = String.Format("Failed to retrieve project details for project '{0}' in site '{1}'", projectId, siteName); ApiRequest request = new ApiRequest(uri, HttpMethod.Put, GetAuthToken(), headers: null, body: requestPayload.SerializeBody()); tsResponse response = request.IssueRequest(errorMessage); return(response.GetProject()); }
/// <summary> /// Updates the project name & description fields for a given project. /// </summary> /// <param name="projectId">The ID of the existing project to update.</param> /// <param name="newProjectName">The new project name to set.</param> /// <param name="newProjectDescription">The new project description to set.</param> public void UpdateProject(string projectId, string newProjectName, string newProjectDescription) { Uri uri = Endpoints.GetUpdateProjectUri(baseUri, GetSiteId(), projectId); // Construct payload. tsRequest requestPayload = new tsRequest { Item = new projectType { name = newProjectName, description = newProjectDescription } }; // Issue request. var errorMessage = String.Format("Failed to update project in site '{0}'", siteName); ApiRequest request = new ApiRequest(uri, HttpMethod.Put, GetAuthToken(), headers: null, body: requestPayload.SerializeBody()); request.IssueRequest(errorMessage); }
/// <summary> /// Builds the ugly multi-part request body for a Publish Workbook request. These requests are limited to 64Mb TWB files. /// </summary> /// <param name="workbookFilePath">The file path to the workbook.</param> /// <param name="requestMetadata">The tsRequest element containing metadata about the workbook.</param> /// <param name="boundaryString">A unique string to be used to separate the sections of the request bdoy.</param> /// <returns></returns> public static byte[] BuildRequestBody(string workbookFilePath, tsRequest requestMetadata, string boundaryString) { // Sanity check. if (!File.Exists(workbookFilePath)) { throw new ArgumentException(String.Format("File '{0}' does not exist!", workbookFilePath)); } using (FileStream fs = new FileStream(workbookFilePath, FileMode.Open, FileAccess.Read)) using (MemoryStream rs = new MemoryStream()) { // Compose the prefix to the actual workbook data. StringBuilder prefix = new StringBuilder(); prefix.AppendLine(String.Format("--{0}", boundaryString)); prefix.AppendLine("Content-Disposition: name=\"request_payload\""); prefix.AppendLine("Content-Type: text/xml"); prefix.AppendLine(); prefix.AppendLine(requestMetadata.SerializeBodyToString()); prefix.AppendLine(String.Format("--{0}", boundaryString)); prefix.AppendLine(String.Format("Content-Disposition: name=\"tableau_workbook\"; filename=\"{0}\"", Path.GetFileName(workbookFilePath))); prefix.AppendLine("Content-Type: application/octet-stream"); prefix.AppendLine(); byte[] prefixBytes = Encoding.UTF8.GetBytes(prefix.ToString()); rs.Write(prefixBytes, 0, prefixBytes.Length); // Write workbook data. var buffer = new byte[4096]; int bytesRead; while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0) { rs.Write(buffer, 0, bytesRead); } // Compose suffix region that indiciates the end of the request. byte[] suffix = Encoding.ASCII.GetBytes(String.Format("\r\n--{0}--", boundaryString)); rs.Write(suffix, 0, suffix.Length); return(rs.ToArray()); } }
public workbookType PublishWorkbook(PublishWorkbookRequest publishRequest) { // Construct URI & compose request payload. var uri = Endpoints.GetPublishWorkbookUri(baseUri, publishRequest.SiteId, publishRequest.OverwriteExistingWorkbook); tsRequest requestPayload = new tsRequest { Item = new workbookType { name = Path.GetFileNameWithoutExtension(publishRequest.FilePath), showTabs = publishRequest.ShowSheetsAsTabs, showTabsSpecified = publishRequest.ShowSheetsAsTabs, project = new projectType { id = publishRequest.ProjectId }, connectionCredentials = new connectionCredentialsType { name = publishRequest.DatasourceUserName, password = publishRequest.DatasourcePassword, embed = true, embedSpecified = true } } }; // Construct multipart request body using a boundary string to delimit sections. var boundaryString = Guid.NewGuid().ToString().Replace("-", ""); string contentType = String.Format("multipart/mixed; boundary={0}", boundaryString); byte[] requestBody = PublishRequestBuilder.BuildFileUploadBody(publishRequest.FilePath, requestPayload, boundaryString); // Issue request. var errorMessage = String.Format("Failed to publish workbook '{0}'", publishRequest.WorkbookName); ApiRequest apiRequest = new ApiRequest(uri, HttpMethod.Post, GetAuthToken(), headers: null, contentType: contentType, body: requestBody, timeoutSeconds: publishRequest.PublishingTimeoutSeconds); tsResponse response = apiRequest.IssueRequest(errorMessage); return(response.GetWorkbook()); }
/// <summary> /// Serializes the body of a tsRequest into a byte array. /// </summary> /// <param name="request">The request to serialize.</param> /// <param name="encoding">The encoding to use, e.g. ASCII or UTF-8.</param> /// <returns>Byte array representation of the body of the tsRequest.</returns> public static byte[] SerializeBody(this tsRequest request, string encoding = Constants.DefaultEncoding) { string requestBody; using (StringWriter sw = new StringWriter() { NewLine = "\r\n" }) { XmlSerializer xsSubmit = new XmlSerializer(typeof(tsRequest)); XmlWriterSettings settings = new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true }; using (XmlWriter writer = XmlWriter.Create(sw, settings)) { xsSubmit.Serialize(writer, request); requestBody = sw.ToString(); } } return(Encoding.GetEncoding(encoding).GetBytes(requestBody)); }
/// <summary> /// Serializes the body of a tsRequest into string format. /// </summary> /// <param name="request">The request to serialize.</param> /// <param name="encoding">The string encoding to use, e.g. ASCII or UTF-8.</param> /// <returns></returns> public static string SerializeBodyToString(this tsRequest request, string encoding = Constants.DefaultEncoding) { return(Encoding.GetEncoding(encoding).GetString(SerializeBody(request))); }
public PublishedWorkbookResult PublishWorkbookWithEmbeddedCredentials(PublishWorkbookRequest publishRequest) { PublishedWorkbookResult publishedWorkbookResult = new PublishedWorkbookResult(publishRequest); // Construct URI & compose request payload. var uri = Endpoints.GetPublishWorkbookUri(baseUri, publishRequest.SiteId, publishRequest.OverwriteExistingWorkbook); tsRequest requestPayload = new tsRequest { Item = new workbookType { name = Path.GetFileNameWithoutExtension(publishRequest.FilePath), showTabs = publishRequest.ShowSheetsAsTabs, showTabsSpecified = publishRequest.ShowSheetsAsTabs, project = new projectType { id = publishRequest.ProjectId }, connectionCredentials = new connectionCredentialsType { name = publishRequest.DatasourceUserName, password = publishRequest.DatasourcePassword, embed = true, embedSpecified = true } } }; // Construct multipart request body using a boundary string to delimit sections. var boundaryString = Guid.NewGuid().ToString().Replace("-", ""); string contentType = String.Format("multipart/mixed; boundary={0}", boundaryString); byte[] requestBody = PublishRequestBuilder.BuildRequestBody(publishRequest.FilePath, requestPayload, boundaryString); // Issue request. var errorMessage = String.Format("Failed to publish workbook '{0}'", publishRequest.WorkbookName); ApiRequest apiRequest = new ApiRequest(uri, HttpMethod.Post, GetAuthToken(), headers: null, contentType: contentType, body: requestBody, timeoutSeconds: publishRequest.publishingTimeoutSeconds); try { tsResponse response = apiRequest.TryIssueRequest(errorMessage); publishedWorkbookResult.IsSuccessful = true; publishedWorkbookResult.WorkbookId = response.GetWorkbook().id; publishedWorkbookResult.Uri = GetWorkbookUrl(response.GetWorkbook().contentUrl); } catch (Exception ex) { publishedWorkbookResult.IsSuccessful = false; publishedWorkbookResult.ErrorMessage = ex.Message; } // Add any tags to the newly-published workbook. if (publishedWorkbookResult.IsSuccessful) { try { AddTagsToWorkbook(publishedWorkbookResult.WorkbookId, publishRequest.Tags); } catch { // We swallow any errors here. } } return(publishedWorkbookResult); }