Skip to content

Commit 7ede0da

Browse files
authored
Fix setting linked datasources for reports #398 (#400)
* #398 fix setting referenced datasource in report * add test case * remove test items to avoid interfering other test cases * move test items to dedicated folder * adjust expected values for recursive folder upload
1 parent 9c21e68 commit 7ede0da

File tree

6 files changed

+241
-36
lines changed

6 files changed

+241
-36
lines changed

ReportingServicesTools/Functions/CatalogItems/Rest/Set-RsRestItemDataSource.ps1

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ function Set-RsRestItemDataSource
100100
Description
101101
-----------
102102
Updates data sources to the specified $dataSources object. This example is only applicable to Paginated Reports.
103-
103+
104104
.LINK
105105
https://docs.microsoft.com/en-us/power-bi/report-server/connect-data-source-apis-pre-oct-2020
106106
#>
@@ -140,7 +140,7 @@ function Set-RsRestItemDataSource
140140
$WebSession = New-RsRestSessionHelper -BoundParameters $PSBoundParameters
141141
if ($null -ne $WebSession.Credentials -and $null -eq $Credential) {
142142
Write-Verbose "Using credentials from WebSession"
143-
$Credential = New-Object System.Management.Automation.PSCredential "$($WebSession.Credentials.UserName)@$($WebSession.Credentials.Domain)", $WebSession.Credentials.SecurePassword
143+
$Credential = New-Object System.Management.Automation.PSCredential "$($WebSession.Credentials.UserName)@$($WebSession.Credentials.Domain)", $WebSession.Credentials.SecurePassword
144144
}
145145
$ReportPortalUri = Get-RsPortalUriHelper -WebSession $WebSession
146146
$dataSourcesUri = $ReportPortalUri + "api/$RestApiVersion/{0}(Path='{1}')/DataSources"
@@ -177,33 +177,35 @@ function Set-RsRestItemDataSource
177177
}
178178
elseif ($ds.DataSourceSubType -eq $null)
179179
{
180-
# DataSourceType, ConnectionString and CredentialRetrieval must always be specified!
181-
if ($ds.DataSourceType -eq $null -or
182-
$ds.ConnectionString -eq $null -or
183-
$ds.CredentialRetrieval -eq $null -or
184-
!($ds.CredentialRetrieval -LIKE 'Integrated' -or
185-
$ds.CredentialRetrieval -LIKE 'Store' -or
186-
$ds.CredentialRetrieval -LIKE 'Prompt' -or
187-
$ds.CredentialRetrieval -LIKE 'None'))
188-
{
189-
throw "Invalid data source specified: $ds!"
190-
}
191-
elseif ($ds.DataModelDataSource -ne $null)
192-
{
193-
# since this is an embedded data source for Paginated Report/Shared data set,
194-
# you should not set any value to DataModelDataSource
195-
throw "You cannot specify DataModelDataSource for this datasource: $ds!"
196-
}
197-
198-
if ($ds.CredentialRetrieval -LIKE 'Store' -and $ds.CredentialsInServer -eq $null)
199-
{
200-
# CredentialsInServer must be specified for Store
201-
throw "CredentialsInServer must be specified when CredentialRetrieval is set to Store: $ds!"
202-
}
203-
elseif ($ds.CredentialRetrieval -LIKE 'Prompt' -and $ds.CredentialsByUser -eq $null)
204-
{
205-
# CredentialsByUser must be specified for Prompt
206-
throw "CredentialsByUser must be specified when CredentialRetrieval is set to Prompt: $ds!"
180+
if (!$ds.IsReference) {
181+
# DataSourceType, ConnectionString and CredentialRetrieval must always be specified!
182+
if ($ds.DataSourceType -eq $null -or
183+
$ds.ConnectionString -eq $null -or
184+
$ds.CredentialRetrieval -eq $null -or
185+
!($ds.CredentialRetrieval -LIKE 'Integrated' -or
186+
$ds.CredentialRetrieval -LIKE 'Store' -or
187+
$ds.CredentialRetrieval -LIKE 'Prompt' -or
188+
$ds.CredentialRetrieval -LIKE 'None'))
189+
{
190+
throw "Invalid data source specified: $ds!"
191+
}
192+
elseif ($ds.DataModelDataSource -ne $null)
193+
{
194+
# since this is an embedded data source for Paginated Report/Shared data set,
195+
# you should not set any value to DataModelDataSource
196+
throw "You cannot specify DataModelDataSource for this datasource: $ds!"
197+
}
198+
199+
if ($ds.CredentialRetrieval -LIKE 'Store' -and $ds.CredentialsInServer -eq $null)
200+
{
201+
# CredentialsInServer must be specified for Store
202+
throw "CredentialsInServer must be specified when CredentialRetrieval is set to Store: $ds!"
203+
}
204+
elseif ($ds.CredentialRetrieval -LIKE 'Prompt' -and $ds.CredentialsByUser -eq $null)
205+
{
206+
# CredentialsByUser must be specified for Prompt
207+
throw "CredentialsByUser must be specified when CredentialRetrieval is set to Prompt: $ds!"
208+
}
207209
}
208210
}
209211
else

Tests/CatalogItems/Rest/Set-RsRestItemDataSource.Tests.ps1

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,38 @@ Describe "Set-RsRestItemDataSource" {
212212
$fetchedDataSources = Get-RsRestItemDataSource -ReportPortalUri $reportPortalUri -RsItem $datasourcesReport
213213
$fetchedDataSources[0].CredentialRetrieval | Should Be "None"
214214
}
215+
216+
It "Updates linked datasource" {
217+
# uploading datasourceReport.rdl
218+
Write-RsRestCatalogItem -ReportPortalUri $reportPortalUri -Path "$localPath\linkedDatasources\datasourcesReportLinkedDS.rdl" -RsFolder $rsFolderPath
219+
Write-RsRestCatalogItem -ReportPortalUri $reportPortalUri -Path "$localPath\linkedDatasources\dsMaster.rsds" -RsFolder $rsFolderPath
220+
Write-RsRestCatalogItem -ReportPortalUri $reportPortalUri -Path "$localPath\linkedDatasources\dsModel.rsds" -RsFolder $rsFolderPath
221+
$datasourcesReport = "$rsFolderPath/datasourcesReportLinkedDS"
222+
223+
$datasources = Get-RsRestItemDataSource -ReportPortalUri $reportPortalUri -RsItem $datasourcesReport
224+
$datasources.Count | Should -Be 2
225+
$datasources[0].IsReference | Should -BeTrue
226+
$datasources[1].IsReference | Should -BeTrue
227+
$datasources[0].Id | Should -Be "00000000-0000-0000-0000-000000000000"
228+
$datasources[1].Id | Should -Be "00000000-0000-0000-0000-000000000000"
229+
230+
# now set the second to a valid path
231+
$datasources[0].Path = "$rsFolderPath/DSmaster"
232+
$datasources[1].Path = "$rsFolderPath/DSmodel"
233+
234+
Set-RsRestItemDataSource -ReportPortalUri $reportPortalUri -RsItem $datasourcesReport -RsItemType Report -DataSources $datasources -Verbose
235+
236+
$fetchedDataSources = Get-RsRestItemDataSource -ReportPortalUri $reportPortalUri -RsItem $datasourcesReport
237+
$fetchedDataSources | Should -HaveCount 2
238+
$fetchedDataSources[0].Path | Should -Be "$rsFolderPath/DSmaster"
239+
$fetchedDataSources[1].Path | Should -Be "$rsFolderPath/DSmodel"
240+
$fetchedDataSources[0].Id | Should -Not -Be "00000000-0000-0000-0000-000000000000"
241+
$fetchedDataSources[1].Id | Should -Not -Be "00000000-0000-0000-0000-000000000000"
242+
# remove test items
243+
Remove-RsRestCatalogItem -ReportPortalUri $reportPortalUri -RsItem $datasourcesReport -Confirm:$false
244+
Remove-RsRestCatalogItem -ReportPortalUri $reportPortalUri -RsItem "$rsFolderPath/DSmaster" -Confirm:$false
245+
Remove-RsRestCatalogItem -ReportPortalUri $reportPortalUri -RsItem "$rsFolderPath/DSmodel" -Confirm:$false
246+
}
215247
}
216248

217249
Context "ReportPortalUri parameter - Power BI Reports" {
@@ -379,9 +411,42 @@ Describe "Set-RsRestItemDataSource" {
379411
$fetchedDataSources = Get-RsRestItemDataSource -WebSession $rsSession -RsItem $datasourcesReport
380412
$fetchedDataSources[0].CredentialRetrieval | Should Be "None"
381413
}
414+
415+
It "Updates linked datasource" {
416+
# uploading datasourceReport.rdl
417+
Write-RsRestCatalogItem -WebSession $rsSession -Path "$localPath\linkedDatasources\datasourcesReportLinkedDS.rdl" -RsFolder $rsFolderPath
418+
Write-RsRestCatalogItem -WebSession $rsSession -Path "$localPath\linkedDatasources\dsMaster.rsds" -RsFolder $rsFolderPath
419+
Write-RsRestCatalogItem -WebSession $rsSession -Path "$localPath\linkedDatasources\dsModel.rsds" -RsFolder $rsFolderPath
420+
$datasourcesReport = "$rsFolderPath/datasourcesReportLinkedDS"
421+
422+
$datasources = Get-RsRestItemDataSource -WebSession $rsSession -RsItem $datasourcesReport
423+
$datasources.Count | Should -Be 2
424+
$datasources[0].IsReference | Should -BeTrue
425+
$datasources[1].IsReference | Should -BeTrue
426+
$datasources[0].Id | Should -Be "00000000-0000-0000-0000-000000000000"
427+
$datasources[1].Id | Should -Be "00000000-0000-0000-0000-000000000000"
428+
429+
# now set the second to a valid path
430+
$datasources[0].Path = "$rsFolderPath/DSmaster"
431+
$datasources[1].Path = "$rsFolderPath/DSmodel"
432+
433+
Set-RsRestItemDataSource -WebSession $rsSession -RsItem $datasourcesReport -RsItemType Report -DataSources $datasources -Verbose
434+
435+
$fetchedDataSources = Get-RsRestItemDataSource -WebSession $rsSession -RsItem $datasourcesReport
436+
$fetchedDataSources | Should -HaveCount 2
437+
$fetchedDataSources[0].Path | Should -Be "$rsFolderPath/DSmaster"
438+
$fetchedDataSources[1].Path | Should -Be "$rsFolderPath/DSmodel"
439+
$fetchedDataSources[0].Id | Should -Not -Be "00000000-0000-0000-0000-000000000000"
440+
$fetchedDataSources[1].Id | Should -Not -Be "00000000-0000-0000-0000-000000000000"
441+
442+
# remove test items
443+
Remove-RsRestCatalogItem -WebSession $rsSession -RsItem $datasourcesReport -Confirm:$false
444+
Remove-RsRestCatalogItem -WebSession $rsSession -RsItem "$rsFolderPath/DSmaster" -Confirm:$false
445+
Remove-RsRestCatalogItem -WebSession $rsSession -RsItem "$rsFolderPath/DSmodel" -Confirm:$false
446+
}
382447
}
383448

384-
Context "ReportPortalUri parameter - Power BI Reports" {
449+
Context "WebSession parameter - Power BI Reports" {
385450
$sqlPowerBIReport = ""
386451

387452
BeforeEach {

Tests/CatalogItems/Write-RsFolderContent.Tests.ps1

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,21 @@ Describe "Write-RsFolderContent" {
8282
Write-RsFolderContent -Path $localReportPath -RsFolder $folderPath -Recurse
8383
It "Should upload a local subFolder with Recurse Parameter" {
8484
$uploadedFolders = (Get-RsFolderContent -RsFolder $folderPath -Recurse ) | Where-Object TypeName -eq 'Folder' | Sort-Object -Property Name -Descending
85-
$uploadedFolders.Count | Should Be 3
85+
$uploadedFolders.Count | Should Be 4
8686
$uploadedFolders[0].Name | Should Be 'testResources2'
87-
$uploadedFolders[1].Name | Should Be 'imagesResources'
88-
$uploadedFolders[2].Name | Should Be 'datasources'
87+
$uploadedFolders[1].Name | Should Be 'linkedDatasources'
88+
$uploadedFolders[2].Name | Should Be 'imagesResources'
89+
$uploadedFolders[3].Name | Should Be 'datasources'
8990
}
9091

9192
It "Should upload a report that is in a folder and a second report that is in a subfolder" {
9293
$uploadedReports = (Get-RsFolderContent -RsFolder $folderPath -Recurse ) | Where-Object TypeName -eq 'Report'
93-
$uploadedReports.Count | Should Be 4
94+
$uploadedReports.Count | Should Be 5
9495
}
9596

96-
It "Should upload a local RsDataSource in Report Server" {
97+
It "Should upload local RsDataSources in Report Server" {
9798
$uploadedDataSource = (Get-RsFolderContent -RsFolder $folderPath -Recurse ) | Where-Object TypeName -eq 'DataSource'
98-
$uploadedDataSource.Name | Should Be 'SutWriteRsFolderContent_DataSource'
99+
$uploadedDataSource | ForEach-Object { $_.Name | Should BeIn 'SutWriteRsFolderContent_DataSource', 'dsMaster','dsModel' }
99100
}
100101

101102
It "Should upload a local DataSet in Report Server" {
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Report MustUnderstand="df" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns:df="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition/defaultfontfamily">
3+
<df:DefaultFontFamily>Segoe UI</df:DefaultFontFamily>
4+
<AutoRefresh>0</AutoRefresh>
5+
<DataSources>
6+
<DataSource Name="master">
7+
<DataSourceReference>DSmaster</DataSourceReference>
8+
<rd:SecurityType>None</rd:SecurityType>
9+
<rd:DataSourceID>24e9bb1a-7346-4007-9ff9-5bec2e485891</rd:DataSourceID>
10+
</DataSource>
11+
<DataSource Name="model">
12+
<DataSourceReference>DSinvalid</DataSourceReference>
13+
<rd:SecurityType>None</rd:SecurityType>
14+
<rd:DataSourceID>19977be0-7084-48d9-a184-659be45fb3fd</rd:DataSourceID>
15+
</DataSource>
16+
</DataSources>
17+
<ReportSections>
18+
<ReportSection>
19+
<Body>
20+
<ReportItems>
21+
<Textbox Name="ReportTitle">
22+
<CanGrow>true</CanGrow>
23+
<KeepTogether>true</KeepTogether>
24+
<Paragraphs>
25+
<Paragraph>
26+
<TextRuns>
27+
<TextRun>
28+
<Value />
29+
<Style>
30+
<FontFamily>Segoe UI Light</FontFamily>
31+
<FontSize>28pt</FontSize>
32+
</Style>
33+
</TextRun>
34+
</TextRuns>
35+
<Style />
36+
</Paragraph>
37+
</Paragraphs>
38+
<rd:WatermarkTextbox>Title</rd:WatermarkTextbox>
39+
<rd:DefaultName>ReportTitle</rd:DefaultName>
40+
<Height>0.5in</Height>
41+
<Width>5.5in</Width>
42+
<Style>
43+
<Border>
44+
<Style>None</Style>
45+
</Border>
46+
<PaddingLeft>2pt</PaddingLeft>
47+
<PaddingRight>2pt</PaddingRight>
48+
<PaddingTop>2pt</PaddingTop>
49+
<PaddingBottom>2pt</PaddingBottom>
50+
</Style>
51+
</Textbox>
52+
</ReportItems>
53+
<Height>2.25in</Height>
54+
<Style>
55+
<Border>
56+
<Style>None</Style>
57+
</Border>
58+
</Style>
59+
</Body>
60+
<Width>6in</Width>
61+
<Page>
62+
<PageFooter>
63+
<Height>0.45in</Height>
64+
<PrintOnFirstPage>true</PrintOnFirstPage>
65+
<PrintOnLastPage>true</PrintOnLastPage>
66+
<ReportItems>
67+
<Textbox Name="ExecutionTime">
68+
<CanGrow>true</CanGrow>
69+
<KeepTogether>true</KeepTogether>
70+
<Paragraphs>
71+
<Paragraph>
72+
<TextRuns>
73+
<TextRun>
74+
<Value>=Globals!ExecutionTime</Value>
75+
<Style />
76+
</TextRun>
77+
</TextRuns>
78+
<Style>
79+
<TextAlign>Right</TextAlign>
80+
</Style>
81+
</Paragraph>
82+
</Paragraphs>
83+
<rd:DefaultName>ExecutionTime</rd:DefaultName>
84+
<Top>0.2in</Top>
85+
<Left>4in</Left>
86+
<Height>0.25in</Height>
87+
<Width>2in</Width>
88+
<Style>
89+
<Border>
90+
<Style>None</Style>
91+
</Border>
92+
<PaddingLeft>2pt</PaddingLeft>
93+
<PaddingRight>2pt</PaddingRight>
94+
<PaddingTop>2pt</PaddingTop>
95+
<PaddingBottom>2pt</PaddingBottom>
96+
</Style>
97+
</Textbox>
98+
</ReportItems>
99+
<Style>
100+
<Border>
101+
<Style>None</Style>
102+
</Border>
103+
</Style>
104+
</PageFooter>
105+
<LeftMargin>1in</LeftMargin>
106+
<RightMargin>1in</RightMargin>
107+
<TopMargin>1in</TopMargin>
108+
<BottomMargin>1in</BottomMargin>
109+
<Style />
110+
</Page>
111+
</ReportSection>
112+
</ReportSections>
113+
<ReportParametersLayout>
114+
<GridLayoutDefinition>
115+
<NumberOfColumns>4</NumberOfColumns>
116+
<NumberOfRows>2</NumberOfRows>
117+
</GridLayoutDefinition>
118+
</ReportParametersLayout>
119+
<rd:ReportUnitType>Inch</rd:ReportUnitType>
120+
<rd:ReportID>68930910-5594-43ac-aed6-c0d26ea291b9</rd:ReportID>
121+
</Report>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<DataSourceDefinition>
2+
<Extension>SQL</Extension>
3+
<ConnectString>Data Source=localhost;Initial Catalog=master</ConnectString>
4+
<UseOriginalConnectString>False</UseOriginalConnectString>
5+
<OriginalConnectStringExpressionBased>False</OriginalConnectStringExpressionBased>
6+
<CredentialRetrieval>Integrated</CredentialRetrieval>
7+
<Enabled>True</Enabled>
8+
</DataSourceDefinition>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<DataSourceDefinition>
2+
<Extension>SQL</Extension>
3+
<ConnectString>Data Source=localhost;Initial Catalog=model</ConnectString>
4+
<UseOriginalConnectString>False</UseOriginalConnectString>
5+
<OriginalConnectStringExpressionBased>False</OriginalConnectStringExpressionBased>
6+
<CredentialRetrieval>Integrated</CredentialRetrieval>
7+
<Enabled>True</Enabled>
8+
</DataSourceDefinition>

0 commit comments

Comments
 (0)