Yellowfin インスタンスへの初期コンテンツのインポート
- YUKA SAITO
- Yuka Saito
ISVクライアントがオンプレミスにインストールするシナリオでは、インストール自体に構築済みのコンテンツをバンドルする必要がある場合があります。構築済みのコンテンツは、通常コンテンツのマスターコピーが作成されたYellowfinの別のインスタンスからエクスポートされたYFXファイルの形式で存在します。
Yellowfinにコンテンツをインポートするにはいくつかの方法があります。UIから手動でインポートすることも、Yellowfinのインストールの一部として自動的にインストールすることもできます。自動インポートには、REST APIを使用する方法と、スタンドアローンインポーターを使用する方法の2つがあります。
スタンドアローンコマンドラインインポーターを使用したインポート
スタンドアローンインポーターは、実際にYellowfinを起動していなくても動作します。リポジトリデータベースに直接接続し、YFXファイルに含まれるコンテンツをインポートすることができます。
コマンドラインインポーターは、コマンドラインから以下のコマンドで実行できます。
java -cp "appserver/webapps/ROOT/WEB-INF/lib/*:appserver/lib/*" com.hof.standalone.ImportData <properties file> <import file>
クラスパス (-cp) パラメーターには、OSシステムによって異なる引用符が必要な場合があります。上記のコマンドには、Yellowfin ディレクトリでコマンドを実行するための正しいクラスパスが含まれています。
<properties> ファイルは、Yellowfin リポジトリデータベースの接続詳細を定義します。import.properties の例は、標準インストールのYellowfin/development/examples/standalone/import.properties にあります。
<import file> は、YellowfinからエクスポートされたYFXまたはXMLファイルです。
REST APIを使用したインポート
コンテンツは、POST /api/rpc/import-export/import-content エンドポイント Import Content を使用してYellowfinにインポートすることができます。初期コンテンツをインポートする場合は、Yellowfin サービスを開始する必要があります。これは、Yellowfin 自体をインストールした直後に実行できます。
以下のコード例では、REST APIを使用して指定したYFXファイルをインポートする方法を示しています。これらは、/api/rpc/import-export エンドポイントへの2つのリクエストで構成されています。最初のリクエストでは、エクスポートファイルに含まれるコンテンツが列挙されています。2番目のリクエストでは、最初のリクエストで作成されたimportOptions を使用してエクスポートファイルをインポートし、すべてのコンテンツを追加して、何もスキップしません。
package rest.code.examples; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Random; import org.apache.hc.client5.http.entity.mime.HttpMultipartMode; import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; import org.apache.hc.client5.http.fluent.Content; import org.apache.hc.client5.http.fluent.Request; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpEntity; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; /** * Import a YFX file via the Yellowfin REST API */ public class ImportYFXFile { public static void main(String[] args) throws Exception { System.out.println("Import YFX File"); String host = "http://localhost:8080/"; String restUsername = "admin@yellowfin.com.au"; String restPassword = "test"; String fileToImport = "/Downloads/Test.yfx"; Path importFile = Paths.get(fileToImport); byte[] fileContents = Files.readAllBytes(importFile); String token = generateToken(host, restUsername, restPassword); // Upload File for initial analysis, and to fetch the number of import items. HttpEntity getImportFileContentMulitpartEntity = MultipartEntityBuilder .create() .setMode(HttpMultipartMode.LEGACY) .setCharset(Charset.forName("UTF-8")) .addBinaryBody("contentToProcess", fileContents , ContentType.DEFAULT_BINARY, importFile.getFileName().toString()) .build(); System.out.println("Getting Import File Contents"); Content getImportContentContent = Request.post(host + "/api/rpc/import-export/get-import-content") .addHeader("Authorization", "YELLOWFIN ts=" + System.currentTimeMillis() + " , nonce=" + new Random().nextLong() + ", token=" + token) .addHeader("Accept", "application/vnd.yellowfin.api-v1+json") .addHeader("Content-Type", getImportFileContentMulitpartEntity.getContentType()) .addHeader("cache-control", "no-cache") .body(getImportFileContentMulitpartEntity) .execute() .returnContent(); JsonObject jsonObject = new JsonParser().parse(getImportContentContent.asString()).getAsJsonObject(); JsonElement itemList = jsonObject.get("items"); JsonArray items = itemList.getAsJsonArray(); // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD. String importOptions = ""; for (int i=0; i < items.size(); i++ ) { JsonObject item = items.getAsJsonArray().get(i).getAsJsonObject(); System.out.println("Item " + i + " " + item.get("resourceType").getAsString() + " " + item.get("resourceName").getAsString() + " found"); if (i>0) { importOptions = importOptions + ","; } importOptions = importOptions + "{ \"itemIndex\": " + i + ", \"optionKey\": \"SKIP\", \"optionValue\": false }, { \"itemIndex\": " + i + ", \"optionKey\": \"OPTION\", \"optionValue\": \"ADD\" }"; } // Upload File for for import, with import options populated HttpEntity importContentMultipartEntity = MultipartEntityBuilder .create() .setMode(HttpMultipartMode.LEGACY) .setCharset(Charset.forName("UTF-8")) .addBinaryBody("contentToProcess", fileContents , ContentType.DEFAULT_BINARY, importFile.getFileName().toString()) .addTextBody("importOptions", "[" + importOptions + "]", ContentType.APPLICATION_JSON) .build(); System.out.println("Importing Content"); Content importContentContent = Request.post(host + "/api/rpc/import-export/import-content") .addHeader("Authorization", "YELLOWFIN ts=" + System.currentTimeMillis() + " , nonce=" + new Random().nextLong() + ", token=" + token) .addHeader("Accept", "application/vnd.yellowfin.api-v1+json") .addHeader("Content-Type", importContentMultipartEntity.getContentType()) .addHeader("cache-control", "no-cache") .body(importContentMultipartEntity) .execute() .returnContent(); System.out.println("Content Import Complete"); System.out.println(importContentContent.asString()); } /* * This function generates an access token for a user that will grant them access to * call REST API endpoints. */ public static String generateToken(String host, String username, String password) throws IOException { Content c = Request.post(host + "/api/refresh-tokens") .addHeader("Authorization", "YELLOWFIN ts=" + System.currentTimeMillis() + " , nonce=" + new Random().nextLong()) .addHeader("Accept", "application/vnd.yellowfin.api-v1+json") .addHeader("Content-Type", "application/json") .bodyString("{ \"userName\": \""+ username + "\",\"password\": \""+ password + "\"}", null) .execute().returnContent(); JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject(); JsonElement accessToken = jsonObject.getAsJsonObject("_embedded").getAsJsonObject("accessToken").get("securityToken"); if (accessToken!=null) { System.out.println("Access Token: " + accessToken); } else { System.out.println("Token not retrieved successfully"); System.exit(-1); } return accessToken.getAsString(); } }
using System.Net.Http.Headers; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace YellowfinAPIExamples { public class ImportYFXFile { static async Task Main(string[] args) { Console.WriteLine("Import YFX File"); string host = "http://localhost:8080/"; string restUsername = "admin@yellowfin.com.au"; string restPassword = "test"; string fileToImport = "/Downloads/Test.yfx"; byte[] fileContents = await File.ReadAllBytesAsync(fileToImport); string token = await GenerateToken(host, restUsername, restPassword); // Upload File for initial analysis, and to fetch the number of import items. var getImportFileContentMultipartContent = new MultipartFormDataContent { { new ByteArrayContent(fileContents), "contentToProcess", Path.GetFileName(fileToImport) } }; Console.WriteLine("Getting Import File Contents"); using (var httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("YELLOWFIN", $"ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()} , nonce={new Random().NextInt64()}, token={token}"); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.yellowfin.api-v1+json")); var getImportContentResponse = await httpClient.PostAsync($"{host}/api/rpc/import-export/get-import-content", getImportFileContentMultipartContent); string getImportContentResponseBody = await getImportContentResponse.Content.ReadAsStringAsync(); JObject jsonObject = JObject.Parse(getImportContentResponseBody); JArray items = (JArray)jsonObject["items"]; // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD. StringBuilder importOptionsBuilder = new StringBuilder(); for (int i = 0; i < items.Count; i++) { JObject item = (JObject)items[i]; Console.WriteLine($"Item {i} {item["resourceType"]} {item["resourceName"]} found"); if (i > 0) { importOptionsBuilder.Append(","); } importOptionsBuilder.Append($"{{ \"itemIndex\": {i}, \"optionKey\": \"SKIP\", \"optionValue\": false }}, {{ \"itemIndex\": {i}, \"optionKey\": \"OPTION\", \"optionValue\": \"ADD\" }}"); } string importOptions = importOptionsBuilder.ToString(); // Upload File for import, with import options populated var importContentMultipartContent = new MultipartFormDataContent { { new ByteArrayContent(fileContents), "contentToProcess", Path.GetFileName(fileToImport) }, { new StringContent($"[{importOptions}]", Encoding.UTF8, "application/json"), "importOptions" } }; Console.WriteLine("Importing Content"); var importContentResponse = await httpClient.PostAsync($"{host}/api/rpc/import-export/import-content", importContentMultipartContent); string importContentResponseBody = await importContentResponse.Content.ReadAsStringAsync(); Console.WriteLine("Content Import Complete"); Console.WriteLine(importContentResponseBody); } } /* * This function generates an access token for a user that will grant them access to * call REST API endpoints. */ static async Task<string> GenerateToken(string host, string username, string password) { using (var client = new HttpClient()) { long nonce = new Random().NextInt64(); var request = new HttpRequestMessage(HttpMethod.Post, $"{host}/api/refresh-tokens"); request.Headers.Add("Authorization", $"YELLOWFIN ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"); request.Headers.Add("Accept", "application/vnd.yellowfin.api-v1+json"); request.Content = new StringContent(JsonConvert.SerializeObject(new { userName = username, password = password }), Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(request); string responseContent = await response.Content.ReadAsStringAsync(); JObject jsonObject = JObject.Parse(responseContent); string accessToken = jsonObject["_embedded"]["accessToken"]["securityToken"].ToString(); if (!string.IsNullOrEmpty(accessToken)) { Console.WriteLine("Access Token: " + accessToken); } else { Console.WriteLine("Token not retrieved successfully"); Environment.Exit(-1); } return accessToken; } } } }
package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "math/rand" "mime/multipart" "net/http" "path/filepath" "strings" "time" ) func main() { fmt.Println("Import YFX File") host := "http://localhost:8080/" restUsername := "admin@yellowfin.com.au" restPassword := "test" fileToImport := "/Downloads/Test.yfx" fileContents, err := ioutil.ReadFile(fileToImport) if err != nil { fmt.Println("Error reading file:", err) return } token, err := generateToken(host, restUsername, restPassword) if err != nil { fmt.Println("Error generating token:", err) return } // Upload File for initial analysis, and to fetch the number of import items. var buf bytes.Buffer writer := multipart.NewWriter(&buf) part, err := writer.CreateFormFile("contentToProcess", filepath.Base(fileToImport)) if err != nil { fmt.Println("Error creating form file:", err) return } part.Write(fileContents) writer.Close() req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/rpc/import-export/get-import-content", host), &buf) if err != nil { fmt.Println("Error creating request:", err) return } nonce := rand.Int63() req.Header.Set("Authorization", fmt.Sprintf("YELLOWFIN ts=%d, nonce=%d, token=%s", time.Now().UnixMilli(), nonce, token)) req.Header.Set("Accept", "application/vnd.yellowfin.api-v1+json") req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("cache-control", "no-cache") client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() getImportContentContent, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response body:", err) return } var jsonObject map[string]interface{} if err := json.Unmarshal(getImportContentContent, &jsonObject); err != nil { fmt.Println("Error parsing JSON response:", err) return } items := jsonObject["items"].([]interface{}) var importOptions strings.Builder for i, item := range items { itemMap := item.(map[string]interface{}) fmt.Printf("Item %d %s %s found\n", i, itemMap["resourceType"].(string), itemMap["resourceName"].(string)) if i > 0 { importOptions.WriteString(",") } importOptions.WriteString(fmt.Sprintf(`{ "itemIndex": %d, "optionKey": "SKIP", "optionValue": false }, { "itemIndex": %d, "optionKey": "OPTION", "optionValue": "ADD" }`, i, i)) } // Upload File for import, with import options populated buf.Reset() writer = multipart.NewWriter(&buf) part, err = writer.CreateFormFile("contentToProcess", filepath.Base(fileToImport)) if err != nil { fmt.Println("Error creating form file:", err) return } part.Write(fileContents) writer.WriteField("importOptions", fmt.Sprintf("[%s]", importOptions.String())) writer.Close() req, err = http.NewRequest("POST", fmt.Sprintf("%s/api/rpc/import-export/import-content", host), &buf) if err != nil { fmt.Println("Error creating request:", err) return } req.Header.Set("Authorization", fmt.Sprintf("YELLOWFIN ts=%d, nonce=%d, token=%s", time.Now().UnixMilli(), nonce, token)) req.Header.Set("Accept", "application/vnd.yellowfin.api-v1+json") req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("cache-control", "no-cache") resp, err = client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() importContentContent, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response body:", err) return } fmt.Println("Content Import Complete") fmt.Println(string(importContentContent)) } /* * This function generates an access token for a user that will grant them access to * call REST API endpoints. */ func generateToken(host, username, password string) (string, error) { nonce := rand.Int63() requestBody, err := json.Marshal(map[string]string{ "userName": username, "password": password, }) if err != nil { fmt.Println("Error marshaling request body:", err) return "", err } client := &http.Client{} request, err := http.NewRequest("POST", fmt.Sprintf("%s/api/refresh-tokens", host), bytes.NewBuffer(requestBody)) if err != nil { fmt.Println("Error creating request:", err) return "", err } request.Header.Set("Authorization", fmt.Sprintf("YELLOWFIN ts=%d, nonce=%d", time.Now().UnixMilli(), nonce)) request.Header.Set("Accept", "application/vnd.yellowfin.api-v1+json") request.Header.Set("Content-Type", "application/json") response, err := client.Do(request) if err != nil { fmt.Println("Error sending request:", err) return "", err } defer response.Body.Close() responseBody, err := ioutil.ReadAll(response.Body) if err != nil { fmt.Println("Error reading response body:", err) return "", err } var jsonResponse map[string]interface{} if err := json.Unmarshal(responseBody, &jsonResponse); err != nil { fmt.Println("Error parsing JSON response:", err) return "", err } accessToken, ok := jsonResponse["_embedded"].(map[string]interface{})["accessToken"].(map[string]interface{})["securityToken"].(string) if !ok { fmt.Println("Token not retrieved") return "", fmt.Errorf("Token not retrieved successfully") } fmt.Println("Access Token:", accessToken) return accessToken, nil }
const fetch = require("node-fetch"); const fs = require("fs"); const path = require("path"); const FormData = require("form-data"); async function main() { console.log("Import YFX File"); const host = "http://localhost:8080/"; const restUsername = "admin@yellowfin.com.au"; const restPassword = "test"; const fileToImport = "/Downloads/Test.yfx"; const fileContents = fs.readFileSync(fileToImport); const token = await generateToken(host, restUsername, restPassword); if (token === null) { console.error("Failed to retrieve access token"); return; } // Upload File for initial analysis, and to fetch the number of import items const form1 = new FormData(); form1.append("contentToProcess", fileContents, path.basename(fileToImport)); const nonce1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); const headers1 = { 'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce1}, token=${token}`, 'Accept': 'application/vnd.yellowfin.api-v1+json', 'cache-control': 'no-cache', ...form1.getHeaders() }; try { console.log("Getting Import File Contents"); const response1 = await fetch(`${host}/api/rpc/import-export/get-import-content`, { method: 'POST', headers: headers1, body: form1 }); if (!response1.ok) { throw new Error(`HTTP error! Status: ${response1.status}`); } const getImportContentContent = await response1.json(); const items = getImportContentContent.items; // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD let importOptions = items.map((item, i) => { console.log(`Item ${i} ${item.resourceType} ${item.resourceName} found`); return [ `{ "itemIndex": ${i}, "optionKey": "SKIP", "optionValue": false }`, `{ "itemIndex": ${i}, "optionKey": "OPTION", "optionValue": "ADD" }` ]; }).flat().join(", "); // Upload File for import, with import options populated const form2 = new FormData(); form2.append("contentToProcess", fileContents, path.basename(fileToImport)); form2.append("importOptions", `[${importOptions}]`); const nonce2 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); const headers2 = { 'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce2}, token=${token}`, 'Accept': 'application/vnd.yellowfin.api-v1+json', 'cache-control': 'no-cache', ...form2.getHeaders() }; console.log("Importing Content"); const response2 = await fetch(`${host}/api/rpc/import-export/import-content`, { method: 'POST', headers: headers2, body: form2 }); if (!response2.ok) { throw new Error(`HTTP error! Status: ${response2.status}`); } const importContentContent = await response2.text(); console.log("Content Import Complete"); console.log(importContentContent); } catch (error) { console.error("Error:", error.message); } } /* * This function generates an access token for a user that will grant them access to * call REST API endpoints. */ async function generateToken(host, username, password) { // Generate nonce const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); // Create request headers const headers = { 'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`, 'Accept': 'application/vnd.yellowfin.api-v1+json', 'Content-Type': 'application/json' }; // Create request body const body = JSON.stringify({ userName: username, password: password }); try { // Make POST request const response = await fetch(`${host}/api/refresh-tokens`, { method: 'POST', headers: headers, body: body }); // Check if request was successful if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } // Parse JSON response const jsonResponse = await response.json(); const accessToken = jsonResponse._embedded.accessToken.securityToken; if (accessToken) { console.log(`Access Token: ${accessToken}`); } else { console.log("Token not retrieved"); } return accessToken; } catch (error) { console.error("Error:", error.message); } return null; } main();
<?php function main() { echo "Import YFX File\n"; $host = "http://localhost:8080/"; $restUsername = "admin@yellowfin.com.au"; $restPassword = "test"; $fileToImport = "/Downloads/Test.yfx"; $fileContents = file_get_contents($fileToImport); try { $token = generateToken($host, $restUsername, $restPassword); } catch (Exception $e) { echo "Error generating token: " . $e->getMessage(); return; } // Upload File for initial analysis, and to fetch the number of import items. $getImportFileContentMultipartEntity = buildMultipartEntityForAnalysis($fileContents, basename($fileToImport)); echo "Getting Import File Contents\n"; try { $getImportContentContent = sendMultipartRequest($host, $token, $getImportFileContentMultipartEntity, "/api/rpc/import-export/get-import-content"); } catch (Exception $e) { echo "Error sending request: " . $e->getMessage(); return; } $jsonObject = json_decode($getImportContentContent, true); $items = $jsonObject['items']; // List content, and generate importOptions for each item, setting it to SKIP=false and OPTION=ADD. $importOptions = []; foreach ($items as $i => $item) { echo "Item $i " . $item['resourceType'] . " " . $item['resourceName'] . " found\n"; $importOptions[] = [ "itemIndex" => $i, "optionKey" => "SKIP", "optionValue" => false ]; $importOptions[] = [ "itemIndex" => $i, "optionKey" => "OPTION", "optionValue" => "ADD" ]; } // Upload File for import, with import options populated $importContentMultipartEntity = buildMultipartEntity($fileContents, basename($fileToImport), json_encode($importOptions)); echo "Importing Content\n"; try { $importContentContent = sendMultipartRequest($host, $token, $importContentMultipartEntity, "/api/rpc/import-export/import-content"); echo "Content Import Complete\n"; echo $importContentContent; } catch (Exception $e) { echo "Error sending request: " . $e->getMessage(); } } /* * This function generates an access token for a user that will grant them access to * call REST API endpoints. */ function generateToken($host, $username, $password) { // Generate nonce $nonce = mt_rand(); // Create request headers $headers = [ 'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce, 'Accept: application/vnd.yellowfin.api-v1+json', 'Content-Type: application/json' ]; // Create request body $body = json_encode([ "userName" => $username, "password" => $password ]); // Make POST request $response = httpRequest('POST', "$host/api/refresh-tokens", $headers, $body); // Parse JSON response $jsonResponse = json_decode($response, true); if (isset($jsonResponse["_embedded"]["accessToken"]["securityToken"])) { $accessToken = $jsonResponse["_embedded"]["accessToken"]["securityToken"]; echo "Access Token: $accessToken\n"; return $accessToken; } else { throw new Exception("Token not retrieved successfully"); } } function buildMultipartEntityForAnalysis($fileContents, $fileName) { $boundary = uniqid(); $multipartBody = "--$boundary\r\n"; $multipartBody .= 'Content-Disposition: form-data; name="contentToProcess"; filename="' . $fileName . "\"\r\n"; $multipartBody .= "Content-Type: application/octet-stream\r\n\r\n"; $multipartBody .= $fileContents . "\r\n"; $multipartBody .= "--$boundary--"; return $multipartBody; } function buildMultipartEntity($fileContents, $fileName, $importOptions) { $boundary = uniqid(); $multipartBody = "--$boundary\r\n"; $multipartBody .= 'Content-Disposition: form-data; name="contentToProcess"; filename="' . $fileName . "\"\r\n"; $multipartBody .= "Content-Type: application/octet-stream\r\n\r\n"; $multipartBody .= $fileContents . "\r\n"; $multipartBody .= "--$boundary\r\n"; $multipartBody .= 'Content-Disposition: form-data; name="importOptions"' . "\r\n"; $multipartBody .= "Content-Type: application/json\r\n\r\n"; $multipartBody .= $importOptions . "\r\n"; $multipartBody .= "--$boundary--"; return $multipartBody; } function sendMultipartRequest($host, $token, $multipartBody, $endpoint) { $boundary = substr($multipartBody, 2, strpos($multipartBody, "\r\n") - 2); $headers = [ 'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . mt_rand() . ', token=' . $token, 'Accept: application/vnd.yellowfin.api-v1+json', 'Content-Type: multipart/form-data; boundary=' . $boundary, 'cache-control: no-cache' ]; $response = httpRequest('POST', "$host$endpoint", $headers, $multipartBody); return $response; } function httpRequest($method, $url, $headers, $data = null) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); if ($data !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } $response = curl_exec($ch); if (curl_errno($ch)) { throw new Exception('Error: ' . curl_error($ch)); } curl_close($ch); return $response; } main(); ?>
import json import random import time import requests def main(): host = "http://localhost:8080/" rest_username = "admin@yellowfin.com.au" rest_password = "test" file_to_import = "/Downloads/Test.yfx" try: with open(file_to_import, 'rb') as f: file_contents = f.read() except IOError as e: print(f"Error reading file: {e}") return try: token = generate_token(host, rest_username, rest_password) except Exception as e: print(f"Error generating token: {e}") return # Upload File for initial analysis, and to fetch the number of import items files = { 'contentToProcess': ('Test.yfx', file_contents, 'application/octet-stream') } headers = { 'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={random.randint(0, 2**63 - 1)}, token={token}', 'Accept': 'application/vnd.yellowfin.api-v1+json', 'cache-control': 'no-cache' } print("Getting Import File Contents") try: response = requests.post(f"{host}/api/rpc/import-export/get-import-content", headers=headers, files=files) response.raise_for_status() import_content = response.json() except requests.RequestException as e: print(f"Error getting import file contents: {e}") return items = import_content.get("items", []) import_options = [] for i, item in enumerate(items): print(f"Item {i} {item['resourceType']} {item['resourceName']} found") import_options.append({ "itemIndex": i, "optionKey": "SKIP", "optionValue": False }) import_options.append({ "itemIndex": i, "optionKey": "OPTION", "optionValue": "ADD" }) import_options_json = json.dumps(import_options) # Upload File for import, with import options populated files = { 'contentToProcess': ('Test.yfx', file_contents, 'application/octet-stream'), 'importOptions': (None, import_options_json, 'application/json') } print("Importing Content") try: response = requests.post(f"{host}/api/rpc/import-export/import-content", headers=headers, files=files) response.raise_for_status() print("Content Import Complete") print(response.text) except requests.RequestException as e: print(f"Error importing content: {e}") def generate_token(host, username, password): nonce = random.randint(0, 2**63 - 1) request_body = json.dumps({ "userName": username, "password": password }) headers = { 'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}', 'Accept': 'application/vnd.yellowfin.api-v1+json', 'Content-Type': 'application/json' } response = requests.post(f"{host}/api/refresh-tokens", headers=headers, data=request_body) if response.status_code == 200: json_response = response.json() access_token = json_response["_embedded"]["accessToken"]["securityToken"] print("Access Token:", access_token) return access_token else: raise Exception("Token not retrieved successfully") if __name__ == "__main__": main()