Page History
...
The following extract from a YFExport.xml file shows in red where tokens could be replaced by an automated process for generating a datasource for use with client source substitution.
...
<source>
<id>132641</id>
<sourceName>PostgreSQL Connection for[TENANT_NAME]</
...
sourceName>
<sourceDescription>PostgreSQL Connection for [TENANT_NAME]</
...
sourceDescription>
<databasePath>public</databasePath>
<userName>[USERNAME]</
...
userName>
<password>[ENCRYPTED_PASSWORD]</
...
password>
<connectionTypeCode>GENERICUSER</connectionTypeCode>
<connectionMethodCode>JDBC</connectionMethodCode>
<connectionDriver>org.postgresql.Driver</connectionDriver>
<databaseURL>jdbc:postgresql://[SERVER_ADDRESS]:5432/[DATABASE_NAME]
...
></databaseURL>
<databaseTypeCode>POSTGRESQL</databaseTypeCode>
<minConnections>1</minConnections>
<maxConnections>5</maxConnections>
<connectionRefreshTime>180</connectionRefreshTime>
<connectionTimeOut>180</connectionTimeOut>
<accessCode>UNSECURE</accessCode>
<maxRowCount>10000</maxRowCount>
<maxAnalysisRowCount>0</maxAnalysisRowCount>
<broadcastPermitted>true</broadcastPermitted>
<subscribePermitted>true</subscribePermitted>
<dataProfileEnabled>true</dataProfileEnabled>
<localTimezoneCode>AUSTRALIA/LORD_HOWE</localTimezoneCode>
<secondaryMinConnections>0</secondaryMinConnections>
<secondaryMaxConnections>0</secondaryMaxConnections>
<secondaryConnectionRefreshTime>0</secondaryConnectionRefreshTime>
<secondaryConnectionTimeOut>0</secondaryConnectionTimeOut>
<lastModifiedGMTDateTime>20240607025556.000000</lastModifiedGMTDateTime>
<sourceUUID>7d7543c0-e9c7-4a80-ab14-
...
73181e4d0694</sourceUUID>
<filterList/>
<sourceParameterList>
<sourceParameter>
<id>0</id>
<parameterTypeCode>TEXT</parameterTypeCode>
<parameterKey>DATABASE</parameterKey>
<parameterIndex>0</parameterIndex>
<parameterValue>[DATABASE_NAME]</
...
parameterValue>
<documentId>0</documentId>
<userVisible>true</userVisible>
</sourceParameter>
<sourceParameter>
<id>0</id>
<parameterTypeCode>TEXT</parameterTypeCode>
<parameterKey>HOSTNAME</parameterKey>
<parameterIndex>0</parameterIndex>
<parameterValue>[SERVER_ADDRESS]</
...
parameterValue>
<documentId>0</documentId>
<userVisible>true</userVisible>
</sourceParameter>
Once an export file has been automatically injected with tokens, it can be uploaded via the REST API using the the POST /api/rpc/import-export/import-content end-point, Import Content.
...
This takes a datasource model of this format:
Code Block |
---|
{ "sourceName": "Client Database", "sourceDescription": "", "sourceType": "POSTGRESQL", "connectionType": "JDBC", "connectionTypeCode": "GENERICUSER", "connectionDriver": "org.postgresql.Driver", "connectionString": "jdbc:postgresql://192.168.1.100:5432/testdata", "connectionTimeout": 180, "userName": "postgres", "minimumConnections": 1, "maximumConnections": 5, "refreshTime": 180, "timezone": "AUSTRALIA/SYDNEY", "accessLevelCode": "UNSECURE", "maxRows": 10000, "maxAnalysisRows": 0, "inheritChildSourceFilters": false, "sourceLogIndicator": false, "sourceOptions": [ { "optionKey": "ISOLATIONLEVEL", "optionValue": "1.0", "valueDataType": "1" }, { "optionKey": "USESCHEMA", "optionValue": "true", "valueDataType": "6" }, { "optionKey": "HOSTNAME", "optionValue": "192.168.1.100", "valueDataType": "2" }, { "optionKey": "PORT", "optionValue": "5432", "valueDataType": "1" }, { "optionKey": "DATABASE", "optionValue": "testdata", "valueDataType": "2" }, { "optionKey": "YF_DRIVER_SELECTION", "optionValue": "org.postgresql.Driver", "valueDataType": "2" } ] } |
The main body of the model is similar to the model returned by the GET /api/data-sources end-point. If creating a new source similar to the Primary Organization datasource, the data returned by GET /api/data-sources can be used as a template.
...
The following examples illustrate how to create a new datasource via the POST /api/data-sources end-point:.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package rest.code.examples; import java.io.IOException; import java.util.Random; import org.apache.hc.client5.http.fluent.Content; import org.apache.hc.client5.http.fluent.Request; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; /** * Create a datasource using the Yellowfin REST API */ public class CreateADataSource { public static void main(String[] args) throws Exception { String host = ""http://localhost:8080/yellowfinHead""; String restUsername = ""admin@yellowfin.com.au""; String restPassword = ""test""; String createDataSourcePayload = ""{\n"" + "" \""sourceName\"": \""PostgreSQL Database Created Via Import\"",\n"" + "" \""sourceDescription\"": \""\"",\n"" + "" \""sourceType\"": \""POSTGRESQL\"",\n"" + "" \""connectionType\"": \""JDBC\"",\n"" + "" \""connectionTypeCode\"": \""GENERICUSER\"",\n"" + "" \""connectionDriver\"": \""org.postgresql.Driver\"",\n"" + "" \""connectionString\"": \""jdbc:postgresql://192.168.1.100:5432/testdata\"",\n"" + "" \""connectionTimeout\"": 180,\n"" + "" \""userName\"": \""postgres\"",\n"" + "" \""minimumConnections\"": 1,\n"" + "" \""maximumConnections\"": 5,\n"" + "" \""refreshTime\"": 180,\n"" + "" \""timezone\"": \""AUSTRALIA/SYDNEY\"",\n"" + "" \""accessLevelCode\"": \""UNSECURE\"",\n"" + "" \""maxRows\"": 10000,\n"" + "" \""maxAnalysisRows\"": 0,\n"" + "" \""inheritChildSourceFilters\"": false,\n"" + "" \""sourceLogIndicator\"": false,\n"" + "" \""sourceOptions\"": [\n"" + ""{\n"" + ""\""optionKey\"": \""ISOLATIONLEVEL\"",\n"" + ""\""optionValue\"": \""1.0\"",\n"" + ""\""valueDataType\"": \""1\""\n"" + ""},\n"" + ""{\n"" + ""\""optionKey\"": \""USESCHEMA\"",\n"" + ""\""optionValue\"": \""true\"",\n"" + ""\""valueDataType\"": \""6\""\n"" + ""},\n"" + ""{\n"" + ""\""optionKey\"": \""HOSTNAME\"",\n"" + ""\""optionValue\"": \""192.168.1.100\"",\n"" + ""\""valueDataType\"": \""2\""\n"" + ""},\n"" + ""{\n"" + ""\""optionKey\"": \""PORT\"",\n"" + ""\""optionValue\"": \""5432\"",\n"" + ""\""valueDataType\"": \""1\""\n"" + ""},\n"" + ""{\n"" + ""\""optionKey\"": \""DATABASE\"",\n"" + ""\""optionValue\"": \""testdata\"",\n"" + ""\""valueDataType\"": \""2\""\n"" + ""},\n"" + ""{\n"" + ""\""optionKey\"": \""YF_DRIVER_SELECTION\"",\n"" + ""\""optionValue\"": \""org.postgresql.Driver\"",\n"" + ""\""valueDataType\"": \""2\""\n"" + ""}\n"" + "" ]\n"" + ""}"" ; String token = generateToken(host, restUsername, restPassword); System.out.println(""Payload: "" + createDataSourcePayload); Content c = Request.post(host + ""/api/data-sources"") .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token) .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"") .addHeader(""Content-Type"", ""application/json"") .bodyString(createDataSourcePayload, null) .execute().returnContent(); System.out.print(c.asString()); } 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(); } } |
...
A list of datasources can be retrieved with the GET /api/data-sources end-point, Get All Data Sources. This will return a datasource model of the following form:
Code Block |
---|
{ "sourceId": 132780, "sourceName": "PostgreSQL Connection for NEWCLIENT", "sourceDescription": "PostgreSQL Connection for NEWCLIENT", "sourceType": "POSTGRESQL", "connectionType": "JDBC", "connectionTypeCode": "GENERICUSER", "connectionDriver": "org.postgresql.Driver", "connectionPath": "public", "connectionString": "jdbc:postgresql://localhost:5432/testdata", "connectionTimeout": 180, "userName": "postgres", "minimumConnections": 1, "maximumConnections": 5, "refreshTime": 180, "timezone": "AUSTRALIA/LORD_HOWE", "accessLevelCode": "UNSECURE", "maxRows": 10000, "maxAnalysisRows": 0, "inheritChildSourceFilters": false, "sourceLogIndicator": false } |
This service can be used to find the internal integer identifier for the datasource (sourceId) for a given data source name.
The following code examples illustrate how to retrieve a list of data sources from the system:.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package rest.code.examples; import java.io.IOException; import java.util.Random; import org.apache.hc.client5.http.fluent.Content; import org.apache.hc.client5.http.fluent.Request; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; /** * List DataSources using the Yellowfin REST API */ public class ListDataSources { public static void main(String[] args) throws Exception { System.out.print(""List Datasources""); String host = ""http://localhost:8080/Yellowfin""; String restUsername = ""admin@yellowfin.com.au""; String restPassword = ""test""; String token = generateToken(host, restUsername, restPassword); Content c = Request.get(host + ""/api/data-sources"") .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token) .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"") .addHeader(""Content-Type"", ""application/json"") .execute().returnContent(); System.out.print(c.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(); } } |
...
The following examples illustrate how to link a Client Datasource (identified by its name) to a Primary Org Datasource (identified by its name):.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package rest.code.examples; import java.io.IOException; import java.util.Random; import org.apache.hc.client5.http.fluent.Content; import org.apache.hc.client5.http.fluent.Request; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; /** * Attach a Client Datasource to Primary Org Source for Source Substitution using the Yellowfin REST API */ public class AttachClientDatasourceToPrimarySource { public static void main(String[] args) throws Exception { System.out.print(""Attach a Tenant Source to Primary Org Source for Source Substitution""); String host = ""http://localhost:8080/Yellowfin""; String restUsername = ""admin@yellowfin.com.au""; String restPassword = ""test""; String primarySourceName = ""PostgreSQL Connection at Primary Org""; String clientSourceName = ""PostgreSQL Connection for NEWCLIENT""; String clientOrgReference = ""NEWCLIENT""; String clientToken = generateToken(host, restUsername, restPassword, clientOrgReference); Integer clientOrgSourceId = findDataSourceForSourceNameAtClient(host, clientToken, clientSourceName); System.out.println(""Client Org Source Id: "" + clientOrgSourceId); String primaryToken = generateToken(host, restUsername, restPassword, null); Integer primaryOrgSourceId = findDataSourceForSourceNameAtClient(host, primaryToken, primarySourceName); System.out.println(""Primary Org Source Id: "" + clientOrgSourceId); Content c = Request.get(host + ""/api/data-sources/"" + primaryOrgSourceId + ""/client-data-sources/?clientSourceId="" + clientOrgSourceId) .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + primaryToken) .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"") .addHeader(""Content-Type"", ""application/json"") .execute().returnContent(); System.out.print(c.asString()); } /* * This function finds a datasource for a given datasource name * call REST API endpoints. */ private static Integer findDataSourceForSourceNameAtClient(String host, String token, String sourceName) throws IOException { Content c = Request.get(host + ""/api/data-sources"") .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token) .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"") .addHeader(""Content-Type"", ""application/json"") .execute().returnContent(); JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject(); JsonElement sourceList = jsonObject.get(""items""); JsonArray sources = sourceList.getAsJsonArray(); for (int i=0; i < sources.size(); i++ ) { JsonObject source = sources.getAsJsonArray().get(i).getAsJsonObject(); if (sourceName.equals(source.get(""sourceName"").getAsString())) return source.get(""sourceId"").getAsInt(); } System.out.println(""Data Source could not be found for name:"" + sourceName); System.exit(-1); return null; } /* * 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, String tenantClientOrgRefId) throws IOException { String tokenBody = ""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""""; if (tenantClientOrgRefId!=null) { tokenBody = tokenBody + "",\""clientOrgRef\"": \""""+ tenantClientOrgRefId + ""\""""; } tokenBody = tokenBody + ""}""; 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(tokenBody, 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(); } } |
...