Skip to main content
Woohoo! Qlik Community has won “Best in Class Community” in the 2024 Khoros Kudos awards!
Announcements
Nov. 20th, Qlik Insider - Lakehouses: Driving the Future of Data & AI - PICK A SESSION
cancel
Showing results for 
Search instead for 
Did you mean: 
hvdbunte
Partner - Contributor III
Partner - Contributor III

edit script load editor with .net SDK

Hi,

We started using the .net SDK in combination with the Qlik-Cli for Windows version for deploying apps to multiple streams.
For every stream we would like to change some variables in the Data load editor. Is that possible with the SDK? I found some options for changing the script with the engine JSON api but not with the SDK.

We have these 3 variables that we use to connect databases, we would like to change for every stream:

let CustomerName = 'CustomerA'
let DWH_CustomerName = 'DWH_CustomerA'
let Source_CustomerName = 'Source_CustomerA'

Would it be possible to search and replace these variable values in the load script?

Kind Regards

Labels (1)
1 Solution

Accepted Solutions
Marc
Employee
Employee

this can be achieved in PowerShell too, but takes a little setup first.

First you need to download and Extract the QlikSense.NetSDK from the following

https://www.nuget.org/packages/QlikSense.NetSDK 
as well as a Version 6.0.x of Newtonsoft.json.

https://www.nuget.org/packages/Newtonsoft.Json/6.0.1

 

once you have extracted both, you will need to update the following to the correct locations.

 

 

 

add-type -path "D:\Extracted\Nuget\packages\newtonsoft.json\6.0.1\lib\net45\Newtonsoft.Json.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Engine.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.JsonRpc.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.Client.dll"

 

 

 

Once these "Add-Type" commands have been run, we can access the QlikSese.NetSDK C# Objects in PowerShell.

The Following will need the SenseServerURL updated to reflect the environment you wish to connect to and when run will prompt for Credentials to use to establish the NTLMViaProxy connection. 

 

 

 

$SenseServerURL = "https://sense01"
$QlikCeredentials = Get-Credential
$ProxyUsesSSL = $true
$TrustAllCerts = $true

#Create the Location Object
$Location = [Qlik.Engine.Location]::FromUri($SenseServerURL)

#Establish a Authenticated Session to the Location.
[Qlik.Engine.LocationExtensions]::AsNtlmUserViaProxy($Location,$ProxyUsesSSL,$QlikCeredentials,$TrustAllCerts)

 

 

 

once the authenticated connection has been established you can then use the Location object for the subsequent requests, such as Getting the AppIdentifier for the App you want to update the Script on.

 

 

#Get All App Identifiers
$AppIdentifiers = [Qlik.Engine.LocationExtensions]::GetAppIdentifiers($Location)
#Get App Identifiers for Apps With a Specific name
$AppIdentifiersByName = [Qlik.Engine.LocationExtensions]::AppsWithNameOrDefault($Location,"Operations Monitor")
#Get App Identifier for App With a Specific ID
$AppID = "39beb78d-ddc4-4346-8023-92c023851385"
$AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($Location,$AppID)

 

 

once you have the AppIdentifier you can get the Qlik Engine App

 

 

$Session = $null
$NoData = $true
$QEApp = [Qlik.Engine.LocationExtensions]::App($Location,$AppIdentifiersByID,$Session,$NoData)

 

 

 

Once you have the Qlik Engine app you can then call the GetScript() and SetScript("ScriptString") Methods.

obviously this is just an example, and you can adapt the UpdatedAppScript sent back as required.

 

 

#Once we have the App we can Get the Load Script
$AppScript = $QEApp.GetScript()

#WE can them manipulate the Load Scripts
$UpdatedAppScript = $AppScript -replace "ValueToReplace","ReplacedWith"

#and finally update the app with the new Load script
$QEApp.SetScript($UpdatedAppScript)

 

 

 

To extend this a little further you can use Qlik-CLI-Windows to get information from the QRS  to get Apps published to a specific stream, then use that information to get the AppIdentifier and then the Qlik Engine App.

 

 

#Example.
#You can use Qlik-CLI-Windows to get all of the APPIDs for apps published to a specific stream
$QRSAppsByStream = Get-QlikApp -filter "Stream.Name eq 'Everyone'"

#Then for each app in the stream we can get the AppIdentifier and App
$QEApps = ForEach ($QRSApp in $QRSAppsByStream){
    $AppID = $QRSApp.Id
    $AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($Location,$AppID)
    $QEApp = [Qlik.Engine.LocationExtensions]::App($Location,$AppIdentifiersByID,$null,$true)
    $QEApp
}

 

 

 

And finally putting it altogether. 

We use the Qlik-CLI-Windows to get all the apps in the Everyone stream

Then we cycle through each of them getting the AppIdentifier and Qlik Engine App, Getting the Script for each and manipulating it by replacing "ValueToReplace" with "ReplacedWith"

 

 

 

#Qlik-CLI-Windows
$StreamName = "Everyone"
Connect-Qlik -TrustAllCerts 
$QRSAppsByStream = Get-QlikApp -filter "Stream.Name eq '$StreamName'"


#QlikSense.NetSDK
add-type -path "D:\Extracted\Nuget\packages\newtonsoft.json\6.0.1\lib\net45\Newtonsoft.Json.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Engine.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.JsonRpc.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.Client.dll"

$SenseServerURL = "https://sense01"
$QlikCeredentials = Get-Credential
$ProxyUsesSSL = $true
$TrustAllCerts = $true

$Location = [Qlik.Engine.Location]::FromUri($SenseServerURL)
[Qlik.Engine.LocationExtensions]::AsNtlmUserViaProxy($Location,$ProxyUsesSSL,$QlikCeredentials,$TrustAllCerts)

$Session = $null
$NoData = $true

$QEApps = ForEach ($QRSApp in $QRSAppsByStream){
$AppID = $QRSApp.Id
#Get the AppIdentifier
$AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($Location,$AppID)

#Get the QEApp
$QEApp = [Qlik.Engine.LocationExtensions]::App($Location,$AppIdentifiersByID,$Session,$NoData)

#Once we have the App we can Get the Load Script
$AppScript = $QEApp.GetScript()

#We can them manipulate the Load Scripts
$UpdatedAppScript = $AppScript -replace "ValueToReplace","ReplacedWith"

#and finally update the app with the new Load script
$QEApp.SetScript($UpdatedAppScript)

}

 

 

 

View solution in original post

15 Replies
Øystein_Kolsrud
Employee
Employee

Yes, certainly. All endpoints available in the engine JSON API are also exposed in the SDK. In your case it's just a matter of doing a combination of "GetScript" and "SetScript" like this:

var script = app.GetScript();
var newScript = ...do changes to script...
app.SetScript(newScript);

 And then you're likely to want to finish it up with a "DoReload" to refresh the app data based on your script modifications:

app.DoReload();

 

Marc
Employee
Employee

this can be achieved in PowerShell too, but takes a little setup first.

First you need to download and Extract the QlikSense.NetSDK from the following

https://www.nuget.org/packages/QlikSense.NetSDK 
as well as a Version 6.0.x of Newtonsoft.json.

https://www.nuget.org/packages/Newtonsoft.Json/6.0.1

 

once you have extracted both, you will need to update the following to the correct locations.

 

 

 

add-type -path "D:\Extracted\Nuget\packages\newtonsoft.json\6.0.1\lib\net45\Newtonsoft.Json.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Engine.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.JsonRpc.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.Client.dll"

 

 

 

Once these "Add-Type" commands have been run, we can access the QlikSese.NetSDK C# Objects in PowerShell.

The Following will need the SenseServerURL updated to reflect the environment you wish to connect to and when run will prompt for Credentials to use to establish the NTLMViaProxy connection. 

 

 

 

$SenseServerURL = "https://sense01"
$QlikCeredentials = Get-Credential
$ProxyUsesSSL = $true
$TrustAllCerts = $true

#Create the Location Object
$Location = [Qlik.Engine.Location]::FromUri($SenseServerURL)

#Establish a Authenticated Session to the Location.
[Qlik.Engine.LocationExtensions]::AsNtlmUserViaProxy($Location,$ProxyUsesSSL,$QlikCeredentials,$TrustAllCerts)

 

 

 

once the authenticated connection has been established you can then use the Location object for the subsequent requests, such as Getting the AppIdentifier for the App you want to update the Script on.

 

 

#Get All App Identifiers
$AppIdentifiers = [Qlik.Engine.LocationExtensions]::GetAppIdentifiers($Location)
#Get App Identifiers for Apps With a Specific name
$AppIdentifiersByName = [Qlik.Engine.LocationExtensions]::AppsWithNameOrDefault($Location,"Operations Monitor")
#Get App Identifier for App With a Specific ID
$AppID = "39beb78d-ddc4-4346-8023-92c023851385"
$AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($Location,$AppID)

 

 

once you have the AppIdentifier you can get the Qlik Engine App

 

 

$Session = $null
$NoData = $true
$QEApp = [Qlik.Engine.LocationExtensions]::App($Location,$AppIdentifiersByID,$Session,$NoData)

 

 

 

Once you have the Qlik Engine app you can then call the GetScript() and SetScript("ScriptString") Methods.

obviously this is just an example, and you can adapt the UpdatedAppScript sent back as required.

 

 

#Once we have the App we can Get the Load Script
$AppScript = $QEApp.GetScript()

#WE can them manipulate the Load Scripts
$UpdatedAppScript = $AppScript -replace "ValueToReplace","ReplacedWith"

#and finally update the app with the new Load script
$QEApp.SetScript($UpdatedAppScript)

 

 

 

To extend this a little further you can use Qlik-CLI-Windows to get information from the QRS  to get Apps published to a specific stream, then use that information to get the AppIdentifier and then the Qlik Engine App.

 

 

#Example.
#You can use Qlik-CLI-Windows to get all of the APPIDs for apps published to a specific stream
$QRSAppsByStream = Get-QlikApp -filter "Stream.Name eq 'Everyone'"

#Then for each app in the stream we can get the AppIdentifier and App
$QEApps = ForEach ($QRSApp in $QRSAppsByStream){
    $AppID = $QRSApp.Id
    $AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($Location,$AppID)
    $QEApp = [Qlik.Engine.LocationExtensions]::App($Location,$AppIdentifiersByID,$null,$true)
    $QEApp
}

 

 

 

And finally putting it altogether. 

We use the Qlik-CLI-Windows to get all the apps in the Everyone stream

Then we cycle through each of them getting the AppIdentifier and Qlik Engine App, Getting the Script for each and manipulating it by replacing "ValueToReplace" with "ReplacedWith"

 

 

 

#Qlik-CLI-Windows
$StreamName = "Everyone"
Connect-Qlik -TrustAllCerts 
$QRSAppsByStream = Get-QlikApp -filter "Stream.Name eq '$StreamName'"


#QlikSense.NetSDK
add-type -path "D:\Extracted\Nuget\packages\newtonsoft.json\6.0.1\lib\net45\Newtonsoft.Json.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Engine.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.JsonRpc.dll"
add-type -path "D:\Extracted\Nuget\packages\qliksense.netsdk\15.1.1\lib\net452\Qlik.Sense.Client.dll"

$SenseServerURL = "https://sense01"
$QlikCeredentials = Get-Credential
$ProxyUsesSSL = $true
$TrustAllCerts = $true

$Location = [Qlik.Engine.Location]::FromUri($SenseServerURL)
[Qlik.Engine.LocationExtensions]::AsNtlmUserViaProxy($Location,$ProxyUsesSSL,$QlikCeredentials,$TrustAllCerts)

$Session = $null
$NoData = $true

$QEApps = ForEach ($QRSApp in $QRSAppsByStream){
$AppID = $QRSApp.Id
#Get the AppIdentifier
$AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($Location,$AppID)

#Get the QEApp
$QEApp = [Qlik.Engine.LocationExtensions]::App($Location,$AppIdentifiersByID,$Session,$NoData)

#Once we have the App we can Get the Load Script
$AppScript = $QEApp.GetScript()

#We can them manipulate the Load Scripts
$UpdatedAppScript = $AppScript -replace "ValueToReplace","ReplacedWith"

#and finally update the app with the new Load script
$QEApp.SetScript($UpdatedAppScript)

}

 

 

 

hvdbunte
Partner - Contributor III
Partner - Contributor III
Author

Thanks a lot for the detailed explanation. I am trying to implement this, but I have one additional question.

I tried a reload of the data from the app, when I run:

 

$QEApp.DoReload()

 

When I run I get a response True but the app doesn't reload. 

Do I need to run another command?

Thank you

Øystein_Kolsrud
Employee
Employee

Perhaps you need to do a "DoSave" as well?

Marc
Employee
Employee

if you call the DoReload method.

$QEApp.DoReload

you can see that it requires a number of overloads.

OverloadDefinitions
-------------------
bool DoReload(int mode, bool partial, bool debug) 

we can find more information on what each of these is on the following DoReload method 

$QEApp.DoReload(0,$False,$False)

however, you will notice in the "Returns" section of the DoReload method page. 
If the data load has successfully finished, no matter how the indexing behaves, _true_ is returned. This happens even if there is a timeout, a memory limit is reached, or any other error occurs during the indexing.

With that in mind you, if your reload takes a while you may be hitting a timeout... so you may be better off using the DoReloadEx method as this will return a DoReloadExResult that contains a link to the ScriptLog file which may be useful in determining any errors.

$DoReloadExParams = [Qlik.Engine.DoReloadExParams]::new()
$QEApp.DoReloadEx($DoReloadExParams)

 

Alternatively. 

if you used the sample script I provided where we leveraged Qlik-CLI to find the app, before using the QlikSense.NetSDK

you will have a variable called AppID.. which you can use this with the Qlik-CLI to run the Reload via the QRS. 

Invoke-QlikPost -path "/qrs/app/$($AppId)/reload"

 

 

hvdbunte
Partner - Contributor III
Partner - Contributor III
Author

Hi Marc,

Thanks again for you reply.

Like I wrote earlier I am new to this, working with API's and Qlik-CLI.

So I have a couple of followup questions:

When I use this:

$DoReloadExParams = [Qlik.Engine.DoReloadExParams]::new()
$QEApp.DoReloadEx($DoReloadExParams)

What does that ::New() do?

The above command returns the outcome if it's true or false, that is really helpful for checking if the app was published correctly.
But it doesn't change the Lastreloadtime. Would that be possible? Or should we also run the invoke command to get that fixed? Because the invoke command updates the Lastreloadtime but doesn't give any information if the reload task was successful or not.

Again both Marc and yko thanks allot for your help!

Regards,

Hendri

Marc
Employee
Employee

$DoReloadExParams = [Qlik.Engine.DoReloadExParams]::new()

This creates a new .net object of the type DoReloadExParams (same as New-Object Qlik.Engine.DoReloadExParams)

you can view the object by running the variable $DoReloadExParams by itself. 

this object type is a input requirement for the Method DoReloadEx. 
$QEApp.DoReloadEx($DoReloadExParams)

performing the reload in this method will cause the app to reload and this will be visible in the apps last reload time.

 chrome_SdMdWvQ77j.png

however it does not update the LastReloadTime in the QMC as this is linked to the QRS Apis.

in order to see the updated time in both you will need to use the QRS Api to perform the reload rather then the DoReload method

Invoke-QlikPost -path "/qrs/app/$($AppId)/reload"

 

 

hvdbunte
Partner - Contributor III
Partner - Contributor III
Author

Thank again, I tried the reload but it didn't change the date/time of the reload, but I will use both to solve this.



 

hvdbunte
Partner - Contributor III
Partner - Contributor III
Author

Hi,

After creating a script for this to change a load script, I still hit an issue. When I reload the script with this code:

$computerName="qlik-test.xxx.xx"
$computerPort="4747"
$userDirectory="QLIK-TEST"
$userName="abc"
$uri = "wss://$($computerName):$($computerPort)"

$location = [Qlik.Engine.Location]::FromUri($uri)
[Qlik.Engine.LocationExtensions]::AsDirectConnection($location,$userDirectory,$userName)

$AppIdentifiersByID = [Qlik.Engine.LocationExtensions]::AppWithId($location,$newappToPublishid)
$QEApp = [Qlik.Engine.LocationExtensions]::App($location,$AppIdentifiersByID,$Session,$NoData)

$DoReloadExParams = [Qlik.Engine.DoReloadExParams]::new()
$QEApp.DoReloadEx($DoReloadExParams)

Invoke-QlikPost -path "/qrs/app/$($newAppToPublishId)/reload"

But when I put this in a loop to go through different apps and check if the reload is correct with the script that is stored when doing a reload. Everyting is working fine. But when I check the app, then I see that the reload didn't go correctly.

For example if I reload app A, and publish this to stream A then the first time it runs correct.
When i change App A to reload into another stream, say stream B then the change of app A is correct but when i reload the app to publish in stream B it still contains the information of stream A. But when I look in the script log file it should be correct, but when i check in the app it is not reloaded.

Any idea how to solve this?