Wie Sie den Report Server auf einer Azure-Container-Instanz bereitstellen und über eine Azure-Funktion verwenden

Da wir immer wieder Anfragen erhalten, List & Label aus einer Azure Function aufzurufen, und wir List & Label in diesem Kontext aufgrund verschiedener Einschränkungen wie z.B. GDI-Sandboxing nicht direkt verwenden können, dachte ich, es könnte interessant sein, einen anderen Weg in die Cloud zu erkunden. Diesmal mit dem Report Server. Mit seiner REST-API können Sie sogar Berichte aus einer Azure-Funktion erstellen. Aber lassen Sie uns den Prozess Schritt für Schritt durchgehen.

Report Server auf einer Azure Instanz installieren

Zunächst benötigen Sie eine Report Server-Instanz, die von außen zugänglich ist. Da wir ohnehin planen, ihn von Azure aus zu nutzen, ist es sinnvoll, ihn in einem Windows-Docker-Image zu installieren und auf Azure Container Instances bereitzustellen. Diese Tutorials helfen Ihnen bei den ersten Schritten:

Daten von Azure SQL verwenden

Natürlich kann der Report Server problemlos Daten aus Azure SQL-Datenquellen nutzen. Für diesen Test – und nur um sicherzustellen, dass wir alles nutzen, was in Azure verfügbar ist – habe ich eine Instanz der berüchtigten Northwind-Datenbank in Azure bereitgestellt. Die Verbindung zu ihr ist einfach. Fügen Sie einfach eine neue Azure-SQL-Datenquelle hinzu und legen Sie ihre grundlegenden Eigenschaften wie folgt fest:

Configure Microsoft Azure SQL

Erstellen Sie anschließend einen neuen Bericht auf der Grundlage dieser Datenquelle:

bericht-aus-neuer-datenquelle
Edit Report Server Template

Auf den Report Server über REST aus einer Azure-Funktion zugreifen

Das letzte Glied in der Kette besteht nun darin, diese Report Server-Instanz zu verwenden und von einer Azure-Funktion aus zu berichten. Natürlich kann diese Funktion auch Parameter entgegennehmen und diese als Berichtsparameter an den Server weiterleiten. Erstellen Sie zu diesem Zweck eine http-ausgelöste Funktionsinstanz:

Create New Azure Function Application
Create New Azure Function Application

Stellen Sie sicher, dass Sie die Autorisierungsebene hier auf Anonym setzen, um die Verwendung zu erleichtern. Wenn Sie die Standardstufe „Funktion“ wählen, müssen Sie in Anfragen den Funktionsschlüssel angeben, um auf Ihren Funktionsendpunkt zuzugreifen.

Visual Studio erstellt ein Projekt und eine Klasse, die Boilerplate-Code für den Funktionstyp HTTP-Trigger enthält. Der Boilerplate-Code sendet eine HTTP-Antwort, die einen Wert aus dem Anforderungstext oder der Abfragezeichenfolge enthält. Das HttpTrigger-Attribut gibt an, dass die Funktion durch eine HTTP-Anforderung ausgelöst wird.

Um die Funktion umzubenennen, ändern Sie einfach das Methodenattribut FunctionName in den gewünschten Wert:

  1. Klicken Sie im Datei-Explorer mit der rechten Maustaste auf die Datei Function1.cs und benennen Sie sie in CreateRSReport.cs um.
  2. Benennen Sie im Code die Klasse Function1 in CreateRSReport um.
  3. Benennen Sie in der HttpTrigger-Methode namens Run das Methodenattribut FunctionName in CreateRSReport um.

Ihre Funktionsdefinition sollte nun wie der folgende Code aussehen:

 [FunctionName("CreateRSReport")]
  public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)

Stellen Sie nun sicher, dass Sie die REST-API im Report Server über „Verwaltung > Erweiterte Einstellungen > REST-API vor der Verwendung aktivieren. Einen Schnellstart finden Sie hier. Wenn Sie die API durchsuchen möchten, stellen Sie außerdem sicher, dass Sie die Swagger-Dokumentation über „Verwaltung > Erweiterte Einstellungen > REST API > Spezifikation durch Swagger / OpenAPI“ aktivieren und auf „Dokumentation der REST API anzeigen“ klicken.

REST-API Report Server

Erstellen Sie dann ein API-Konto mit Token:

  1. Legen Sie in der Benutzerverwaltung einen Benutzer „apiuser“ an und wählen Sie bei „Registrierung konfigurieren“ den Authentifizierungstyp „API-Konto mit Token“. Bestätigen Sie mit „weiter“.
  2. Erzeugen und definieren Sie ein neues Client-Token mit „Übernehmen“. Kopieren Sie dieses Token. Das Token kann nicht erneut angezeigt werden. Wenn Sie einen neuen Token generieren, wird der bisher verwendete Token ungültig und alle Clients müssen neu konfiguriert werden!

Damit können Sie sich nun von Ihrer Azure-Funktion aus wie folgt mit dem Report Server verbinden:

using combit.ReportServer.ClientApi;
using combit.ReportServer.ClientApi.Objects;
 
// Create a connection to the Report Server
ReportServerClient rsClient = await ReportServer.ConnectAsync("http://.../combitreportserver",
new ClientOptions()
{
Authentication = new ApiTokenAuthentication("apiuser", "...")
});

Der nächste Schritt besteht darin, die Berichts-ID des zu exportierenden Berichts zu ermitteln. Am einfachsten ist es, die Berichtsvorlage im Report Server zu bearbeiten und die ID aus der URL zu kopieren:

Edit Report Server Template

Mit Hilfe der Berichtsvorlagen-ID können Sie den Bericht aus Ihrer Funktion heraus z.B. als PDF exportieren:

...
// Set Report Template ID
string reportTemplateId = "FEF8ED98-52C5-4A95-AAF9-F03B5069DA75";
 
// With null as export profile, the default export profile of the report template will be used
string exportProfileId = null;
 
// Prepare an export and set the options:
PreparedReport preparedExport = rsClient.Exporter.PrepareExport(reportTemplateId, exportProfileId);
preparedExport.DisableCaching = true;
 
// Set export path
string exportPath = Path.GetTempPath();
 
// Query parameter for Report Parameter Category
string id = req.Query["Category"];
 
// Add Report Parameters
preparedExport.ReportParameters.Add("Category", id);
 
// Exports the report and download the export file
ExportResult result = await preparedExport.ExportAsync();
await result.DownloadFilesAsync(exportPath, CancellationToken.None);
 
return new FileContentResult (System.IO.File.ReadAllBytes(Path.Combine(Path.GetTempPath(), "azure_test.pdf")), "application/pdf");
...

Azure Funktion lokal testen

In Visual Studio sind die Azure Functions Core Tools integriert. Diese ermöglichen ein einfaches lokales Debugging von Azure Functions. Drücken Sie einfach F5 in Visual Studio, um es auszuprobieren und stellen Sie sicher, dass die Firewall so konfiguriert ist, dass die Tools HTTP-Anfragen verarbeiten können. Wenn dieser lokale Server eingerichtet ist und läuft, können Sie Ihre Funktion testen – entweder über einen Browser oder innerhalb einer Testanwendung:

var client = new HttpClient();
var url = "http://localhost:7071/api/CreateRSReport?Category=2";
HttpResponseMessage response = await client.GetAsync(url);

Wenn Sie mit dem Ergebnis zufrieden sind, können Sie Ihre Funktion in Azure bereitstellen. Klicken Sie im Solution-Explorer mit der rechten Maustaste auf das Projekt und wählen Sie Veröffentlichen. Wählen Sie Azure alsZielund dann Weiter. Wählen Sie dann eine vorhandene Funktionsanwendung oder erstellen Sie eine neue:

Publish New Azure Function

Dann veröffentlichen Sie die Funktion:

Succesfully Published Azure Function

Wenn Sie nun Ihre URL und Funktion öffnen, erhalten Sie den PDF-Download wie erwartet von der neu erstellten Azure-Funktion.

Schreibe einen Kommentar