Like what you see? Have a play with our trial version.

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

In the scenario where ISV clients are installing on-premise, it is sometimes necessary to bundle pre-built content with the installation itself.  Pre-built content would generally exist in the form of YFX files that were exported from another instance of Yellowfin where the master-copy of the content was authored. 

There are several ways to import content into Yellowfin. It could be imported manually through the UI itself, or automatically installed as part of Yellowfin’s installation. There are two ways automated importing can be achieved, via the REST API or via the Standalone Importer

Importing via the Standalone Command Line Importer

The Standalone Importer can work without Yellowfin actually running. It can connect to the repository database directly and import content contained in a YFX file.

The command line importer can be run from the command line with following command:

Code Block
java -cp "appserver/webapps/ROOT/WEB-INF/lib/*:appserver/lib/*" com.hof.standalone.ImportData <properties file> <import file>

The classpath (-cp) parameter may require different quoting on different operating systems. The above command has the correct classpath for executing the command in the Yellowfin directory.

The <properties> file defines the connection details for the Yellowfin repository database. An example import.properties is located in Yellowfin/development/examples/standalone/import.properties on a standard install. 

The <import file> is a YFX or XML that has been exported from Yellowfin.

Importing via the REST API

Content can be imported into Yellowfin via the POST /api/rpc/import-export/import-content end-point, Import Content. When performing an import of initial content the Yellowfin service will need to be started, which could happen directly after installing Yellowfin itself.

The following code examples illustrate how to import a specified YFX file via the REST API. These consist of two requests to the /api/rpc/import-export end-point. The initial request enumerates the content contained in the export file. The second request imports the export file with importOptions created from the initial request, to add all the content, and skip none.

Code Block
languagejava
titleJava
collapsetrue
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/Yellowfin"";
        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();

    }

}
Code Block
languagec#
titleC#
collapsetrue
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/Yellowfin"";
            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;
            }
        }
    }
}
Code Block
titleGo
collapsetrue
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/Yellowfin""
        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
}
Code Block
languagejs
titleJavaScript
collapsetrue
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/Yellowfin"";
    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();
Code Block
languagephp
titlePHP
collapsetrue
<?php
function main() {
    echo ""Import YFX File\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $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();
?>
Code Block
languagepy
titlePython
collapsetrue
import json
import random
import time
import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    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()