Chapter 26. Writing Custom Reporting Services Extensions


In This Chapter

• Common Considerations for Custom Reporting Services Extensions: Implementation, Deployment, and Security

• Delivery Extension

• Interactions Between User, SSRS, and a Delivery Extension


SSRS is designed for extensibility. In the previous chapters, you learned how to extend SSRS’ reporting capabilities by writing a custom code that can be called from a report. Extensions, on another hand, are called by SSRS. Extensions are composed of four key categories: security, delivery, data processing, and rendering (see Chapter 3, “Reporting Services Architecture,” Figure 3.1).

Typical extensions installed with SSRS are as follows:

Data processing—Microsoft SQL Server, OLE DB (including OLEDBMD for Microsoft SQL Server Analysis Services), Oracle, ODBC, and XML. XML was one of the most frequent requests for data extensions in SSRS 2000. Many developers are happy to see XML data sources in SSRS 2005. Additional extensions that can be deployed in this category are SQL Server Integration Services (SSIS) and SAP data-processing extensions.

Delivery—File share, eMail, NULL.

Render—Excel, MHTML, HTML3.2, HTML4.0 (Microsoft Internet Explorer 5.0 or later), PDF, IMAGE (graphical image output, such as TIF, GIF, JPG), CSV, XML, NULL (used to place reports in cache and in conjunction with scheduled execution and delivery).

OtherSemanticQuery and ModelGeneration to extend Report Builder’s functionality. EventProcessing to act on the events generated by Report Server.

Security extensions are not typically installed. By default, SSRS uses Windows integrated authentication. A complete list of extensions installed on a particular instance of SSRS can be retrieved by calling ReportingService2005.ListExtensions(ExtensionTypeEnum.All) or by examining the rsreportserver.config file.

Rendering is, perhaps, the most developed category of extensions. With a wide range of rendering extensions and a multitude of applications (including Microsoft Office) that “understand” HTML, it is hard to think of a new rendering extension that would be immediately useful.

Some of the SSRS capabilities that customers are frequently looking for and that are currently not available “out of the box” are as follows:

Printer (fax) delivery—The ability to print (fax) batches of reports without human interactions

.NET data set access—An ability to access a data set that was created inside of an application

Custom authentication—An ability to authenticate non-Windows clients

It is possible to work around the need to have certain functionality. For example, instead of delivery to a printer directly from SSRS, an administrator can configure delivery of a report to a file share and have a separate process monitoring and printing from such a file share by using the Windows PRINT command, such as PRINT /D:\<server URL><printer name> <files to print>.

It is also possible to work around the scenario in which users cannot use Windows authentication. An administrator can create a Windows account for a user, configure IIS to accept Basic authentication (must enable SSL for better security), and ask the user to enter Windows credentials to access a report.

Although it is possible to work around some of the limitations, custom extensions can offer elegant solutions to supplement missing functionality.

A custom extension is a private or shared .NET assembly with a unique namespace (the exact name is not important, but it must be unique), and a class that implements the IExtension interface and one or more interfaces shown in Table 26.1. As with any .NET implementation, Visual Studio is the most frequently used development tool for development of assemblies and, therefore, extensions.

Table 26.1. Typical Set of Interfaces Used in Custom Extensions

image

image

Common Considerations for Custom Reporting Services Extensions: Implementation, Deployment, and Security

The reporting library provides three namespaces that supply interface definitions, classes, and value types that allow extensions to interact with SSRS:

Microsoft.ReportingServices.DataProcessing—Used to extend the dataprocessing capability of SSRS.

Microsoft.ReportingServices.Interfaces—Used to build delivery and security extensions.

This namespace also allows you to maintain a cross-connection state. A class that implements the IExtension interface from this namespace is kept in memory for as long as SSRS is running.

Microsoft.ReportingServices.ReportRendering—Used to extend the rendering capabilities of SSRS. This namespace is used in conjunction with the Microsoft.ReportingServices.Interfaces namespace.

Before you can successfully compile an extension, you must supply the reference to one or more Microsoft.ReportingServices namespaces as follows:


using Microsoft.ReportingServices.Interfaces;

A namespace can have optional interfaces, such as IDbConnectionExtension in Microsoft.ReportingServices.DataProcessing, and required interfaces, such as IDbConnection in the same extension’s namespace. When an interface is required and a developer chooses not to implement a particular property or method of the interface, it is a best practice to throw a NotSupportedException. NotSupportedException is most appropriate for this purpose as it indicates methods (and properties) that did not provide implementation for methods described in the base classes (interfaces). The next best alternative is NotImplementedException. Note that optional interfaces do not require implementation at all.

Any Common Language Runtime (CLR) application interacts with the CLR security system. This book briefly covered the basics of .NET security in Chapter 23, “How to Create and Call a Custom Assembly from a Report,” specifically in the section “.NET Security Primer for a SSRS Administrator.” The same principles apply to extensions. Local security settings and SSRS configuration files define the code permissions that an extension’s assembly receives. SSRS extensions must be a part of a code group that has the FullTrust permission set.

To deploy an assembly, a SSRS administrator must have appropriate permissions to write to the Report Server directory, Report Designer directory, and configuration files.

When a Report Server first loads an extension in memory, the Report Server accesses an assembly using service account credentials. Service account credentials are needed so an extension can read configuration files, access system resources, and load dependent assemblies (if needed). After an initial load, the Report Server runs an assembly using credentials of the user who is currently logged in.

An extension can be deployed for use by the Report Server, Report Manager, Report Designer, or all of the above. This is provided that the extension can be used by a tool. For example, Report Manager only uses delivery extensions.

The deployment procedure for an extension used by the Report Server, Report Manager, or Report Designer is basically the same, the only difference is the deployment directory and configuration files that need to be modified. To simplify further discussion, this book uses the following abbreviations:

{AssmDir}—To abbreviate assembly deployment directories. The default Report Server binary directory is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesReportServerin. The default Report Designer binary directory is C:Program FilesMicrosoft Visual Studio 8Common7IDEPrivateAssemblies. The default Report Manager binary directory is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesReportManagerin.

{ConfigFile}—To abbreviate configuration files (note the default file path). The default location for the Report Server configuration file is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesReportServerRSReportServer.config. The default location for the Report Designer configuration file is C:Program FilesMicrosoft Visual Studio 8Common7IDEPrivateAssembliesRSReportDesigner.config. The default location for the Report Manager configuration file is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesReportManagerRSWebApplication.config.

{SecConfig}—To abbreviate security configuration files. The default location for the Report Server security configuration file is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesReportServerRsSrvPolicy.config. The default location for the Report Designer security configuration file is C:Program FilesMicrosoft Visual Studio 8Common7IDEPrivateAssembliesRSPreviewPolicy.config. The default location for the Report Manager security configuration is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesReportServerRsMgrPolicy.config.

To deploy an extension, a report administrator can use the following steps:

1. Copy an extension assembly to the {AssmDir} directory. Remember to substitute {AssmDir} with any of the three directories this shortcut abbreviation. If an assembly with the same name exists in the {AssmDir} directory, stop the Report Server service, copy an assembly, and then restart the Report Server service.

2. Locate an entry in the {ConfigFile} under the <Extensions> tag tag ({ConfigFile} directories)> tag> that corresponds to a category ({ExtCategory}) of an extension: <Delivery>, <Data>, <Render>, <Security> (Authorization), <Authentication>, or <DeliveryUI>.

3. Add an entry for a newly created extension to a {ConfigFile}.


  <Extensions>
     ...
     <(ExtCategory}>
        <Extension
            Name="{Unique extension name up to 255 characters}"
            Type="{Fully qualified name of the class implementing   IExtension},
                  {AssemblyName without .dll}"
            Visible="{false|true; false indicates that extension is not   visible in UI}"
         >
         {optional configuration data}
         </Extension>
      </(ExtCategory}>
      ...
   </Extensions>

An example of CustomFileShareProvider for rsreportserver.config is as follows:


<Extensions>
   <Delivery>
       <Extension
         Name="Report Server Custom FileShare"
         Type="MyCorp.FileShareDeliveryProvider.CustomFileShareProviderClass,
         CustomFileShareProviderAssembly"
       >
       <MaxRetries>3</MaxRetries>
       <SecondsBeforeRetry>900</SecondsBeforeRetry>
       <Configuration>
          <StoreResultsAt>
            <FileShare>\myserver1 esult</FileShare>
            <FileShare>\myserver2 esult</FileShare>
          </StoreResultsAt>
       </Configuration>
     </Extension>
     ...

When an extension that implements the IExtension interface is invoked, SSRS calls two methods of the IExtension interface: SetConfiguration and LocalizedName. SSRS passes an XML fragment between <Configuration> and </Configuration> tags in the configuration file as a parameter to SetConfiguration, so the extension can take advantage of the flexibility that configuration offers. The LocalizedName property targets user interface implementations (such as Report Manager) and should return values for various languages. This way, an extension can be used around the world and does not have to be recompiled every time the extension is deployed in a new locale.

4. Finally, an administrator can grant FullTrust permission for an assembly by modifying the {SecConfig} file:


<CodeGroup class="UnionCodeGroup"
   version="1"
   PermissionSetName="FullTrust"
   Name="MyExtensionCodeGroup"
   >
      <IMembershipCondition class="UrlMembershipCondition"
        version="1"
       Url="C:Program FilesMicrosoft SQL ServerMSSQLReporting
ServicesReportServerinMyExtensionAssembly.dll"
      />
</CodeGroup>

5. An administrator can verify deployment of an extension by using the ListExtensions method.


Note

Additional details about security are covered in Chapter 23, specifically in the section “.NET Security Primer for a SSRS Administrator.”


To debug a deployed extension, complete the following steps:

1. Determine the processes that access the extension. For example, for a delivery extension that is accessed by Report Manager (because Report Manager runs in the content of IIS), the process is aspnet_wp.exe or w3wp.exe. Similarly, the subscription notification event is handled by SSRS, and SSRS (the process is ReportingServicesService.exe) invokes a delivery extension to execute a delivery. A data-processing extension can be accessed by Report Manager and from within an instance of Visual Studio (the process is devenv.exe).

2. Set breakpoints in the extension’s code.

3. Attach Visual Studio to the calling process using, for example, the Debug, Attach to Process menu. The Attach to Process dialog box opens. You need to make sure that Show Processes from All Users check box is selected, after which you can select a process to attach to, and click Attach.

4. As the extension is invoked, Visual Studio breaks at set breakpoints, and you can step through the code.

Delivery Extension

The delivery extension sample is one of the three samples supplied by Microsoft and is installed by default in the directory C:Program FilesMicrosoft SQL Server90SamplesReporting ServicesExtension SamplesPrinterDelivery Sample.

Most of the delivery extensions require the Report Server Windows service to run under domain account credentials. Both email and printer delivery extensions, for example, require this condition to be satisfied. The first indicator that this condition is not satisfied is SSRS returning an error message: “The Report Server has encountered a configuration error.

This error message is displayed in a Status column of Report Manager. More details of the error message are recorded to the SSRS log file (the default location is C:Program FilesMicrosoft SQL ServerMSSQL.3Reporting ServicesLogFiles):


ReportingServicesService!library!4!11/01/2005-17:21:40:: e ERROR:
Throwing Microsoft.ReportingServices.Diagnostics.Utilities.
ServerConfigurationErrorException: The report server has encountered  a configuration error. See the report server log files for more information., AuthzInitializeContextFromSid: Win32 error: 1355;  Info: Microsoft.ReportingServices.Diagnostics.Utilities.
ServerConfigurationErrorException: The report server has encountered  a configuration error. See the report server log files for more information.


Tip

Error messages containing AuthzInitializeContextFromSid usually refer to incorrect configurations in access security to domain-level resources. One of the most frequent causes of this error is when the SSRS service is not configured to run under a domain account.


A delivery extension spends part of its “life” responding to subscription-related requests from SSRS and part responding to delivery-related requests from SSRS.

In addition to the IExtension interface, a delivery extension should also implement the IDeliveryExtension interface; see Table 26.2.

Table 26.2. Members of the IDeliveryExtension Interface

image

Interactions Between User, SSRS, and a Delivery Extension

Figure 26.1 provides a partial class diagram for the printer delivery extension.

Figure 26.1. Partial class diagram for the printer delivery extension.

image

The user interacts with SSRS to create a subscription. The interaction could be done from a custom application using a SOAP API call to the SSRS web service’s method CreateSubscription(). The interaction can also be performed through Report Manager, which performs the following:

• Interacts with ISubscriptionBaseUIUserControl implementation inside of a delivery extension to present a UI for data entry

Collects data and passes data as CreateSubscription() parameters

• Interacts with SSRS to create a subscription, as presented in Figure 26.2

Figure 26.2. An application’s interaction with SSRS to create a subscription.

image

Along with other parameters, CreateSubscription() accepts the full pathname of the report and the ExtensionSettings object, which, in turn, contain ParameterValue objects. ParameterValue objects contain name-value pairs with information that a delivery extension expects. For example, for email delivery, one of the parameter values is “TO:” information:


extensionParams(0) = New ParameterValue()
extensionParams(0).Name = "TO"
extensionParams(0).Value = "[email protected]"

SSRS then fills settings with information from ParameterValue and passes settings to a delivery extension for the validation (ValidateUserData() call). After being validated, SSRS stores settings with the subscription and returns a SubscriptionID string to a user.

When the time to “fire” a subscription comes, the SSRS scheduling engine sends a notification event to the Scheduling and Delivery Processor. See Figure 26.3 for the subscription delivery process.

Figure 26.3. An application’s interaction with SSRS to deliver a subscription to a printer.

image

The Schedule and Delivery Processor receives a notification event, matches it to the subscription, creates a Notification object, and calls the Deliver method in a delivery extension, passing Notification as a parameter of the call.

The delivery extension leverages SSRS’s rendering extensions, using the Notification.Report.Render method. The Notification.Report.Render method returns the RenderOutputFile object. The RenderOutputFile.Data property contains a stream with a rendered report.

The delivery extension then “decides” what to do with the stream. In the case of the printer delivery extension, the stream is converted to a metafile and printed using functionality from the System.Drawing.Printing namespace.

Summary

SSRS supplies an infrastructure (interfaces, classes, value types, and customizable configurations) to allow developers to extend SSRS’ capabilities. Developers can write extensions to extend security, delivery, data processing, and rendering functionality of SSRS.

Although extensions require more in-depth understanding of SSRS’ inner workings and supporting infrastructure, the need to provide custom functionality sometimes takes a developer to the realm of extensions. The experience to see an extension coming to “life” is certainly very rewarding.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset