This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Praise from the Experts “While building SAS/IntrNet applications, I would like nothing better than to have someone with the skills of Don Henderson looking over my shoulder. Other than some SAS-L posts and a few personal e-mail messages, this desire went unrealized. That was until I read Don’s book, Building ® Web Applications with SAS/IntrNet : A Guide to the Application Dispatcher. “This book picks up where SAS documentation leaves off. It shows how to increase the functionality of the SAS/IntrNet Application Dispatcher to solve problems commonly encountered when building Web-based SAS applications. This book also supplies a host of ‘best practices’ that can help keep one from creating future difficulties. “An example of the gems that Don has unearthed is the INVSESS option. This option allows developers to implement friendlier responses to failed attempts to reconnect to a session. Along with techniques to refresh long-running requests, this book shows how to partially overcome the problem of user sessions that time-out from user inattention. “One of the most helpful chapters is Chapter 11, “Tools and Techniques for Debugging.” One especially useful tip is to seed programs under development with %testPrint macros to conditionally print intermediate results. This chapter also provides good guidance on how to run Application Dispatcher programs in a stand-alone mode. “In my opinion, this is a must-have book if one is responsible for creating or maintaining Webbased SAS applications.”
Michael Davis
“At long last we have a comprehensive book on the intricacies of SAS/IntrNet programming! Don Henderson has written the definitive, authoritative book on how to develop SAS/IntrNet applications so that you can easily host your SAS programs on the Web. There is so much information packed into this book that you will find something that you did not know in every chapter. Though I have been working with SAS/IntrNet for many years, I was amazed at the volume of information that I was not aware of. “There are several chapters of this book that will allow you to recoup the book’s purchase price, almost immediately. Chapter 7, “Various Techniques to Generate HTML,” is a case in point. It takes you through increasingly advanced material, moving from using simple PUT/FILE statements, to extending the Output Delivery System to the Web, to using SCL submit blocks, to including HTML from external sources, to using SAS Server pages, and finally to using designtime controls. All of these techniques have great merit; and this chapter explains how and when to use them while providing great examples. This chapter will save you hours of research and development time. “Another chapter that would have saved my staff at least a week’s worth of work is Chapter 19, “Handling On-Demand Long-Running Requests.” Many organizations face the unenviable prospect of having to offer Web-based reports or analysis against large, complicated data sources that end up as long-running SAS jobs. In doing so, one cannot expect Web users to sit idly by, wondering when their output will arrive as the minutes tick by. This chapter provides two specific
techniques for spawning asynchronous SAS batch jobs, behind the scenes, to produce result sets. The first technique launches the batch job, and then e-mails the result set to the user when the batch job completes. The second technique provides the user with a status page in their browser that is continuously updated as each batch job step completes, and then overlays the status page with the final output when it becomes available. Both techniques are clearly described and include easy-to-follow examples. “Singling out specific chapters for comment is hard, because all of the chapters in this book have significant tips, insights, and well-explained examples. It is obvious to me that there will not be another book published about SAS/IntrNet software, because Don has covered everything there is to say about the topic in this one great publication. But, then again, one would expect no less from one of the original creators of SAS/IntrNet software!”
Michael A. Raithel Westat
“The Paris Herald Tribune once published a satirical column by Art Buchwald describing a mythical American tourist who visited Paris and ran a ‘four-minute Louvre.’ The tourist touched all the must-see bases—the Venus de Milo, the Mona Lisa, and the Winged Victory of Samothrace—making excellent time Buchwald wrote, ‘under perfect conditions, with a smooth floor, excellent lighting, and no wind.’ “Superficial involvement with substance is something one can poke fun at, but it has no place in serious matters. There is no way one could race through Don Henderson’s new book about how to use the Application Dispatcher in SAS/IntrNet. This is material that demands close, patient, and studious attention. “This book reveals two characteristics of the author himself. First, he is a person who willingly gives away his own know-how, sharing highly valuable insights with anyone who cares to listen. Second, he is someone who is able to master advanced coding techniques easily and apply that mastery to solving complex coding problems. Any programmer who works with SAS/IntrNet will feel a sense of indebtedness to Don for making life easier. “This book, which could have been subtitled Making the Most of SAS/IntrNet, makes it easy to realize that the software has tremendous depth and is up to the job of dealing with practical coding requirements. This shouldn’t astonish us. After all, SAS software in general has continued to evolve and take on enhanced capabilities. Thus, to understand the Application Dispatcher, one must make the same kind of effort that is involved in learning ODS or SAS/GRAPH, for example. Don challenges the reader to do just that. There is no fluff here, only solid meat. Each paragraph, each example, contains important information that a reader must digest slowly and carefully. “This text is so educational that it really ought to become material for a new course offered by SAS. Each chapter contains examples that could be converted easily into exercises. In any form, Don’s masterful work will help SAS programmers to become better and stronger.”
Jim Sattler, President Satmari Software Systems, Inc.
Building Web Applications with SAS/IntrNet
®
A Guide to the Application Dispatcher
Don Henderson
The correct bibliographic citation for this manual is as follows: Henderson, Don. 2007. Building Web Applications with SAS/IntrNet®: A Guide to the Application Dispatcher. Cary, NC: SAS Institute Inc.
Chapter 1 Overview of SAS/IntrNet and Related Technologies 3 1.1
Is the Application Dispatcher a Good Fit? 4
1.2
Components of SAS/IntrNet Software 5 1.2.1 The Application Dispatcher 5 1.2.2 SAS Design-Time Controls 5 1.2.3 Xplore Sample Web Application 6 1.2.4 htmSQL 6 1.2.5 SAS/CONNECT Driver for Java 6 1.2.6 SAS/SHARE Driver for JDBC 6 1.2.7 Tunnel Feature 7
1.3
Other SAS Web Components and Technologies 7 1.3.1 The Output Delivery System 7 1.3.2 The Web Publishing Tools and Related Macro Tools 8 1.3.3 SAS AppDev Studio, a SAS Applications Development Environment 9 ®
1.3.4 SAS 9 Business Intelligence Platform 9 1.4
Industry Components 12 1.4.1 Scripting Languages 12 1.4.2 Dynamic HTML 15 1.4.3 Web Services 16
1.5
Component-Based Architectures 16
1.6
Terminology 18
iv Contents
Part 2
How the SAS/IntrNet Application Dispatcher Works
Chapter 2 Overview of the Application Dispatcher Process Flow 23 2.1
Introduction 23
2.2
Application Broker—Application Server Process Flow 24
2.3
Process Flow Including the Load Manager 25
2.4
Performance Benefits of Using the Load Manager 27
Chapter 3
The Application Broker and the Load Manager 31
3.1
Introduction 31
3.2
Specifying Additional HTML Output 33
3.3
Defining the Load Manager 34 3.3.1 The Load Manager Command 34
3.4
Defining the SAS Application Servers 35 3.4.1 Socket Servers 35 3.4.2 Pool Servers 37 3.4.3 Launch Servers 39
Application Server Sessions 50 4.3.1 ODS and Sessions 50
4.4
PROC APPSRV 51 4.4.1 TCP/IP Port 51 4.4.2 Assigning Libraries 51 4.4.3 Initiating and Terminating Requests 54
4.5
Application Server Process Flow 55 4.5.1 Application Server Functions Available to the Executing Program 60 4.5.2 Application Server Clean-Up Processing 60
Contents
Chapter 5
v
Communicating with the Application Dispatcher 63
5.1
Introduction 63
5.2
Name/Value Pairs Defined by the User’s Request 64 5.2.1 _program: The SAS Program to Execute 64 5.2.2 _service: The Application Server to Process the Request 65 5.2.3 _debug: The Output to Display 65 5.2.4 Program-Specific HTML Name/Value Pairs 68
5.3
Name/Value Pairs Defined by the Application Broker 72 5.3.1 Application Broker Administrative Fields 72 5.3.2 Environment Variables 73 5.3.3 Installation Dependent Fields 74
5.4
Name/Value Pairs Defined by the Application Server 76
Part 3
Developing Application Dispatcher Programs
Chapter 6
Methods You Can Use to Access and Reference Input Parameters 81
6.1
Introduction 81
6.2
Accessing Parameters as Macro Variables 82 6.2.1 Using and Referencing the Multiple Values for a Single Parameter (the Suffix Variables) 85 6.2.2 Using the APPSRV_UNSAFE Function 87
6.3
Chapter 7 7.1
Accessing Parameters in SCL Programs 91
Various Techniques to Generate HTML
94
Introduction 94 7.1.1 The Problem with Generating Valid HTML 95
7.2
Simple PUT and FILE Statements 96 7.2.1 The generateFormTag and generateInputTag Sample Macros 101
7.3
Extending the Output Delivery System 102 7.3.1 FORM Tags Via TITLE and FOOTNOTE Statements 102 7.3.2 Character Variables with HTML Form Text 105
7.4
SCL Submit Blocks 107
7.5
Including Static HTML from External Sources 110 7.5.1 A Macro Tool to Include External HTML 114
vi Contents
7.6
SAS Server Pages 116 7.6.1 The SAS Server Page Macro 116 7.6.2 Sample Server Page: List Libraries 118 7.6.3 A Macro to Generate Data-Driven SELECT Tags 119 7.6.4 Sample Server Page: List the Data Sets in the Selected Library 121 7.6.5 Sample Server Page: List the Variables in the Selected Data Set 122 7.6.6 A Macro to Generate Checkboxes for Variables in a SAS Data Set 124 7.6.7 A Program to Page Through the Selected Data Set 125
7.7
Chapter 8
SAS Design-Time Controls 127
Creating Pages with Mixed and Alternative Content Types 131
8.1
Introduction 131
8.2
Defining the Content Type to Be Generated 132 8.2.1 Other Headers: Selected Examples 132
8.3
Generating Pages with Other Content Types 135 8.3.1 Creating a Comma-Separated Values File 136 8.3.2 Downloading Reports and Results into Microsoft Excel 137 8.3.3 Generating Content for Printing 138 8.3.4 Generating Multiple Output Types at Once 143
8.4
Generating Pages with Mixed Content Types: Text and Graphics 146 8.4.1 Ensuring That the Graph Is Current 153
Chapter 9
Using REQUEST INIT and REQUEST TERM to Specify Set-up and Shut-down Behavior 155
9.1
Introduction 155
9.2
Specifying the REQUEST INIT and REQUEST TERM Programs 156
9.3
Using REQUEST INIT and REQUEST TERM 156 9.3.1 Defining Libraries and Files 157 9.3.2 Overriding or Supplying Parameter Values 159 9.3.3 Standard Header and Trailer Blocks 161 9.3.4 Terminating a Request 163
Contents
Chapter 10 How to Create and Use Sessions
165
10.1 Introduction 165 10.2 Creating a Session 166 10.3 Saving or Restoring All Macro Variables 171 10.4 Returning to a Previous State of a Session 175 10.5 Generating Friendlier Messages for Expired Sessions 179 10.6 Extending Sessions 182 10.7 Session INIT and TERM Programs 186
Part 4
Addressing Common Application Requirements
Chapter 11 Tools and Techniques for Debugging
191
11.1 Introduction 191 11.2 Using the _debug Parameter 192 11.3 The PROC APPSRV LOG Statement 196 11.4 Conditionally Generating Debugging Output 197 11.5 Running Application Dispatcher Programs Using SAS Display Manager 200 11.5.1 Special Handling for SCL Programs 201 11.6 Dedicating an Application Server for Debugging 202
Chapter 12 Tips for Safeguarding Security
205
12.1 Introduction 205 12.2 The Application Server Environment 206 12.2.1 Limiting Which Application Brokers Can Access an Application Server 206 12.2.2 Hiding Passwords 208 12.2.3 Best Practices for a Secure Application Server Environment 211 12.3 Controlling Access to Data and Reports 212 12.3.1 Customizing Menu Choices 219 12.3.2 Using AUTH=HOST 223
vii
viii Contents
Chapter 13 Integrating Application Dispatcher Applications with Other Applications, Products, and Environments 225 13.1 Introduction 225 13.2 htmSQL 226 13.2.1 Integrating htmSQL with the Application Dispatcher 228 13.2.2 Integrating the Application Dispatcher with htmSQL 230 13.3 Single Sign-On Environments 235 13.4 External Session Facilities 236
Chapter 14 Maintaining an Applications Environment 239 14.1 Introduction 239 14.2 Supporting Development, Test, and Production Environments and Applications 239 14.2.1 Using a Developer’s Workstation 240 14.2.2 Distinct Services 240 14.2.3 Distinct Brokers 241 14.2.4 Customized INIT Program 242 14.3 Metadata Approaches to Minimize Code Changes 244 14.3.1 The getTextString Macro 249
Part 5
Selected Examples
Chapter 15 Generating Static Versions of Dynamic Reports 253 15.1 Introduction 253 15.2 Sample Program 254 15.3 Ensuring That Generated Links Function Correctly 256 15.4 E-mailing Static Copies of Dynamic Reports 256
Chapter 16 Simulating a Pause and Resume Capability for the Application Server 259 16.1 Introduction 259 16.2 Sample Implementation 260 16.2.1 The Metadata Control Table 262 16.2.2 The Toggle Program 263 16.2.3 Macro to Check Status 264 16.2.4 The HTML Templates 265 16.3 Doing More with the Sample 266
Contents
ix
Chapter 17 Techniques for Handling Long-Running Processes 267 17.1 Introduction 267 17.2 Using the Cascading Style Sheets Display Attribute 268 17.3 Using the JavaScript location.replace Function 271
Chapter 18 Using Scheduled Execution to Handle Long-Running Processes 275 18.1 Introduction 275 18.2 Sample Implementation 276 18.3 Doing More with Scheduled Execution 279
Chapter 19 Handling On-Demand Long-Running Requests 281 19.1 Introduction 281 19.2 E-mailing Results from an On-Demand Long-Running Process 282 19.1.1 Notifying the User 284 19.2 Updating Process Status by Refreshing the User’s Browser 285 19.2.1 Notifying the User 287 19.3 The Sample Framework—Spawning a Separate SAS Session 290 19.3.1 Sample Program to Submit a Long-Running Program— spawnSAS.source 295 19.3.2 Sample spawnSAS Macro 298 19.3.3 Sample Long-Running Program 300 19.4 Doing More with Independent Sessions 305
Chapter 20 Using Metadata-Driven Reporting to Construct Reports 307 20.1 Introduction 307 20.2 Sample Implementation 309 20.2.1 The Logon Template 311 20.2.2 The Logon Program 312 20.2.3 Selecting the Case or Individual to Examine 315 20.2.4 Report Components 319 20.2.5 The assembleReport Macro 323
x Contents
Chapter 21 Packaging the Application Dispatcher as a Web Service 327 21.1 Introduction 327 21.2 Solution Architecture 329 21.3 Sample Application 330 21.3.1 The Sample .NET Client Application 331 21.3.2 The .NET Web Service 332 21.4 Using the Sample Client Application 335 21.5 Final Thoughts 338
Index
339
Preface The rush to take mission-critical applications to the Web has changed the way companies compete and interact. This competition has produced a lower cost-per-desktop and has extended information access to just about anyone, whether through a Web browser, a personalized portal, or a handheld device. Therefore, it is essential that organizations use the tools at their disposal to their best advantage. This book focuses on the Application Dispatcher, which is one of the components of SAS/IntrNet software. SAS/IntrNet, and specifically the Application Dispatcher, is a mature and proven technology for the deployment of Web solutions. However, as with most products, it has many features and capabilities that are not fully known or exploited by users. This book discusses many such features, thus enabling you to take better advantage of the software’s facilities and tools. In the move to the Web, it is also important to note that applications to be deployed there must recognize the underlying distributed nature of Web-based applications. The native Web environment is a two-tier architecture: the Web server/Web browser tier and the data/compute services tier. This separation means that many architectural assumptions made in the development of applications are incompatible with the Web. The resulting issues can include the following:
Many Web applications are stateless (i.e., each request for compute or data services is completely independent of the other). Thus, applications that assume exclusive access to data are problematic (e.g., in the transaction-based world of the Web, the concept of opening a data set for exclusive update access is not the same as in a desktop world).
The event model in a Web application is very different from the event model in a desktop application. For example, if the client is a browser, the back-end compute engine has no access to key clicks until the browser has forwarded a request for processing to the compute server.
A corollary to the previous point is that even if some of the logic relating to the event model can be surfaced in the client (e.g., using Java, JavaScript, Dynamic HTML, etc.), the separation of the client and the server can be a complicating factor in moving existing applications to a Web environment.
While we will not explore these issues in great detail, many of the ideas and techniques presented here will enable you to better address these requirements while building Web-based applications using the Application Dispatcher.
Organization of This Book This book contains five parts:
Part 1 provides an overview of SAS/IntrNet and the role the Application Dispatcher can play in building Web applications.
Part 2 provides details about how the components of the Application Dispatcher work and interact with one another.
Part 3 discusses techniques and examples illustrating the features and capabilities of the SAS/IntrNet Application Dispatcher. A variety of tools and best practices are provided to
xii Preface
facilitate developing applications for the Application Dispatcher. Many of these ® techniques apply to the SAS 9 Stored Process Server as well.
Part 4 shows how the techniques and features of the Application Dispatcher presented in Parts 1 through 3 can be used to address common application requirements. It contains a number of short chapters that focus on how to use the ideas discussed earlier, with a few new techniques and methods included.
Part 5 provides a number of examples that use the techniques, samples, and approaches described in previous chapters and illustrates how they can be integrated to address commonly encountered requirements. Each example describes a scenario or requirement along with a suggested approach to implementing it using the SAS/IntrNet Application Dispatcher.
Sample Environment Almost all of the examples discussed in this book are available in a sample environment that is a companion to the book. You can access it from the following URL: http://hcsbi.com/IntrNetAppDev/
The sample environment allows you to run demonstrations and most examples. Some examples are not available for security reasons. The demonstrations and examples are organized by chapter (i.e., you access the examples for Chapter X by clicking the link for Chapter X). The location of each example appears in the text that describes that example. Example text is easily identified by a Run icon in the left margin, as shown here. The Web site also contains instructions and links to download and install the sample environment on your local PC. By downloading and installing the sample environment locally you will be able to do the following:
run selected examples that are disabled on the Web site
easily modify and experiment with the examples
add your own data to the sample environment
start using the samples and tools in your own SAS/IntrNet Application Dispatcher applications
You can start out by accessing the examples from the Web site. Later, download and install the sample environment. Thus, you can begin (and perhaps complete) reviewing the book without having to install anything locally. Be sure to check the sample environment frequently for updates.
Acknowledgments Among the people I’d like to thank are the technical reviewers: Robert Allison, Vincent DelGobbo, Paul Grant, Dana Rafiee, Michael Raithel, Warren Repole, David Shinn, Heather Weinstein, and Bryan Wolfe. I’d also like to thank Alan Churchill of Savian and Scott Wood of Zencos Consulting. Alan wrote the Windows .NET sample applications discussed in Chapter 21 that illustrate packaging the Application Dispatcher as a Web service. Scott provided the sample Java code discussed in Section 13.4 that illustrates integration with external session facilities. Thanks, also, to the SAS Press team who produced the book: Caroline Brickley, Patrice Cherry, Jennifer Dilley, Shelly Goodin, Candy Farrell, Stephenie Joyner, Mary Beth Steinbach, and Liz Villani. I would like to thank those folks who provided feedback (and continue to provide feedback) on the sample environment (http://hcsbi.com/IntrNetAppDev). And finally, I would like to thank my wife, Celia Henderson, for reviewing parts of the book even though she knows very little about SAS as well as for her patience when I would disappear for hours and days at a time using the excuse I need to work on my book.
xiv
1
P a r t
An Introduction to SAS/IntrNet Software Chapter
1
Overview of SAS/IntrNet and Related Technologies 3
SAS/IntrNet software opens SAS to the Internet, extranet, or intranet. Specifically, this software enables users to run ad-hoc reports and dynamic applications via the Web. Broadly speaking, SAS/IntrNet is divided into three areas:
data services that enable the user to make SQL-type queries to the SAS server. Users can query, update, and report data.
compute services that give the user full access to the analytical capabilities of the SAS server. Users can access and use any non-visual functionality provided by the SAS server.
out-of-the-box applications that use the SAS/IntrNet data and compute services to deliver access to OLAP cubes created with PROC MDDB (the MDDB Report Viewer) and to explore and report the contents of SAS catalogs and libraries (the Xplore Sample Application).
2 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Organizations often use a diverse collection of technologies to store, manage, and report on information. Therefore, organizations should consider factors such as the following when choosing a technology for developing a Web-based information delivery system:
user interface requirements
data access and analysis requirements
application performance
costs of development, deployment, and maintenance
The Application Dispatcher component of SAS/IntrNet software has many facilities that can make the applications development task easier. This book explains many of those facilities including some that are not known to the broad population of users. Chapter 1 gives a high-level overview of the Application Dispatcher component of SAS/IntrNet software and places the software in context with related Web technologies.
C h a p t e r
1
Overview of SAS/IntrNet and Related Technologies 1.1 Is the Application Dispatcher a Good Fit? 4 1.2 Components of SAS/IntrNet Software 5 1.2.1 The Application Dispatcher 5 1.2.2 SAS Design-Time Controls 5 1.2.3 Xplore Sample Web Application 6 1.2.4 htmSQL 6 1.2.5 SAS/CONNECT Driver for Java 6 1.2.6 SAS/SHARE Driver for JDBC 6 1.2.7 Tunnel Feature 7 1.3 Other SAS Web Components and Technologies 7 1.3.1 The Output Delivery System 7 1.3.2 The Web Publishing Tools and Related Macro Tools 8 1.3.3 SAS AppDev Studio, a SAS Applications Development Environment 9 ®
1.3.4 SAS 9 Business Intelligence Platform 9 1.4 Industry Components 12 1.4.1 Scripting Languages 12 1.4.2 Dynamic HTML 15 1.4.3 Web Services 16 1.5 Component-Based Architectures 16 1.6 Terminology 18
4 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
1.1 Is the Application Dispatcher a Good Fit? One of the primary design goals for the SAS/IntrNet Application Dispatcher was to mask the complexity of other technologies, such as CGI and HTML, which are needed to implement SAS Web technologies. The Application Dispatcher enables organizations to deploy a Web application without requiring the development staff to have extensive knowledge of CGI or HTML. The advent of ODS makes this even easier. Of course, some knowledge of these technologies is advantageous in implementing a Web solution. However, the application and the data usage factors should be the driving force behind determining which technologies to use. There are many different factors and criteria that should be considered when deciding which components are most appropriate for a given set of development needs. In addition to the requirements and the skills available for the current application, other Web-based applications and skills available within the organization should be considered. Applications that meet the following criteria are likely to be good candidates for the Application Dispatcher:
Existing SAS programs produce output and reports that should be made available to some or all users in an organization over the Web.
The application is an extension of existing SAS applications.
The reports are generated from dynamic data. Note that if data is reasonably static (e.g., only change monthly), then Web publishing the data via ODS might suffice to meet the application needs.
Users need the ability to customize the reports (e.g., select specific subsets) to get the output they need.
The development staff has a broad range of SAS programming skills. If there is only limited knowledge of or experience with CGI, HTML, Java, etc., then the Application Dispatcher with ODS would be a good choice.
SAS programming expertise is available and the timeframe to deploy is a critical factor (i.e., time to train the staff in new technologies is not available).
The application will be run on-demand to deliver specific reports.
The data is maintained centrally (e.g., in a data mart or data warehouse). Data which is inherently local or specific to a particular user is typically not a good candidate for application or report distribution.
The data files are potentially large and the reporting process reduces the size of the data (i.e., downloading a final customized report as HTML, PDF, or RTF is much faster than downloading the data for the user to process locally).
The data already exists (or is accessible) as SAS data sets.
There is a need to reduce paper reports by allowing users to access customized reports that meet their specific requirements.
Chapter 1: Overview of SAS/IntrNet and Related Technologies 5
1.2 Components of SAS/IntrNet Software SAS/IntrNet contains a variety of components that can be used individually or in combination to address specific needs of a Web-enabled information delivery solution. If multiple components are used, each component provides services that best meet the requirements. The power of SAS/IntrNet lies in the remarkable range of its components. They are discussed in the following subsections. For more information about terminology, refer to Section 1.6.
1.2.1 The Application Dispatcher The Application Dispatcher has two required components: the Application Server and the Application Broker. It provides both compute (i.e., running a SAS program) and data services (i.e., running a SAS program that does a SQL query using PROC SQL). It also includes out-ofthe-box applications (e.g., Xplore). The Application Server and the Application Broker are discussed in detail in Chapters 3 and 4. The Application Dispatcher provides a CGI gateway (namely, the Application Broker) between a Web browser and SAS. This gateway lets programmers build dynamic applications that can access the power of SAS (the Application Server) from a Web browser. The gateway also provides the capability to run any SAS program that can be executed in batch mode. The programmers need to work only with the details of what results (e.g., reports) the SAS program is to generate. All of the details relating to CGI (e.g., communicating the parameter values from the HTML page and returning the results to the user’s Web browser) are handled by the Application Broker and require no knowledge of CGI development or programming. The Application Broker passes all incoming requests to the Application Server, which can execute almost any batch SAS program. The Application Dispatcher allows the deployment of SAS programs to multiple users (whether or not they have SAS installed on their machines). The SAS/IntrNet Application Dispatcher also includes an optional Load Manager that can be used to intelligently route and handle a large volume of incoming requests. Based on its configuration, the Load Manager can start and stop remote Application Servers based on demand, and route requests across multiple back-end application servers, regardless of the operating environment. The Application Broker, Load Manager, and Application Server are described in more detail in Chapters 3 and 4.
1.2.2 SAS Design-Time Controls SAS Design-Time Controls (DTCs) make it easy to create SAS/IntrNet applications without prior knowledge of HTML or SAS programming. DTCs are add-in components for What You See Is What You Get (WYSIWYG) HTML editors that support the SAS Design-Time Controls standard defined by Microsoft, including Microsoft FrontPage, Macromedia Drumbeat 2000, SoftQuad HoTMetaL PRO 5, webAF, and more. DTCs are ActiveX controls that run inside the HTML editor and generate text based on the user’s input. In this way, a favorite visual HTML editor can be used to build SAS/IntrNet reports and applications via a point-and-click interface. With SAS DTCs, static reports can be created and published to a Web server. Dynamic reports can be created using JSP and ASP technologies, retrieving and displaying the latest information when a user selects the page from the Web browser. Both static and dynamic DTC reports can be
6 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
viewed by any browser (e.g., Internet Explorer, Netscape, Firefox, etc.). Using the DTCs does not require any prior experience with developing ASP or JSP pages.
1.2.3 Xplore Sample Web Application SAS/IntrNet includes a sample application called Xplore which exposes the SAS data environment to the Web. Using the Application Dispatcher, Xplore can dynamically access a variety of SAS data and file types for reporting, generating graphics, and performing drill-down analysis on the Web. The Xplore sample application is shipped with the SAS source and can provide a valuable resource of techniques and tools.
1.2.4 htmSQL htmSQL is a CGI gateway to SAS and provides data services that, in turn, provide access to SAS data from a Web browser, enabling the building of dynamic SQL queries. htmSQL consists of a CGI program that resides on the Web server and can be used to access and update a SAS data set (including Read access through views to an external DBMS). The developer provides an input file, e.g., a .hsql file (note that the extension does not have to be hsql), containing SQL statements embedded in HTML, and htmSQL submits the statements to a SAS data server (either SAS/SHARE or the SAS Scalable Performance Data Server). htmSQL retrieves and formats the results according to the HTML embedded in the .hsql file. htmSQL can be used to create sophisticated, dynamic applications that let users manipulate data to address their specific information requirements. htmSQL can also be used to generate any other type of markup language such as Extensible Markup Language (XML), Compact HTML (cHTML), Handheld Device Markup Language (HDML), and Wireless Markup Language (WML).
1.2.5 SAS/CONNECT Driver for Java The SAS/CONNECT driver for Java provides compute services. It is a set of Java classes that can be used to create Java applets, JSP, and Java applications that communicate with SAS software on a server, thus taking advantage of remote SAS computing resources. The driver provides functionality that is similar to what a SAS client can do with SAS/CONNECT, except that the functionality is available to any Java program and does not require SAS to be locally installed. Programs that use the SAS/CONNECT driver for Java can start a SAS session, connect to that session, create data sets, access existing SAS data, run SAS programs to analyze SAS data, and retrieve the results. The Java components in SAS AppDev Studio can be used to create applications that use the SAS/CONNECT driver for Java without requiring extensive knowledge of Java.
1.2.6 SAS/SHARE Driver for JDBC The SAS/SHARE driver for Java Database Connectivity (JDBC) provides data services and is a set of Java classes that can be used to create Java applets, JSP, and Java applications that communicate with a SAS data server (either SAS/SHARE or the SAS Scalable Performance Data Server) via SQL queries. The Java programs can let a user view and update data by submitting SQL queries and statements through a direct connection to the SAS server. The Java components in SAS AppDev Studio can be used to create applications that use the SAS/SHARE driver for JDBC without requiring extensive knowledge of Java.
Chapter 1: Overview of SAS/IntrNet and Related Technologies 7
1.2.7 Tunnel Feature The SAS/IntrNet tunnel feature employs HTTP tunneling to allow Java applets to communicate with remote systems via a CGI program running on the Web server. As a security measure, Java specifications dictate that an applet cannot make network connections to a machine other than the machine from which it was downloaded, unless Java 2 (or later) is being used and explicitly allows this. When deploying Java applets, this security measure might force the use of a server configuration that is less than ideal, because that server would have to be installed on the same machine as the Web server. In addition, many firewalls prohibit applets from communicating beyond the firewall, a restriction that can further reduce server configuration options. The tunnel feature addresses both of these configuration problems. The tunnel feature, with Java applets written using the Java components in SAS/IntrNet or the Java components in SAS AppDev Studio, can be used to eliminate the restriction on where the SAS server runs in relation to a Web server and firewall. JSP applications do not have any of these restrictions because they run as native operating environment applications and have access to all resources.
1.3 Other SAS Web Components and Technologies Other SAS resources provide facilities and tools that provide critical capabilities for any Web application that is based on SAS. Selected resources are briefly described in this section.
1.3.1 The Output Delivery System Starting with Version 7 of SAS, the Output Delivery System (ODS), which is part of Base SAS software, allows the direct creation of Internet content, including HTML files. In general, ODS is a method of delivering output in a variety of formats and of making the formatted output easy to access. Instead of taking the output from a procedure and creating HTML via post-processing, ODS creates the HTML during the initial creation of the procedure output. This method is more efficient and provides many new possibilities for report layout. Through the addition of a few simple lines of code, developers can convert a standard program into one that creates HTML output. It’s not necessary to know HTML or modify existing SAS code. In addition to HTML, ODS supports many other types of output formats, including Adobe Acrobat Portable Document Format (PDF), Rich Text Format (RTF) for use in Microsoft Word and other word processing programs, CSV for use by Microsoft Excel and other spreadsheet tools, XML, and WML for use with WAP-enabled hand-held devices. ODS also produces GIF-, JPEG-, ActiveX- and Java-based graphics in conjunction with SAS/GRAPH software. This capability lets developers create a wide variety of content that can be delivered over the Web with little or no extra effort. Consider the following example that uses ODS to produce the desired output and automatically passes the results back to the user’s browser: ODS HTML BODY=_webout; proc print data=sashelp.class; run; ODS HTML CLOSE;
ODS, which is the subject of a number of papers and SAS Press books, should be the default mechanism for producing the Internet content output required of most Web applications.
8 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
1.3.2 The Web Publishing Tools and Related Macro Tools For users running SAS Version 6 and later, the Web publishing tools are a collection of tools that generate Internet content output. While these tools continue to exist in SAS software, the tasks they perform are usually easier to accomplish with ODS. However, there are occasions where their use might be a better fit. Also note that these tools are not part of SAS/IntrNet and may be used in any SAS program. The Web publishing tools include the following:
The HTML formatting tools, included with Base SAS software, are a collection of macros that format SAS data sets and procedure output into HTML pages that can be shared with Web users:
The Output Formatter (%out2htm), which reformats output from any SAS procedure as an HTML file.
The Data Set Formatter (%ds2htm), which displays SAS data sets as HTML 3.x tables. The Data Set Formatter supports WHERE clauses, BY-group processing, and other data presentation capabilities.
The Tabulate Formatter (%tab2htm), which reformats the output from the TABULATE procedure into HTML 3.x tables.
Thin-client graphics are part of SAS/GRAPH software and are specialized, lightweight, visual Java applets or ActiveX controls which do not establish a persistent connection to a server. Instead, they receive all the information they need from applet parameters. The following tools generate the applet and ActiveX HTML calls along with the custom data values that are used as input to the visual component:
The GraphApplet HTML Generator (%ds2graf) produces graphs and charts from SAS data. It generates HTML that uses the GraphApplet or SAS/GRAPH Control for ActiveX to display and manipulate the graphics.
The MetaView HTML Generator (%meta2htm) produces an HTML file that includes metadata through which users can view SAS/GRAPH output in a Java applet. To view the output as graphics, you must use the MetaViewApplet.
The RangeView HTML Generator (%ds2csf) produces an HTML file that displays a critical success factor (CSF) from a SAS data set using the RangeViewApplet.
The TreeView HTML Generator (%ds2tree) produces an HTML file that displays a hierarchical tree from a SAS data set using the TreeViewApplet.
The Constellation Chart HTML Generator (ds2const) produces an HTML file that displays data from a SAS data set as a constellation chart using the ConstellationChartApplet.
Chapter 1: Overview of SAS/IntrNet and Related Technologies 9
The following are two other macro tools from SAS:
The DS2CSV macro takes as its input a SAS data set and creates a comma-separated value file. Optionally, the hexadecimal code for the separator character can be specified to create other types of output file (e.g., a tab-separated values file). Prior to SAS 9.1, the DS2CSV macro was shipped only with SAS/IntrNet for use with the Application Dispatcher. Beginning with SAS 9.1, the macro is available for use in any SAS program.
The FILESRV macro is used to serve a wide variety of external files and catalog entries, including those that are not defined to a Web server. The FILESRV program enables the files that are to be served to be controlled (including what HTTP and MIME headers are served with the file). This macro uses an authorization data set to determine which files can be served. The mechanism for making this decision is RX function pattern matching. This data set is used to set patterns (or masks) for the files that can be served. If a requested file does not match one of these patterns, then it is not served and an error message is issued.
1.3.3 SAS AppDev Studio, a SAS Applications Development Environment SAS AppDev Studio is a development suite that supports various ways to develop, deploy, and maintain information delivery applications. SAS AppDev Studio offers users the choice of building Java-based applications on the client or on the server, flexible CGI and HTML applications, ASP applications, or traditional full-client applications, with ease and efficiency, all from within one stand-alone development environment. In addition, this software provides access to the proven, extensive server capabilities of SAS for enterprise applications development. SAS AppDev Studio includes the two Java components webAF and webEIS. webAF is a complete Java Integrated Development Environment (IDE) tailored for the rapid creation of Java applications, applets, servlets, and JSPs that use the power of SAS. SAS AppDev Studio also includes for development purposes multiple SAS products, including SAS/IntrNet, that are required to develop Web-based applications.
1.3.4 SAS®9 Business Intelligence Platform ®
The SAS 9 Business Intelligence Platform is a framework for providing business intelligence services that use SAS Stored Processes. Like SAS/IntrNet Application Dispatcher programs, SAS Stored Processes are traditional SAS language programs that use SAS DATA steps, procedures, macros, and the SAS Component Language (SCL) to deliver powerful SAS capabilities to client applications across an enterprise. SAS Stored Processes are stored and managed from a central server and must be described by metadata, which includes information about where each process is stored, how it is executed, and what output it generates. However, SAS Stored Processes are slightly different from traditional SAS programs in that they are executed by a SAS Stored Process Server. SAS Stored Processes are conceptually similar to SAS/IntrNet Application Dispatcher programs. In fact, many Application Dispatcher programs can be executed as is, or with only slight modifications, by the SAS Stored Process Server. This is true because both use macro variables to communicate the user’s parameters to the program or process being executed, and both use the same reserved fileref, _WEBOUT, to stream the results back to the user’s browser. Many of the examples and techniques presented in this book for the Application Dispatcher can also be used with the SAS Stored Process Server.
10 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Because almost any valid batch SAS program can be converted to a stored process, the stored process capability delivers access to the full range of SAS analytics. Stored processes can be used to accomplish tasks such as these:
generate report content or analytic results for Web browsers, Microsoft Excel, Web services, and other clients.
generate report content or analytic results for SAS solutions and custom applications.
implement Data Warehouse Extract-Transform-Load (ETL) job flows and other data transformation procedures.
implement Web applications or functional components of Web applications.
create or update data on the SAS server.
run any batch SAS process.
Note, however, that there are currently differences between the two that will affect any decision to switch from the Application Dispatcher to the SAS Stored Process Server. Consider, for example, the following facts:
SAS Stored Processes can be invoked from a broader range of clients (e.g., the Web, Microsoft Office, and SAS Enterprise Guide).
Application Dispatcher programs can be external .sas files, catalog source entries, compiled SCL entries, and compiled macros. Stored processes may invoke any of these, but the process itself must be a .sas file.
Stored process results can be made available to users in a number of ways, including, but not limited to the following:
SAS Stored Process Web Application is a Java Web application that executes stored processes and returns results to a Web browser. For Web-based applications it performs services comparable to what the Application Broker component of the Application Dispatcher provides.
SAS Information Delivery Portal provides integrated Web access to SAS reports, stored processes, SAS Information Maps, and publish-and-subscribe channels. If the SAS Information Delivery Portal is installed, stored processes can be made available for execution from the portal without the need for additional programming.
SAS Add-In for Microsoft Office is a component object model (COM) add-in that extends Microsoft Office by enabling dynamic execution of stored processes with the output embedded in Microsoft Word documents and Microsoft Excel spreadsheets. Additionally, within Excel the SAS Add-In for Microsoft Office can be used to access and view SAS data sources or any data source that is available from a SAS server.
SAS Enterprise Guide is a client application for the Microsoft Windows environment that provides a guided interface to SAS for business analysts, statisticians, and programmers. It can be used to create as well as access SAS Stored Processes.
SAS Web Report Studio is a Web-based interface that provides access to query and reporting capabilities.
1.3.4.1 The SAS Stored Process Web Application For Web-based applications similar to what can be done with the Application Dispatcher, stored processes can be accessed from a browser using the SAS Stored Process Web Application (part of
Chapter 1: Overview of SAS/IntrNet and Related Technologies 11
the SAS Web Infrastructure Kit). The user interacts with a Web interface and clicks a link to retrieve results, or the user can interact with an HTML form to specify any required parameters. Other similarities to the Application Dispatcher include these:
The user interacts with a Web browser interface. In most cases the user enters parameters into an HTML form and clicks Submit. The request is then sent to the SAS Stored Process Web Application, a Java Web application located on the Web application server that can execute stored processes that are on a SAS Stored Process Server and return results to a Web browser.
To write a Web application that uses SAS Stored Processes, only SAS and HTML programming skills are needed; no other programming (e.g., Java, CGI) is required. Thus, applications can be Web-enabled very quickly.
1.3.4.2 SAS Information Delivery Portal The SAS Information Delivery Portal disseminates information in a targeted, secure, and personalized way. It allows companies to distribute SAS products and solutions to users within an enterprise and to external customers, vendors, and partners through a secure, Web-based client interface. It also supports various languages. The SAS Information Delivery Portal is a J2EE, N-tier Web application that is deployed on Java application servers across various operating environments. Built using the SAS Intelligence Platform, it shares infrastructures and metadata with other SAS solutions and technologies. ®
Any stored process that is registered in the SAS Management Console (a component of the SAS 9 BI tool set) can be readily searched and run using the SAS Information Delivery Portal. After selecting the search link, the user can search specifically for SAS Stored Processes.
1.3.4.3 SAS Add-In for Microsoft Office SAS Add-In for Microsoft Office enables users to connect to a SAS Server in order to do several things:
provide users access to SAS analytics from within Microsoft Office. This is accomplished by providing a self-sufficient, automated way to populate and maintain Microsoft Office reports with information from corporate data stores as well as from the results of analytic analysis.
make enterprise data from multiple platforms easily available to business users. Users can be given broad access to all relevant data sources, even data repositories larger than those allowed by Excel. Users can access and switch between any enterprise data source and control the amount of data that is loaded into their Excel applications.
1.3.4.4 SAS Enterprise Guide SAS Enterprise Guide is a Microsoft Windows interface that allows a user to access a SAS server (either a locally installed or remote SAS server). Here are some features of SAS Enterprise Guide:
The software has a graphical user interface that allows access to SAS. A process flow diagram facility lets users organize, view, and maintain their projects visually. It includes reporting, graphical, and analytical tasks, as well as more than 60 wizard-based tasks. Advanced users can create programs that produce tables and charts that can be easily embedded in other SAS applications and easily and securely shared.
12 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Users can perform data management functions allowing them to visually access any data types supported by SAS and native Windows data types. Users can create, update, subset, and join tables themselves using a graphical query builder.
Data stored as OLAP (i.e., multidimensional data stores) can be presented allowing users to navigate through multidimensional data, add topic-specific business calculations, and extract information from multidimensional sources for further analysis.
1.3.4.5 SAS Web Report Studio SAS Web Report Studio has a Web-based interface that provides access to query and reporting capabilities on the Web. It is targeted to non-technical business users, providing them with selfservice access to corporate data. It is completely Web-based and does not require the installation of any local software on the end-user’s PC. A Report wizard enables novice or casual users to quickly create basic queries and reports. Users can search and choose the information they need. As users’ needs evolve, more sophisticated layout and query capabilities are available from a Report Builder interface. Business users can create folders for organizing reports. Existing reports can be edited, moved, copied, deleted, or renamed. Any user with the appropriate access can search for relevant reports in public or private folders. Users can print or save a PDF version of their report. Graphs and tables can be exported to Microsoft Excel as images. Alternatively, the data presented in a graph or table can be exported as tab-delimited text.
1.4 Industry Components By definition, the Web is an open environment. The use of other technologies is an integral part of Web-based solutions. Of course, Web servers and Web browsers are a standard component. However, there are other technologies that should be considered in using SAS/IntrNet and other SAS Web technologies.
1.4.1 Scripting Languages Scripting languages, such as JavaScript and VBScript, are lightweight interpreted programming languages with simple object-oriented capabilities. Scripting language programs operate at the client side (i.e., the Web browser), and they allow executable content to be included in Web pages. Executable content within the Web page means that Web pages can include dynamic programs that interact with the user, control the Web browser, and create the HTML content dynamically. If development staff is well versed in VBScript and if the user community is using Microsoft Internet Explorer as the Web browser, then VBScript is a viable choice for a scripting language. Some will say that JavaScript is more widely used and supported, and should be the scripting language of choice. One of the more important capabilities of JavaScript is its ability to define code fragments that are to be executed when a specific event occurs. JavaScript code can be used to perform functions such as the following:
Chapter 1: Overview of SAS/IntrNet and Related Technologies 13
Validating input (e.g., check for required fields, numeric values, etc.) before submitting a CGI request.
Submitting a CGI request automatically when an item is selected from a list box (an HTML select tag).
Updating a user’s choices based on previous selections without requiring a round-trip to the server.
Reading and writing properties of, and invoking methods of, Java applets and plug-ins.
For example, general purpose JavaScript functions are used in the Xplore sample application. As one example, consider the JavaScript functions defined in the page titled Select Variables to Process. This is the page users receive when they click on a non-summary SAS data set. Those functions are used to update both a text display and a cumulative list of variables in drill-down order. Figures 1.1 through 1.3 demonstrate this. Figure 1.1 shows the initial display. Figure 1.2 shows the results after the user selects the Region check box; note how the text display was also updated. Then Figure 1.3 shows the display after the user selects another check box (Subsidiary).
Figure 1.1 JavaScript Used by Xplore to Provide Dynamic Content—Initial Display
14 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 1.2 JavaScript Used by Xplore to Provide Dynamic Content—User Selects Region
Figure 1.3 JavaScript Used by Xplore to Provide Dynamic Content—User Selects Subsidiary
Chapter 1: Overview of SAS/IntrNet and Related Technologies 15
1.4.2 Dynamic HTML As discussed in Section 1.6, Dynamic HTML (DHTML) provides facilities to make HTML-based reports dynamic in terms of interactivity and visual effects in response to user actions without requiring a round-trip to a server to regenerate HTML. It was created to overcome the interaction limitations of standard HTML. Unfortunately, different browsers support different versions of DHTML. However, in an environment (e.g., an intranet) where browser vendor and versions can be assumed, DHTML can provide an easy and powerful mechanism to extend the functionality of a Web application. For example, with Microsoft DHTML, a simple (and generic) JavaScript function can be used to expand and collapse simple lists that were built using the HTML
tag. Xplore has an Internet Explorer implementation of the SAS library viewer that is automatically used whenever the Web browser is Internet Explorer 4 or later. While the browser is loading, the content of all libraries and catalogs is defined in the initial HTML. However, the DHTML capability in Internet Explorer is used to expand and collapse libraries and catalogs without requiring any additional server processing. Figure 1.4 shows an initial folder list produced by Xplore. If the user clicks a folder (e.g., SASUSER), Figure 1.5 shows the resulting display.
Figure 1.4 Library List Produced by Xplore
16 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 1.5 SASUSER Library Expanded
1.4.3 Web Services Web services is a framework in which applications that provide specific content in response to a request are packaged as services that can be made available over the Web. All communication between services (i.e., the request for a service, and the results of running a service) is handled via XML files. Web services have been embraced by a number of vendors (e.g., the Microsoft .NET framework provides extensive support and use of the Web services model). Web services are discussed in more detail in Chapter 21, which discusses how the Application Dispatcher can be packaged to provide Web services.
1.5 Component-Based Architectures The future of Web applications development consists of a component-based architecture in which developers can mix and match a variety of programming languages and concepts, such as the SAS and industry components mentioned previously, using whichever is most appropriate for each application. Consider an example where Pareto charts are generated on historical shop-floor data. Using ODS, the code is relatively straightforward to generate one or more HTML pages with the appropriate graphics. Management decides that such charts need to be produced so that the staff monitoring the shop floor can see the most recent data being collected. But there is a wrinkle: the requirement is that the graphs need to be refreshed every ten minutes (and, of course, it is discovered later that the users may want to change that refresh frequency) with no user intervention. At first glance it is not clear how to do this using SAS or SAS/IntrNet. However, the solution is quite simple: HTML constructs exist to force a page to be refreshed on a scheduled basis. The solution is to include an
Chapter 1: Overview of SAS/IntrNet and Related Technologies 17
appropriate META tag in the HEAD section of the HTML. The following code (where the LINE data to select and the refresh rate are passed in as parameters) addresses the requirement: goptions device=jpeg cback='white'; ods html body=_webout (title="&Line Data as of &sysdate:&systime") metatext="http-equiv=""refresh"" content=""&refresh""" path=&_tmpcat (url=&_replay) rs=none nogtitle nogfootnote style = sasweb ; proc pareto data=qcdata.failure ; title .h=1 "&line Data as of &sysdate:&systime"; where line = "&line"; vbar DEFECT / freq = COUNT weight = WEIGHT chigh(2)=red cframe=gray cbars=blue nohlleg; run; ods html close; ®
The results of running this program using SAS 9 are shown in Figure 1.6. The only additions to the code to cause the refresh and to update the display with the information about the time are highlighted in bold. By combining SAS technology components (e.g., the Application Dispatcher, ODS, the PARETO procedure from SAS/QC) with an industry component (e.g., the META tag), the complete requirement has been addressed. For demonstrations and examples described in this section, go to the sample environment for this book and select Chapter 1.
Figure 1.6 Pareto Chart—Automatically Refreshed with No Additional User Input Needed
18 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
1.6 Terminology Web technology has had a dramatic impact on information delivery and the applications development process. Today’s technologies provide many benefits over the client/server model because it is no longer necessary to distribute and install applications on each desktop; information is accessible using a Web browser. The Web, as the main delivery mechanism, provides the infrastructure to ease the deployment of applications so that a client can request data or compute services. Web-enabled information delivery systems can be described in terms of the function they serve, how they work, and the types of technology they use. Here are the broad categories of how Web technologies can be used:
Web publishing is the creation of static reports, which are made available via a Web server. Any user with a Web browser can access the information. The generated reports can be produced in a variety of ways. Scheduled batch jobs are an example. The only constraint is that the files containing the reports must be written in valid Internet content form. HTML for text-based files and GIF or JPEG for graphics files are some examples of valid Internet content form.
Report distribution means that reports can be customized for specific user needs. Simple queries constructed on the clients (usually a Web browser) are passed through the Web server to a data repository, and then formatted as a report to be viewed on the client.
Application distribution means that requests for decision support services can be initiated on the client (e.g. via a Web browser), and then executed by an application server with the results available to be viewed by the client.
Data services enable the creation of Web-based applications that let the user view and query data from a Web browser. These applications are implemented using Web-enabled SQL. At the user’s request, dynamic queries can be sent to a server.
Compute services provide the ability to not only query or view data, but to actually process the data on the back-end server, thus making it possible to analyze the data, create custom reports with interactive graphics, carry out OLAP analysis, and interact with data in a data warehouse all via a user’s browser.
SAS/IntrNet data and compute services can be accessed via the Common Gateway Interface or Java technology. Here are definitions of common technology terms.
CGI (Common Gateway Interface) is a programming interface that allows a Web server to communicate with an external program. Typically, CGI programs are small, written in a script or a high-level language, and reside on the Web server to act as the interface between a Web browser and a content server (providing data and compute services). When a Web browser accesses a Uniform Resource Locator (URL) for a CGI program, the Web server executes the CGI program. Usually, the CGI program invokes a session with a database or an application server, which processes the request from the client and returns the result to the Web browser via the Web server. Strictly CGI-based applications need repeated interaction with a server or servers in order to provide an interactive interface for the user.
Chapter 1: Overview of SAS/IntrNet and Related Technologies 19
Dynamic HTML (DHTML) provides facilities to make HTML-based reports dynamic in terms of interactivity and visual effects in response to user actions, without requiring a round-trip to a server to regenerate HTML.
JavaScript is a lightweight, interpreted programming language with simple objectoriented capabilities. JavaScript operates on the client side (i.e., the Web browser) and enables executable content in Web pages.
Java is an object-oriented programming language originally developed and promoted by Sun Microsystems. It now has broad support across a variety of platforms. This language is expressly designed for use in the distributed environment of the Internet. Java enables the creation of two types of applications relevant to the Web:
Perhaps best known are Java applets. When deployed, an applet contains two parts: an HTML page, which contains a reference to the applet, and a set of Java classes, which contains the program logic. The HTML page specifies which Java applet is to be invoked. (In fact, a single HTML page can include multiple applet references.) When a Web server returns an HTML page to a Web browser that contains a reference to an applet, the Web browser reads the applet information and requests the applet classes from the Web server. After these classes are downloaded, the applet is executed, based on input from a user. For example, the applet can establish a connection to a database or application server, submit requests for processing, and receive and display the results. Because the Java applet is executing locally on the client side, it can provide a much richer interactive environment than a CGI program.
Java Server Pages (JSP) allow the execution of Java code on the Web server. A JSP page contains HTML interspersed with Java code that is executed when the page is requested to produce the desired dynamic content. This process reduces the need to download Java classes to the local machine, reduces the need to ensure that the clients all support the necessary version of Java (a major problem in the Java applet space), and speeds up execution.
JavaBeans is a component architecture framework for Java. This component defines a software Application Program Interface (API) that lets developers write reusable components once and run them anywhere a Java virtual machine is available. These components can be used in either Java applets or Java Server Pages.
ActiveX controls are an implementation for Windows only that takes advantage of the Microsoft Windows implementation of COM technologies to provide interactivity and interoperability with other types of COM components and services.
Active Server Pages (ASP) can be compared to JSPs in that ASPs are programs that execute on the Web server and return Internet content to the client. ASP is a Microsoft standard and is available on Microsoft Web servers.
.NET is the Microsoft Web-enablement architecture. .NET facilities are available or planned for virtually every Microsoft application.
Web services provides a mechanism that cross vendor, application, hardware and operating system boundaries. Web services uses XML as the transport mechanism for defining both the request as well as the delivery of results (e.g., the data).
20 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
2
P a r t
How the SAS/IntrNet Application Dispatcher Works Chapter
2
Overview of the Application Dispatcher Process Flow 23
Chapter
3
The Application Broker and the Load Manager 31
Chapter
4
The Application Server 47
Chapter
5
Communicating with the Application Dispatcher 63
Part 2 provides details about how the components of the Application Dispatcher work and interact with one another. Here are some of the topics covered:
the foundation for understanding the techniques and examples presented in Parts 3 through 5
Best Practices for the Application Dispatcher environment as well as Application Dispatcher programs
tools (available as a download as a part of the sample environment) that can be used in developing and deploying SAS Web-based applications built using the foundation provided by the Application Dispatcher
the environment to evaluate and test the examples presented in the book
Chapter 2 provides a high-level description of the components of the Application Dispatcher (the Application Broker, Application Server, and Load Manager) and how they interact with each other.
22 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Chapter 3 provides more detail regarding how the Application Broker and Load Manager components work, including a detailed discussion of the logical processing flow of the Application Broker. Chapter 4 further describes how the Application Server works, including a detailed discussion of its logical processing flow as it executes the user-requested SAS programs. Chapter 5 discusses in detail how parameter values specified via links or HTML forms are communicated to the Application Dispatcher, and how those values can be used and referenced in the SAS programs run in response to user requests. The material contained here is not intended to be a substitute for the SAS/IntrNet documentation, which is available on the SAS Web site at support.sas.com/rnd/web/intrnet. Only selected material/topics are included here. After gaining an understanding of the material in this book, you might want to read the full details about the particular component, statement, or directive. The techniques and examples presented in Parts 3, 4, and 5 rely on the concepts presented in Part 2 and so it may be useful to refer back to Part 2 while reading Parts 3, 4, and 5.
Reader Notes The topics presented in Part 2 are inter-dependent and require the background that is presented elsewhere in this part. Unfortunately, there is no optimal reading order that works for everyone. (Users can approach the material from a variety of directions, depending on what their primary goals are.) The following suggested paths should help you get the maximum benefit from Part 2. Chapters 9 and 10 include material that discusses how the Application Dispatcher works. These two chapters are included in Part 3 instead of Part 2 so the discussion can leverage some of the techniques presented in Part 3. You may want to briefly review these chapters after reading Part 2.
If You Are New to the SAS/IntrNet Application Dispatcher Readers that are new to the SAS/IntrNet Application Dispatcher may want to first scan Chapter 5, not worrying about the details and nuances. Then, go back to Chapter 2 and read the chapters in order, finishing with a detailed reading of Chapter 5. Alternatively, the reader may want to consider scanning Chapters 5, 2, 3, then 4, and then reading the chapters in order for more detail.
For Experienced SAS/IntrNet Application Dispatcher Develops and Users Experienced developers and users may want to scan Chapters 2 through 5 and then go back and re-read selected chapters in order.
C h a p t e r
2
Overview of the Application Dispatcher Process Flow 2.1 Introduction 23 2.2 Application Broker—Application Server Process Flow 24 2.3 Process Flow Including the Load Manager 25 2.4 Performance Benefits of Using the Load Manager 27
2.1 Introduction The Application Dispatcher comprises three distinct components:
the Application Broker the Application Server optionally, the Load Manager
These three work in concert to respond to a user’s request. This chapter provides a high-level overview of the components of the Application Dispatcher and provides the framework for the detailed processing flow discussed in the next two chapters.
24 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
2.2 Application Broker—Application Server Process Flow In Web applications, the user’s browser provides interface functions, querying the user about what he wants to do. The browser displays and formats the results as well. In most cases, the request for processing starts with the user filling out a form or clicking a link. This action causes the components of the Application Dispatcher to begin its processing (see Figure 2.1):
Figure 2.1 Application Dispatcher Process Flow
1. The user performs one or more of the following actions: a. b. c. d.
fills out a form and selects Submit clicks a hyperlink selects a favorite uses another HTTP client to initiate a request (e.g., the SAS URL access method)
Note: In Step 1, any client that can submit an HTTP request can invoke the Application Dispatcher. If such a client makes a request, that client will be the recipient of the streamed output in Step 5. 2. The Application Broker begins execution on the Web server: a. The Application Broker configuration file is checked to verify that the requested service (i.e., Application Server) is defined. b. If it is defined, the Application Broker forwards the request to an Application Server via TCP/IP. If there are multiple servers defined for the service, the Application Broker picks one at random, regardless of whether that server is currently running another request. Section 2.3 discusses how the use of the Load Manager enables a more intelligent selection. c. Otherwise (i.e., the service is not defined), the Application Broker streams HTML back to the user’s browser with a message to that effect. Note: The Application Server is associated with a service, and a service may include one or more Application Servers.
Chapter 2: Overview of the Application Dispatcher Process Flow 25
3. The Application Server receives the request: a. It checks to make sure the requested program is available. b. If the program is available, it then executes the program that writes Internet content to the reserved fileref _webout. c. If the requested program is not available, it streams HTML back with a message to that effect. 4. The output written by the program to _webout is streamed back to the Application Broker via TCP/IP. 5. The Application Broker streams the output back, as it is received, to the user’s browser. 6. When the Application Server has finished executing the requested program it tells the Application Broker that it has completed execution of the requested program. 7. The Application Broker finishes its processing and ends execution. All of the above steps are expanded upon in Chapters 3 and 4, which discuss the processing details of the Application Broker, Load Manager, and Application Server.
2.3 Process Flow Including the Load Manager The addition of the Load Manager enables intelligent routing and handling of incoming requests. Working in concert with the Application Broker, the Load Manager enables the Application Broker to perform the following actions:
route new incoming requests to an available server, regardless of the operating environment
start and stop remote servers based on demand
The processing logic is shown in Figure 2.2.
Figure 2.2 Application Dispatcher Process Flow Including the Use of Load Manager
Note: The Load Manager adds value only when there are multiple Application Servers defined for a service. However, the Load Manager will run correctly for services with only one server. It will always tell the Application Broker to use the single server defined for that service.
26 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
1. The user performs the following actions:
a. fills out a form and clicks on a submit button b. clicks a hyperlink c. selects a favorite d. uses another HTTP client to initiate a request (e.g., the SAS URL access method) 2. The Application Broker begins execution on the Web server: a. The Application Broker configuration file is checked to verify that the requested service (i.e., Application Server) is defined. b. If it is defined, the Application Broker sends a request to the Load Manager requesting the server and port for an available server. c. Otherwise (i.e., the service is not defined), the Application Broker streams HTML back to the user’s browser with a message to that effect. d. If the Load Manager determines that no Application Servers are currently available to process the request, the Load Manager performs one of the following actions: i. For Pool services (see Section 3.4.2), the Load Manager requests information from the Application Broker so that it can determine if starting a new Application Server (see Chapter 3) is possible. ii. If starting a new Application Server is possible, the Load Manager requests the details for starting a new Application Server from the Application Broker. It starts a new Application Server and then selects that Application Server for the current request. iii. Otherwise, if starting a new Application Server is not possible, the Load Manager waits until it is notified that an Application Server is available. e. Otherwise, the Load Manager selects an available Application Server. f. The Load Manager flags the selected Application Server’s status as Pending. g. The Load Manager tells the Application Broker the server and port to forward the request to. 3. The Application Broker forwards the request to the selected Application Server via TCP/IP. 4. Upon receiving the request, the Application Server performs the following actions: a. It tells the Load Manager to change its status from Pending to Busy. b. It checks to make sure the requested program is available. c. If the program is available, it then executes the program that writes internet content to the reserved fileref _webout. d. Otherwise, if the requested program is not available, it streams HTML back with a message to that effect. Note: Only one Load Manager should be associated with a specific Application Server. If multiple Load Managers are associated with a specific Application Server (e.g., by defining the same Application Server in two Application Broker configuration files), the different Load Managers will not be able to correctly track the state of the Application Server. 5. The output written by the program to _webout is streamed back to the Application Broker via TCP/IP. 6. The Application Broker streams the output, as it is received, back to the user’s browser. 7. When the Application Server has finished executing the requested program, it does two things:
Chapter 2: Overview of the Application Dispatcher Process Flow 27
a. It tells the Load Manager that its status is now Idle. b. It tells the Application Broker that it has completed execution of the requested program. 8. The Application Broker finishes its processing and ends execution.
2.4 Performance Benefits of Using the Load Manager When multiple Application Servers are used, it is clear that using the Load Manager will improve performance. Recall that the Load Manager causes the Application Broker to route requests to an available Application Server (if one is available). Without the Load Manager, the action is to randomly select an Application Server (which may result in an Application Server that is currently busy being selected). To illustrate that the Load Manager is instructing the Application Broker to route requests to specific Application Servers, a second request must be submitted while a first request is still processing. The same technique used for the Pareto chart example in Chapter 1 (where a META tag caused the browser to automatically refresh the requested URL) can be used here to ensure that there is a second request while the first one is still running. The secret is to pick a refresh value that is shorter than the expected duration of the SAS job. To run the examples in this section, go to the sample environment and select Chapter 2. Then select Investigate Load Manager Routing, and Open a second instance in a new browser window. The example prints the SASHELP.CLASS data set, and displays (in a title) which Application Server is running the request by displaying the server and port (see Chapter 5 for a discussion of how these values are available to the program) for the executing Application Server, along with the date and time the request was run. By default, the request is refreshed every second. Note how the requests in the two browser windows intermittently alternate between the two Application Servers. Note that there is also an option that allows a refresh rate other than 1 second to be used. It is possible to model the performance of an Application Server environment, including the potential performance gain realized by using the Load Manager, using queuing theory. The model described here is conceptually similar to the common textbook bank teller example where there is a line of customers and a fixed number of available tellers with an average time for each customer request. The pool of tellers is analogous to the pool of Application Servers; the line of customers is analogous to requests waiting for execution. Such a model can also be used to provide an estimate of the number of required Application Servers, as well as to demonstrate the benefit provided by the Load Manager. The model, as implemented, makes these assumptions:
that requests arrive randomly following a distribution quite common in queuing theory, a Poisson distribution. The defining parameter is the total number of requests per hour.
that the length of time to satisfy a request also follows a distribution quite common in queuing theory, an exponential distribution. The defining parameter is the average job length. Note that this is not a symmetric distribution, i.e., most jobs will be short, but there is a possibility of a few long running jobs. This is a very reasonable assumption.
Note: The model described here is not intended to be a robust model for Application Dispatcher environments. It is intended to provide only an approximation of the expected performance.
28 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
In order to use this model, the following parameters must be specified:
the number of requests per hour the average time for a typical request the number of available Application Servers
Tip: Estimating the average job time for a typical request is relatively straightforward. The Application Server is simply a SAS session. Thus, a simple estimate is to simply run typical jobs on the Application Server and note the average time. For demonstrations and examples described in this section, go to the sample environment for this book and select Chapter 2. This page provides a simple interface to select various values for these parameters. When the user selects Run, the queuing model is executed and the results are returned to the user’s browser. The output includes the following information:
an HTML table (see Figure 2.3) with performance statistics for both the case of the Load Manager not being used, as well as the Load Manager being used.
Expected # of Total Waiting Requests This means the average number of requests that are waiting to begin execution because the Application Servers are busy. For the No Load Manager case, this includes the jobs that were routed to a busy Application Server. For the With Load Manager case, it represents the jobs that were submitted while all the Application Servers were busy.
Expected # of Requests in the System This means the average number of requests in the system at any point. It includes both requests that are currently executing, as well as requests that are waiting.
Expected Waiting Time in Queue This means the average time that a request waits before beginning execution. Ideally, this number should be small. A value of zero results if there are never more requests than Application Servers.
Expected Time Spent in System This means the average time a user waits before seeing the results. It is the sum of the Average Request Time (one of the input parameters) and the Expected Wait Time in Queue. Note, however, that it does not include any network communication time.
Chapter 2: Overview of the Application Dispatcher Process Flow 29
a graph (see Figure 2.4) that shows the cumulative distribution of how many jobs are in the system (including running jobs) at any point. A reference line is drawn at the number of Application Servers. The intersection of this line with the graph shows what percentage of requests (on average) begin execution with no wait time.
a graph that shows what percentage of jobs are completed (i.e., results returned) versus time. A reference line is drawn at the Expected Time Spent in System (i.e., the average total waiting time). The intersection of this line with the graph shows what percentage of the jobs are completed in less than the average time.
After the model has run with the default parameters (as specified in the HTML file), the output demonstrates that, for this set of parameters, the addition of the Load Manager decreases the average time a user waits for requests by approximately 20% = (3.79–3.01)/3.79. Note that the wait time for the Load Manager case shows that nearly all the requests start almost immediately. The graph confirms this observation by demonstrating that 99.8% of the time a new request starts immediately because there is an available Application Server.
30 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
C h a p t e r
3
The Application Broker and the Load Manager 3.1 Introduction 31 3.2 Specifying Additional HTML Output 33 3.3 Defining the Load Manager 34 3.3.1 The Load Manager Command 34 3.4 Defining the SAS Application Servers 35 3.4.1 Socket Servers 35 3.4.2 Pool Servers 37 3.4.3 Launch Servers 39 3.5 Application Broker Process Flow 40 3.5.1 Load Manager Administrative Functions 46
3.1 Introduction The Application Broker and Load Manager’s processing is controlled through directives that are contained in the Application Broker configuration file. These directives define the following:
the processing, including server identification, that is involved in processing each request values that are to be made available to Application Dispatcher applications
Providing values to Application Dispatcher applications is discussed in more detail in Chapter 5. Figure 3.1 shows a sample of the directives discussed in this chapter.
32 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Note: The Application Broker is a Common Gateway Interface (CGI) program. CGI applications are quite often broadly categorized as less than optimal because the CGI process must execute on the Web server. For CGI applications that are “doing all the work” this is a valid criticism. However, the Application Broker is a very lightweight application; it is doing very little work other than communicating a request for services to another computer. Thus, the typical criticisms of the Application Broker as a CGI program are often misplaced. An exception is the rarely used launch services extension where all the work is done on the Web server since, for launch services, the SAS Application Server is also running on the Web server. For heavily loaded systems where performance is critical, the reader may want to consider one of the two additional versions (an ISAPI and a GWAPI version) of the Application Broker. These versions may also be less vulnerable to attacks by hostile users.
Figure 3.1 Sample of Application Broker Directives SASPoweredLogo "/sasweb/IntrNet9/images/saslanim.gif" SASPoweredAlt "SAS Institute Inc." SASPoweredHref "http://www.sas.com" SASPoweredTarget "wwwsascom" PrependFile "/inetpub/wwwroot/css/default.css" AppendFile "/inetpub/wwwroot/defaultContact.html" LoadManager localhost:5555 SocketService default "Default Socket Service" ServiceDescription "Default service used for SAS/IntrNet samples." ServiceAdmin "Don Henderson" ServiceAdminMail "[email protected]" Server localhost Port 5001 FullDuplex True PoolService appdisp ServiceDescription "Demo Environment for SAS Press book Application + Development Using the SAS/IntrNet Application Dispatcher" ServiceAdmin "Don Henderson" ServiceAdminMail "[email protected]" Server localhost Port 4 MinRun 1 IdleTimeout 30 FullDuplex True ServiceLoadManager localhost:5555 SasCommand "\"DRIVE:\\Program Files\\SAS\\SAS 9.1\\sas.exe\" + \"DRIVE:\\root\\SAS\\IntrNet\\appdisp\\appstart.sas\" + -rsasuser -noterminal -nolog -SYSPARM " ServicePrependFile "/inetpub/wwwroot/css/serviceSpecific.css" ServiceAppendFile "/inetpub/wwwroot/serviceSpecificContact.html"
Chapter 3: The Application Broker and the Load Manager 33
3.2 Specifying Additional HTML Output The PrependFile, ServicePrependFile, AppendFile, and ServiceAppendFile directives can be used to define a set of static HTML (tags and text) to insert at the beginning or end of every HTML page generated by an Application Dispatcher application. The PrependFile and AppendFile directives provide files to use for all the services in the Application Broker configuration file. They may be overridden on a per-service basis with ServicePrependFile and ServiceAppendFile directives. Here is the syntax: directive host-path-name
Note that the value is a host path name, not a URL, for a file that is available to the Application Broker (which executes on the Web server). See Figure 3.1 for an example of those directives. Tip: Use the forward slash (/) instead of the backward slash (\) when specifying the path name because the \ character is the Application Broker escape character. / works on both UNIX and Windows. Alternatively, use a double backslash (\\) for a single \. Some example uses of these directives could be to insert the following:
standard style sheets or JavaScript function definitions (using one of the prepend directives)
copyright text at the bottom of the generated HTML (using one of the append directives)
Best Practice: Use the prepend and append directives with care. If they are used, any ODS statement should include the no_top_matter or no_bottom_matter option or both in order to prevent malformed HTML. For example if you put an HTML and BODY tag in the PrependFile, and the application also outputs them, the generated HTML is malformed. Major browsers, however, are forgiving about this.
The SASPoweredLogo directive can be used to instruct the Application Broker to include a graphical logo which links, by default, to the SAS home page at the end of the output (and after any Append directives). It may be overridden on a per-service basis with the ServiceSASPoweredLogo. Here is the syntax: SASPoweredLogo url-path-name-for-an-image
The SASPoweredAlt, SASPoweredHref and SASPoweredTarget (and the corresponding service level directives) can be used to specify the following:
The hover text to be displayed when the user’s cursor hovers over the image (this is also the text that is displayed if the image cannot be displayed).
The URL to go to when the user clicks the image. The value to use for the TARGET= option of the image tag. Specifying a value here can force the browser to open the URL specified in SASPoweredHref in a new or different browser window.
Tip: The SASPowered directives can be used to generate an image that links to any address (e.g., a corporate home page) at the end of the generated output. See Figure 3.1 for examples of these directives.
34 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
3.3 Defining the Load Manager Whether or not the Load Manager is to be used is defined by the LoadManager and the ServiceLoadManager directives. The LoadManager directive defines a default Load Manager which is used for all the services defined in the Application Broker configuration file. This value may be overridden on a per-service basis with the ServiceLoadManager directive. Note: The use of the Load Manager, and thus a LoadManager directive, is required for pool services. Both the LoadManager and ServiceLoadManager directives define the host and port for the Load Manager, using the following syntax: LoadManager server:port ServiceLoadManager server:port
The value for server can be the DNS name (e.g., appsrv.yourcomp.com) or the IP address (e.g., 127.0.0.1) of the machine where the Load Manager is to run. The Load Manager can run on any machine that the Application Broker and Application Server can communicate with via TCP/IP, including the servers that the Web server and SAS Application Server are running on. The value for port can either be a numeric port value or a symbolic name that is defined in the system services file on the Load Manager server. Note: The Load Manager creates a log file with an audit trail of how requests are processed. Such information can provide useful diagnostics. The Load Manager is available under OS/390, UNIX, and Windows and is included in the CGI Tools download package. It is also included in the SAS installation under UNIX and Windows. See Figure 3.1 for examples of these directives.
3.3.1 The Load Manager Command The Load Manager is invoked by issuing the Load Manager command. Under Windows, the SAS/IntrNet Service Configuration Utility (inetcfg) creates the command and adds it to the Start menu (it also creates the command to define it as a Windows service). Here is the syntax: loadmgr
The most commonly used option is PORT, which specifies the port number or service name for the socket on which the Load Manager listens. If this parameter is not specified, the services file in the /etc directory is checked for an entry for LOADMGR. ®
The Load Manager shipped with SAS 9 includes options that provide additional capabilities for heavily used environments and production level applications that use pool services.
Best Practice: Always use the most current Broker and Load Manager. They are backwards compatible with previous releases of the Application Server.
Chapter 3: The Application Broker and the Load Manager 35
maxreq=minutes the maximum time it should take for the Application Server to send a BUSY state after the Application Server is selected for a request. The default is 1 minute.
maxrun=minutes the expected maximum job run time in minutes before an Application Server is declared to be hung. The default is 60 minutes. Note: The default value for maxrun is likely too long. Set maxrun to a value that is longer than the longest running request (see Chapters 17, 18, and 19 for techniques to handle long-running requests). Likewise, a shorter value for maxstart may also be appropriate (e.g., 1 or 2 minutes).
maxstart=minutes the maximum time that it should take an Application Server to start. The default is 5 minutes.
nokill the instruction to Load Manager to not kill a pool server that is marked as hung.
3.4 Defining the SAS Application Servers The SAS/IntrNet Application Dispatcher includes three kinds of Application Servers:
socket servers pool servers launch servers
The type of server to use for a user request is referred to as a service and is defined in a request using the name _service (see Chapter 5 for a discussion of _service). The value must correspond to a service defined in the Application Broker configuration file for a launch, socket or pool Application Server.
3.4.1 Socket Servers Socket services consist of one or more Application Servers that run continuously servicing client requests. Socket services can be started at administrator control, typically whenever a machine is restarted (either manually or by an operating system mechanism for starting processes at boot or log-on time). The service usually runs until the machine is shut down. Socket services are relatively simple to configure and manage and are typically adequate for many applications. Here are the primary advantages of Socket servers:
Socket services are supported on all SAS/IntrNet platforms.
The Application Server is already running by the time a client request appears, so clients do not have to wait for an Application Server to start.
The administrator has explicit control of resources allocated to the service: the administrator can control how many Application Servers are run on each system and the resources to allocate to each Application Server.
An Application Dispatcher service can include socket services running on multiple different host platforms (e.g., Windows, UNIX, MVS, etc.).
36 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Increasing load can be handled by an administrator adding more Application Servers to the service. The potential impact of adding Application Servers was seen in the Load Manager Queuing Model results in Section 2.4.
The number of Application Servers is static since they must be started and stopped manually or by the operating environment.
A fixed number of Application Servers are available to handle all client requests. Thus, one (or more) long-running requests can slow the entire service for all clients.
Additionally, since the servers are static, they are all always running, even if there are no requests.
3.4.1.1 Directives to Define Socket Servers Defining a socket server is also done with directives. Three directives are required to define a socket server:
SocketService The SocketService directive begins the definition of the socket service and provides a name for the service as well as an optional short description. The name is the value for the _service field that is passed to the Application Broker from the user request. Best Practice: If the Application Servers are running on the Web Server server, use localhost for the server The Server directive follows the name. This allows the SocketService directive. It provides the names configuration file to remain or IP numbers of the physical machines where unchanged if it is necessary to the SAS/IntrNet Application Servers are move to a different server. running. The value can be the DNS name (e.g., machine-name.your-domain.com) or the IP address (e.g., 127.0.0.1) of the machine. Port The Port directive follows the server directive. It specifies the TCP/IP port number or numbers or network service name or names used by the Application Servers for this service. You can define multiple ports by separating their values with spaces or by issuing the port directive multiple times. Numeric port ranges and symbolic names defined in the system services file are supported.
See Figure 3.1 for examples of these directives to define a socket server. The server directive can specify multiple names or IP numbers for the servers on which Application Servers are running. The port directive can specify multiple TCP/IP port numbers that represent multiple Application Server processes on a single machine. The following example shows two servers, each with three Application Servers (i.e., three port numbers): Server server_a server_b Port 5001-5003
This example defines six Applications Servers:
three Application Servers (ports 5001, 5002, and 5003) on server_a three Application Servers (ports 5001, 5001, and 5003) on server_b
Chapter 3: The Application Broker and the Load Manager 37
Note: If the Application Server selected by the Broker is not running, the Broker tries to access another one (until it finds one that is running). If the Load Manager is not being used, each of the previous Application Servers has a 1 in 6 chance of being selected for a specific request. The Application Broker randomly selects the specific Application Server (i.e., the server or port). If the Load Manager is being used, it selects which Application Server to use for a specific request. See Section 3.5. Multiple server and port lines can be used to accommodate asymmetrical configurations. Here is an example: Server server_a server_b Port 5001 5002 Server server_b Port 5003
This example defines five Application Servers:
two Application Servers (ports 5001 and 5002) on server_a three Application Servers (ports 5001, 5002, and 5003) on server_b
Since some servers are more powerful than others, you can assign weights to servers. For example, consider the following: Server server_a server_b*5
Here, server_a has a 1 in 6 chance of being assigned a request, while server_b has a 5 in 6 chance. Note that the weights apply to servers and not to individual ports on those servers. The Application Broker cannot be forced to favor one port over another on the same server. Note: Weights can be used to specify a back-up Application Server that receives requests only if the primary Application Server or servers are not operating. Set the weight to zero (0), e.g., server server_a
server_b*0
The result is that server_b (that is, the back-up server) is selected only if server_a is unavailable. Consult the SAS/IntrNet Application Dispatcher documentation for a list of SocketService directives and their options.
3.4.2 Pool Servers Pool services consist of a pool of Application Servers shared by clients. They combine the advantages of socket and launch services. (See Section 3.4.3.) Based on the system load (e.g., the number of requests), Application Servers can be started and stopped by the Load Manager. Here are the primary advantages of pool servers:
Servers are started as needed. If all the Application Servers in the service are busy, the Load Manager can start an additional Application Server.
However, once started, the Application Servers can be used for additional requests. Once an Application Server is started, it remains in the pool until an idle timeout is reached (which causes the Load Manager to stop the Application Server).
Like socket services and unlike launch services, pool services can be on a different system than the Web server.
38 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Here are the primary disadvantages of Pool Servers:
Installation and configuration is more complex for pool services than for socket servers.
The Load Manager is required for pool servers.
The Application Dispatcher service can include only pool services running under a single operating environment (e.g., all Windows, all UNIX, all MVS, etc.).
3.4.2.1 Directives to Define Pool Servers Defining a pool server is also done with directives. Four directives are required to define a pool server. Since a pool server combines the features of both launch and socket servers, it has the same set of required directives (which require similar information):
PoolService The PoolService directive begins the definition of the pool service and provides a name for the service as well as an optional short description. Just as for socket services, the name is the value for the _service field that is passed to the Application Broker from the User request.
Server The Server directive follows the PoolService directive. It provides the names or IP numbers of the physical machines where the SAS/IntrNet Application Servers are running. Note that these Application Servers are started and stopped by the Load Manager. The value can be the DNS name (e.g., machine-name.your-domain.com) or the IP address (e.g., 127.0.0.1) of the machine. Note: Weights can also be used with pool servers. However, the weights serve only to order the servers. When the Load Manager selects a server, it picks a server with the largest weight that is available at the time.
Port The Port directive follows the server directive. It specifies the TCP/IP port number(s) or network service name or names used by the Application Servers for this service. You can define multiple ports by separating their values with spaces or by issuing the port directive multiple times. Numeric port ranges and symbolic names defined in the system services file are supported. If the value of port is less than or equal to 256, the value is the number of Application Servers. In this case the Application Server picks an available port once it is started and relays the value to the Load Manager.
SasCommand The SasCommand directive provides the command and arguments that are necessary to invoke a new SAS session and is usually the fully qualified path to the SAS executable or shell script as well as the fully qualified path to the SAS program that starts the Application Server. The template provided at installation of SAS/IntrNet includes a sample SAS command.
Note: The SAS/IntrNet Service Configuration Utility (inetcfg) provides the default value to use for the SasCommand directive. Use the value provided during the installation. The value specified in the SasCommand directive must end with the text sysparm. When starting a server, the Load Manager inserts a port value at the end of the provided value. That value is used in the PROC APPSRV statement (see Chapter 4). Also note that under Windows, the .exe extension for the SAS executable file is required. See Figure 3.1 for an example of these directives to define a pool server (a subset of the directives used to define the pool server for the sample environment).
Chapter 3: The Application Broker and the Load Manager 39
The following directives are optional, but are typically included in the server definition of the configuration file:
SpawnerPort specifies the port on which the SAS Spawner is listening. The SAS Spawner is used to start new Application Servers, using the value specified in the SasCommand directive, when the Application Servers are running on a server other than the Web server. This directive is required in such cases.
IdleTimeout specifies an Application Server timeout in minutes. If no requests are sent to an Application Server, it is shut down after the IdleTimeout value is reached. The default is 60 minutes. A value of 0 indicates immediate shutdown after processing a request, including all of its sessions.
MinRun specifies the minimum number of Application Servers to keep running.
Note: When the STOP command is used, it brings the service down (i.e., no Application Servers running). Note that the service is not reset to its minimal state. MinRun isn’t enforced at Load Manager start-up. That is, the Application Server or Servers won't be started until the first request for that service. Consult the SAS/IntrNet Application Dispatcher documentation for a list of PoolService directives and their options.
3.4.3 Launch Servers A launch service starts a new Application Server for each request and then shuts down. If no sessions are involved, the Application Server shuts down as soon as the requested program finishes execution. See Chapter 4 for the details.
Best Practice: Except in rare cases, launch servers should be avoided in favor of pool servers.
The primary advantages of launch servers stem from the fact that each request is run by a separate Application Server. Therefore, the following are true:
Long-running requests do not block access for other requests. Requests with serious errors are isolated from other requests.
The major disadvantages of launch servers are these:
Launch servers must be run on the Web server.
Launch servers are not available on all hosts (e.g., MVS and VMS).
Each new request incurs the resource overhead and delay of starting a new Application Server. Launch servers are not suitable for high user loads since the Application Broker must start a new Application Server for each request.
40 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
3.4.3.1 Directives to Define Launch Servers Defining a launch server is straightforward since it involves starting a new SAS session on the Web server. There are two directives that are used in the configuration file to do this:
LaunchService The LaunchService directive begins the definition of the launch service and provides a name for the service as well as an optional short description. Just as for socket and pool services, the name is the value for the _SERVICE field that is passed to the Application Broker from the user request.
SasCommand The SAS command and arguments that are necessary to invoke a new SAS session on the Web server and is usually the fully qualified path to the SAS executable or shell script as well as the fully qualified path to the SAS program that starts the Application Server. The SYSPARM parameter (without a value) must be included at the end of the command. Note: Just as for pool services, the SAS/IntrNet Service Configuration Utility (inetcfg) provides the default value to use for the SasCommand.
Consult the SAS/IntrNet Application Dispatcher documentation for a list of LaunchService directives and their options.
3.5 Application Broker Process Flow The process flow for the Application Broker begins with the user making a request as described in Chapter 2. The Application Broker is started on the Web server, and the processing flow is illustrated in Figures 3.2 through 3.7 Note: The outline of steps described here is very detailed. You are encouraged to review it to get a general sense of the process flow. As you work through developing applications, consult the steps described here as needed.
Chapter 3: The Application Broker and the Load Manager 41
Figure 3.2 shows the processing flow for the initial set up processing done by the Application Broker. The value of _debug (discussed in detail in Section 5.2.3) is a critical component of the process flow.
Figure 3.2 Application Broker Set-Up
42 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 3.3 shows the process flow for the primary administrative functions provided by the Application Broker. The process flow makes reference to _debug containing certain values. _debug is a binary flag whose values are additive, e.g., the value 9 contains 1 and 8. Each component of _debug corresponds to a distinct power of 2. Values are added together to specify multiple options. As shown in Figure 3.3, a request may not be sent to an Application Server.
Chapter 3: The Application Broker and the Load Manager 43
Upon successful completion of its set-up and administrative processing, the Application Broker selects the Application Server to which the request should be forwarded. This processing is shown in Figure 3.4. Note: _service is required, even if _server and _port are specified. If _server and _port are specified, their values must be consistent with the service definition. Note: During this selection process, the Application Broker generates HTML content and returns it to the user’s browser with details of the Application Server selection process if _debug contains 256, 512, or 2048. These are advanced options and are rarely used.
Figure 3.4 Select Application Server
44 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
The logic shown in Figure 3.4 includes a determination of whether the Load Manager is to be used to select the Application Server. That logic is shown in Figure 3.5
Figure 3.5 Application Server Selection Delegated to Load Manager
Chapter 3: The Application Broker and the Load Manager 45
Figure 3.6 shows the process flow for forwarding the request to the Application Server. Note: The Application Server will continue to execute the user’s request (assuming it has not failed) even if the Application Broker determines that the timeout has been reached. If this happens, the content generated by the Application Server and passed back to the Application Broker is lost.
Figure 3.6 Send Request to Application Server
46 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 3.7 shows the process flow for streaming the results back to the user’s browser. See Section 4.6 for details of the Application Server process flow.
Figure 3.7 Stream Content Back to User’s Browser
3.5.1 Load Manager Administrative Functions The Load Manager performs several administrative tasks in parallel to its function of selecting servers:
It polls all the Application Servers to ensure that its table of their status is up-to-date.
It also responds to requests for its status (i.e., the LOADSTAT program) administrative request.
If an Application Server has been in a BUSY state for a period that exceeds the time period specified in the maxrun option, it attempts to kill the Application Server process. For pool servers the nokill option must also be specified in order for the Load Manager to attempt to kill the server.
If Application Servers have been idle for a period longer than the server timeout period, and the number of Application Servers is greater than the minimum number of Application Servers, the Load Manager sends a STOP command to those extra Application Servers.
C h a p t e r
4
The Application Server 4.1 Introduction 47 4.2 SAS Application Server Executives 49 4.3 Application Server Sessions 50 4.3.1 ODS and Sessions 50 4.4 PROC APPSRV 51 4.4.1 TCP/IP Port 51 4.4.2 Assigning Libraries 51 4.4.3 Initiating and Terminating Requests 54 4.5 Application Server Process Flow 55 4.5.1 Application Server Functions Available to the Executing Program 60 4.5.2 Application Server Clean-Up Processing 60
4.1 Introduction A component of the Application Dispatcher, the Application Server executes SAS programs that use SAS for data access and reporting. The Application Server not only executes the programs; it also provides a robust execution environment, which enables SAS programs to generate their results as Internet content. This content is then sent back to the user’s browser. The execution details for the Application Server are the same regardless of the type of service (e.g., launch, socket, or pool service) and regardless of where the Application Server is running. From the perspective of the Application Server, there are only two differences between these types of services:
how and when the Application Server process begins execution when the Application Server stops processing requests
48 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
The programs that are executed by the Application Server are SAS programs. All of them have these characteristics:
they can be executed in batch
they generate output as Internet content
they use macro variables (see Chapter 5 for a more detailed discussion of this) to specify parameters used to customize what the program does
The Application Server itself is simply a constantly running SAS job that was invoked by the APPSRV procedure. Once PROC APPSRV begins execution, it performs the following tasks:
listens on a TCP/IP socket for requests to run a program from the Application Broker runs the requested program sends the results back to the Application Broker waits for another request, and if one is received, cycles through this process again
See Figure 4.1 for a sample SAS job that invokes PROC APPSRV. If the SAS/IntrNet Service Configuration Utility was used, it creates a default SAS job. The bold text was added to the job for the Application Server that supports the sample environment.
An understanding of how the Application Server executes SAS programs will help you use the Application Server effectively. This chapter focuses on four key areas:
the concept of a SAS Application Server Executive Application Server sessions the APPSRV procedure the process flow for user requests
4.2 SAS Application Server Executives A SAS Executive is an independent runtime environment that can be started within a SAS process. SAS can create multiple Executives in a single SAS session (conceptually similar to having SAS spawn a new SAS session using an operating environment command or through SAS/CONNECT software). When SAS is started, one Executive is created. Most user programs run in this single Executive and then terminate. In the case of the Application Server, PROC APPSRV runs in this main Executive and the Application Server starts and stops other Executives to run the user programs. These are referred to as Request Executives. Since each Executive is completely independent, statements that define or set global macro variables, librefs, filenames, and options apply only to the Executive in which they are defined. This means, for example, that any such statements defined in the SAS program that executes the PROC APPSRV statement do not have any impact on user programs that are executed by PROC APPSRV. The reason is that they each run in their own Request Executive. Note: The example presented at the end of Chapter 1 used &sysdate and &systime as the current date time. In a typical SAS job those macro variables represent the date and time the SAS job started. Given that these are created in a Request Executive, the values correspond to the date and time the Request Executive was created. Thus they reflect the date and time that the current request was started and not the date and time the Application Server itself was started. Tip: Since user programs are executed in separate Executives, an ENDSAS statement in a program tells the Application Server to end the Executive for that user program; it does not end the Application Server. Thus, an ENDSAS statement can be used to terminate a user request. If an ENDSAS statement is used to terminate a request, the REQUEST TERM program, if specified, will not be run. Check with your server administrator to see if this is a problem. Examples that use this technique are discussed in Parts 4 and 5. Note: In Version 6 an ENDSAS statement in a user-requested program ended the execution of the Application Server.
50 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
4.3 Application Server Sessions The Web is a stateless environment. That is, each request knows nothing about any prior request. This fact creates a simple environment in that each request is completely self-contained. However, quite often it is desirable and necessary to maintain certain information from one request to the next. This is known as maintaining state. The Application Dispatcher supports the creation and use of sessions as a way to share data and macro variables across separate requests without requiring each application program to provide a mechanism to store and retrieve such information. Sessions provide a way to maintain this state across multiple requests. A session is simply the saving of data and parameters from one program execution to the next. Sessions provide the ability to save library members (data sets and catalogs) and macro variables. The program explicitly specifies what to save and restore. The Application Server can support multiple independent sessions (for separate sets of user request streams). It is the responsibility of each program to perform the following tasks:
create a session only when necessary and appropriate specify what information (e.g., data sets, catalogs, macro variables) is to be saved ensure that future requests reconnect to the session retrieve any needed information from a prior session
A program can specify that future requests reconnect to a session by ensuring that any generated links or forms include the _SERVICE, _SERVER, _PORT, and _SESSIONID values for that session. These fields are discussed further in Chapter 5. The mechanics of using sessions are straightforward. Once the session has been created, a library named SAVE is created. By creating or copying data sets and catalogs to this library, the user program can trust that they will be there the next time a request is made that uses this session. All the global macro variables whose names begin with SAVE_ are saved by the Application Server at the completion of any request that uses sessions. At the beginning of any future request, they are restored. Chapter 10 discusses creating and reconnecting to sessions in more detail.
4.3.1 ODS and Sessions Sessions are used in Application Dispatcher programs that use ODS where ODS creates multiple separate output files. Here are just two examples:
an HTML page with both a tabular report and a graph a frame with a table of contents with links to each part of the output
If the program has already created a session of its own, ODS will use it; otherwise ODS will create a lightweight session. Since a single Web request can return only one file, ODS will create the additional files and save them in SAS catalog entries. For an HTML page with an embedded graph, the graph (or graphs) will be created and saved as a graphic (e.g., GIF or JPEG) entry in a catalog. For a frame, the table of contents file and the body file are saved in HTML entries in such a catalog. These entries are returned to the user’s browser by a link that reconnects to the session to replay the entry. The replay tool is discussed in Parts 3, 4, and 5, and specifically in Chapter 8. Sessions created by ODS are lightweight sessions in that they do not have their own distinct SAVE library, nor are macro variables saved. They share a single APSWORK library instead of having separate SAVE libraries for each session.
Chapter 4: The Application Server 51
4.4 PROC APPSRV A SAS/IntrNet Application Server is started by a SAS program that invokes PROC APPSRV. The SAS/IntrNet Service Configuration Utility (inetcfg) creates a SAS program (appstart.sas) that includes a PROC APPSRV statement with reasonable defaults. The most commonly used options and statements of PROC APPSRV are discussed here as they are important components of the process flow. Selected options and statements are covered later. For complete details on PROC APPSRV statements and options, see the SAS/IntrNet documentation. The statements and options addressed here are those that relate to the following:
communicating with the Application Broker via TCP/IP port assigning libraries initiating and terminating requests
Figure 4.1 includes an example PROC APPSRV statement.
4.4.1 TCP/IP Port The PORT= option of the PROC APPSRV statement specifies the TCP/IP socket that the Application Server uses to communicate with the Application Broker. The Application Server listens on this port, waiting for requests. Once a request is received and processed, the results are sent back to the Application Broker on the same port. The value for port can be specified in one of three ways:
a numeric value other than zero is assumed to be the TCP/IP port number on which the server listens for requests
an alphanumeric value is assumed to be a network service name. The name is searched in the system services file (for example, /etc/services) and translated to a port number
a value of zero is used for launch and pool services, causing PROC APPSRV to choose an available port
4.4.2 Assigning Libraries The following are four PROC APPSRV statements are used to specify the libraries and directories that are available to programs executed by the Application Server in response to user requests:
ALLOCATE LIBRARY and ALLOCATE FILE DATALIBS PROGLIBS ADMINLIBS
Note: SAS LIBNAME and FILENAME statements should not be used in the SAS program used to run PROC APPSRV if the intent is to make those files and libraries available to programs executed by the Application Server in response to user requests. As mentioned previously, each request is run by a separate Request Executive and the program that runs PROC APPSRV is its own Executive. Since each Executive is independent, library and file definitions are not shared between Executives. See Figure 4.1 for examples of each of these statements.
52 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
4.4.2.1 ALLOCATE The ALLOCATE statement takes two forms:
ALLOCATE LIBRARY libref <engine> 'SAS-data-library' ; This form associates a SAS libref with a SAS data library.
ALLOCATE FILE fileref <device-type> 'directory-or-PDS-path' ; This form associates a SAS fileref with an external file or directory (including PDS’ on MVS)
The syntax and options for both of these statements are identical to the syntax for the SAS LIBNAME and FILENAME statements. The key point is that the ALLOCATE statement provides the information needed by PROC APPSRV to issue LIBNAME and FILENAME statements that are associated with the Request Executives. However, the SAS librefs and filerefs defined in an ALLOCATE statement are not automatically made available to the Request Executives, so they must also be listed in a DATALIBS, PROGLIBS, or ADMINLIBS statement.
4.4.2.2 DATALIBS SAS librefs and filerefs that are listed in a DATALIBS statement are made available to all programs that are run by the Application Server. Here is the syntax: DATALIBS libref-1 | <…libref-n | fileref-n>; The librefs and filerefs must correspond to librefs and filerefs defined in an ALLOCATE statement or that are defined externally to SAS (e.g., in the JCL stream that starts the Application Server on MVS). Best Practice: Since including a libref or fileref in a DATALIBS statement specifies that the libref/fileref is assigned and accessible to all programs that run on the server, use DATALIBS statements only for globally accessible data repositories that contain non-sensitive data. Keep private or application-specific data in its own library and assign it by using a LIBNAME statement. Techniques to do this are discussed in Part 3 and used in the examples in Part 5.
Librefs and filerefs listed in a DATALIBS statement cannot be cleared by programs that are executed by the Application Server (that is, by PROC APPSRV). In other words, if the libref MYDATA is defined using a DATALIBS statement, that libref is available to all programs run by the Application Server and cannot be cleared by a LIBNAME statement like this: libname MYDATA clear;
4.4.2.3 PROGLIBS The PROGLIBS statement defines which libraries, catalogs, and filerefs contain the SAS programs that can be run by a request to an Application Server. Here is the syntax: PROGLIBS libref-1 | libref-1.catalog-1 | fileref-1 <…libref-n | libref-n.catalog-n | fileref-n>;
Chapter 4: The Application Server 53
Just as for the DATALIBS statement, the librefs and filerefs defined in a PROGLIBS statement must correspond to librefs and filerefs defined in an ALLOCATE statement or that are defined externally to SAS (e.g., in the JCL stream that starts the Application Server on MVS). They cannot be cleared by programs that are executed by the Application Server. SAS librefs listed in PROGLIBS statements should contain catalogs. In turn, these catalogs should contain SAS programs that can be executed by the Application Server. The SAS programs can be SOURCE, MACRO, or SCL catalog entries. The same librefs and filerefs can be listed in both DATALIBS and PROGLIBS statements. However, it is typically not a good idea to put application-specific code in a library that is available to all requests run by an Application Server. SAS filerefs listed in a PROGLIBS statement should point to a directory or partitioned data set (PDS) that contains SAS code in individual .sas files (a PDS is assumed to contain SAS source code in individual members). Note that if a libref is specified in the PROGLIBS statement, then any SCL, SOURCE, or MACRO entry in any catalog in that library can be run by the Application Server in response to a user request. Instead of specifying the libref, you can specify the catalogs in that library as libref.catalog. Using this form causes the libref to be defined, but restricts how they are run: only entries in the listed catalogs can be run by the Application Server in response to a user request.
Best Practice: For code contained in SAS catalogs, if just the libref is specified in the ADMINLIBS or PROGLIBS statements, then any entry in any catalog in the library can be specified as the program to run. Using the libref.catalog syntax instead of just specifying the libref is a suggested Best Practice and enables a developer to include other catalogs in the library that contain utility code (used by an application) that should not be directly executable by the Application Server in response to a user request. Utility code that is used by multiple applications should be stored in a separate library. That code can be made available to all programs run by the Application Server by including the libref or fileref in a DATALIBS statement.
When a request is received by the Application Server, it checks the PROGLIBS list for a match on the first one or two levels in the program name that is supplied in the special request variable _PROGRAM. If a match is found, then that program can be executed.
4.4.2.4 ADMINLIBS The ADMINLIBS statement is similar (in syntax Best Practice: Since the Application Server has and function) to the PROGLIBS statement except several built-in programs (such as STOP) that that it specifies one or more librefs, catalog, and should not be available to all users, using the filerefs that contain password-protected ADMINPW variable is recommended. Otherwise any user can stop an Application Server from any administrator programs. They are used in Web browser. conjunction with the ADMINPW option in the PROC APPSRV statement. If ADMINPW is specified in the PROC APPSRV statement (see Figure 4.1 for an example), the user must supply the password in the request (using the _ADMINPW variable) in order to run a program contained in one of the librefs, libref.catalogs, or filerefs listed in an ADMINLIB statement.
54 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
4.4.3 Initiating and Terminating Requests The REQUEST and SESSION statements define a number of parameters and actions for PROC APPSRV to use as it executes a request.
Best Practice: Specifying a program to run at the beginning of any program (i.e., REQUEST INIT=) is often a good idea. This initial program can be used to provide default options and parameters that apply to all programs; for example, graphics options, sasautos, and others. Numerous examples are presented in Parts 3, 4, and 5 that make use of this Best Practice.
The INIT option specifies the name of a program whose purpose is similar to what an autoexec.sas file does. Since user The location for the REQUEST (and SESSION) INIT and requests are executed in separate Request TERM programs should be listed in an ADMINLIBS Executives, statements in the standard statement, not a PROGLIBS statement. autoexec.sas file are not applied to the Request Executive. Instead, this option is used to provide the name of a program that is run at the following times:
at the beginning of any request to the Application Server to run a program (i.e., REQUEST INIT=)
when a session is created by a program that is being executed by the Application Server in response to a user request (i.e., SESSION INIT=) Note: Lightweight sessions created by ODS do not cause the SESSION INIT= program to be run.
By default, no program is run before beginning a request or when a session is created. The program names referenced in the INIT option must be in the same format as the _PROGRAM variable (see Chapter 5 for a discussion of the _PROGRAM variable). The libraries, catalogs, or directories that contain these programs must be defined in a PROGLIBS or ADMINLIBS statement. The TERM option specifies the name of a program that PROC APPSRV runs:
at the completion of any request to the Application Server to run a program (i.e., REQUEST TERM=)
when a session is destroyed by a program that is being executed by the Application Server in response to a user request (i.e., SESSION TERM=)
when a session expires Note: Sessions created by ODS do run the SESSION TERM= program when the session is terminated.
Chapter 4: The Application Server 55
The TERM option is comparable to the INIT option in several ways:
By default, no program is run. The program name must be in the same format as the _PROGRAM variable. The libraries, catalogs, or directory must be defined in a PROGLIBS or ADMINLIBS statement.
The INVSESS option enables more control over what the Application Server does if a request is to reconnect to a previously created session that no longer exists. It provides the name of a program that is to be run in the place of the requested program. The name of the program that was requested by the user is made available to this program as the value of the _USERPROGRAM macro variable.
Best Practice: Specifying a program to run when an attempt to reconnect to a session fails (i.e., SESSION INVSESS=) is often a good idea. This program can display an informative response when a reconnect fails, generate HTML to redirect the user to an application login screen, explain how to restart the application, or provide a friendlier error message. Examples are presented in Chapter 10 and later chapters using sessions that make use of the INVSESS option.
The INVSESS option is comparable to the INIT option in several ways:
By default, no program is run. The program name must be in the same format as the _PROGRAM variable. The libraries, catalogs, or directory must be defined in a PROGLIBS statement.
4.5 Application Server Process Flow The process flow for the Application Server begins with the execution of a SAS program that invokes PROC APPSRV. Typically this program is named appstart.sas and has been customized from a default appstart.sas file built by the SAS/IntrNet Service Configuration Utility (inetcfg) (see Figure 4.1 for a sample appstart.sas file). Running this appstart.sas file starts a SAS Executive that runs PROC APPSRV. The appstart.sas file can be run in a number of ways, e.g.:
For pool services, it is launched by either the Load Manager or the SAS spawner (in response to a request from the Load Manager).
For socket services it can be started in several ways:
by the operating environment when the machine boots (e.g., as a Windows service)
by an administrator-defined batch process
interactively (i.e., a user starts it as a batch process)
in an interactive SAS session (this is typically be limited to situations where advanced debugging is required. See Chapter 11)
For launch services, it is launched by the Application Broker, which starts the Application Server on the Web server.
56 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
The syntax of the statements in the appstart.sas file is checked as is the case for any submitted SAS program (e.g., mismatched quotes, invalid statements, etc.). There are several additional conditions that can cause the Application Server to not start. Conditions such as the following are all noted in the log:
One or more of the programs referenced in the INIT, TERM, or INVSESS options of the REQUEST or SESSION statements do not exist (or the libref libref.catalog were not listed in a PROGLIBS or ADMINLIBS statement).
The specified value for PORT is missing, invalid, or unavailable.
Note: If a directory, library, or catalog listed in an ALLOCATE, DATALIBS, or PROGLIBS statement statement does not exist, the Application Server will still start execution. However, a note is displayed in the log that the file was unavailable. If the library, directory, or catalog exists when a Request Executive begins, they are available to the executing program. A functional overview of the processing logic once the Application Server begins execution is shown in Figures 4.2, 4.3, and 4.4. Note: The outline of steps described here is very detailed. You are encouraged to briefly review the outline to get a general sense of the processing flow. As you work through developing applications, consult the steps described here as needed. Figure 4.2 shows the set-up processing done by the Application Server to prepare to run the requested program. Upon successful completion of this set-up processing, the Application Server will run the program using a Request Executive as illustrated in Figure 4.3. After the programming has completed execution, the Application Server performs termination processing as illustrated in Figure 4.4.
Chapter 4: The Application Server 57
Figure 4.2 Set-Up to Run Program
Footnote: The status of an Application Server that is associated with more than one service (which have different Load Managers) can cause the updates sent from the Application Server to Load Manager to get out of synch.
58 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 4.3 Process in Request Executive
Footnote: _GRPHOUT was needed in an earlier version of the Application Server where it was not possible to write both text (e.g., HTML) and binary (e.g., graphics) content to the same fileref. That restriction was removed in Version 7 and _WEBOUT can now be used for both text and binary output.
Chapter 4: The Application Server 59
Figure 4.4 Termination Processing
60 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
4.5.1 Application Server Functions Available to the Executing Program While the requested program is executing, there are a number of Application Server functions or services that the program can invoke by using one of the Application Server functions. Consult the SAS/IntrNet documentation for a list of functions and the details of how they work. The most commonly used functions and their actions are the following:
APPSRV_SESSION can be used to create a new session or flag the existing session for deletion. When this function is used to create a session the following actions occur:
The macro variable _SESSIONID is assigned and given a value to uniquely identify the session.
The macro variables _REPLAY and _TMPCAT (see Section 5.4) to reflect the creation of a user session are created or updated.
A temporary SAVE library is defined. This library exists for the length of the session.
The SESSION INIT program, if specified, is run.
APPSRV_HEADER can be used to explicitly specify the content-type header that should be sent at the beginning of the generated Internet content.
APPSRV_UNSAFE is used to get the values of parameters before any special characters were stripped out. The values are from the internal table created as shown in Figure 4.2.
APPSRVSET can be used to set various parameters that control the characteristics of the request or the session. For example, the maximum time to allow a program to run can be set or updated. Similarly, the time that a session is to remain active between reconnect requests can be set or updated.
APPSRVGETN (or C) can be used to get various numeric (N) or character (C) parameters (e.g., this function can be used to get the name of the REQUEST TERM program).
4.5.2 Application Server Clean-Up Processing The Application Server has a number of clean-up or bookkeeping tasks that it does in parallel with what is described above for the processing of requests. Here is a functional overview of bookkeeping or clean-up logic (not necessary in this order):
If a program has been running longer than Best Practice: If the majority of requests to be the maximum allowed time, the Application processed by an Application Server are long and Server terminates it (as described above). consistent in their length, use the REQUEST The default time a program is allowed to run TIMEOUT option. Otherwise, use the APPSRVSET function in long-running jobs to is 5 minutes. This value can be changed on update the maximum time. This limits the the REQUEST statement using the longer times to just those requests that need it TIMEOUT option. Values set this way and allows for the time to be customized to the apply to all programs run by the Application specific request. Server. An individual program can update the maximum allowed time using the APPSRVSET function.
Chapter 4: The Application Server 61
Sessions that were last accessed earlier than Best Practice: If the majority of sessions to be the current time minus the session timeout processed by an Application Server are are terminated. In addition, sessions that consistent in their length, use the SESSION were flagged for deletion by a request TIMEOUT option. Otherwise, use the (which has completed its processing) are APPSRVSET function to update the maximum also terminated. In both cases the SESSION time. This limits the longer times to just those sessions that need it and allows for the time to TERM program, if specified, is run. The be customized to the specific session. SAVE library, if created for the session, is deleted and is no longer available on disk. The default time a session is allowed to remain active is 15 minutes. This value can be changed in the SESSION statement using the TIMEOUT option. Values set this way apply to all programs run by the Application Server. An individual program can update the maximum allowed time using the APPSRVSET function. This TIMEOUT value can be updated by the program that created the session as well as by any program that is run in response to a request that uses the session.
If a request with _program=STOP was made (see Figure 4.2), the Application Server (i.e., PROC APPSRV) stops accepting new requests. Once any active sessions have timed out, control is returned to the next step (if any) in the appstart.sas program. Typically, there is no next step after the PROC APPSRV and the SAS session ends.
Responses to the Load Manager queries about its status: The Application Server informs the Load Manager of its current status (either Busy or Idle).
62 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
C h a p t e r
5
Communicating with the Application Dispatcher 5.1 Introduction 63 5.2 Name/Value Pairs Defined by the User’s Request 64 5.2.1 _program: The SAS Program to Execute 64 5.2.2 _service: The Application Server to Process the Request 65 5.2.3 _debug: The Output to Display 65 5.2.4 Program-Specific HTML Name/Value Pairs 68 5.3 Name/Value Pairs Defined by the Application Broker 72 5.3.1 Application Broker Administrative Fields 72 5.3.2 Environment Variables 73 5.3.3 Installation Dependent Fields 74 5.4 Name/Value Pairs Defined by the Application Server 76
5.1 Introduction When the Application Dispatcher executes a SAS program and generates Internet content to be returned to the user’s browser, it needs to know the values for a number of parameters. Likewise, the program typically has a number of parameters whose values need to be passed to it. When values are defined in an HTML page they are referred to as HTML name/value pairs. As mentioned in Chapters 3 and 4, this construct is used by the Application Dispatcher for the information that needs to be passed from the user’s browser to the Application Broker and then on to the Application Server and eventually to the requested program.
64 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
There are three points in the process flow where these name/value pairs are defined and made available to the program as macro variables:
by the user’s request (e.g., an HTML page or form or a URL such as a saved favorite or link on an HTML page)
by the Application Broker by the Application Server
5.2 Name/Value Pairs Defined by the User’s Request The request to the Application Dispatcher must define the name/value pairs necessary for the program to be executed. Note that the Application Dispatcher has three required name/value pairs:
_program which identifies the specific SAS program to be executed
_debug which is used to define what output is displayed
_service which identifies the SAS Application Server or Servers to be used to process the user’s request
Note: Default values can be provided for _service and _debug in the Application Broker configuration file. These three are discussed first, followed by a discussion of defining program-specific HTML name/value pairs.
5.2.1 _program: The SAS Program to Execute The _program name/value pair specifies the name of the program to be executed. The program can be any of the following:
an external file containing SAS source code (i.e., a .sas file) a SAS source entry containing SAS source code (i.e., a .source catalog entry) the name of a compiled SAS macro (i.e., a .macro catalog entry) a SAS SCL entry containing a compiled SCL program (i.e., a .scl catalog entry)
Note: The SAS Process Server can only directly execute an external file containing SAS code. The other three entries can be executed if they are invoked from such a file of SAS code. For the three types that are SAS catalog entries, a four-level name must be provided. The first node is the libref (as defined in the ALLOCATE LIBRARY statement). The second node is the catalog; the third node is the entry name; and the fourth node is the entry type (e.g., SOURCE, MACRO, or SCL). For example, a value of saspress.chapter1.pareto.source for _program runs the program that generated the Pareto chart shown in Chapter 1. For an external file of SAS code, a three-level name must be provided. The first node in the name is the directory (as defined in the ALLOCATE FILE statement). The second node is the actual filename as it is defined to the operating environment (including the case if the operating environment is case sensitive); and the third node is sas. For example, a value of
Chapter 5: Communicating with the Application Dispatcher 65
sample.webhello.sas for _program will run one of the sample programs provided as part of the installation of the SAS/IntrNet Application Dispatcher.
Tip: The source code for a macro entry can be stored in the same catalog as the compiled macro. If it is stored in the same catalog, the source entry can be executed by a user when the user specifies the four-level name as the value of _program. If such an entry contained only the macro definition, it would not generate any output when executed by the Application Dispatcher. Instead, the program would simply compile the macro. Depending on the environment, it is a Best Practice either to always or never store the source in the same catalog. Note that for the Xplore sample application, which is distributed with SAS/IntrNet, the macro source is included in the catalog.
5.2.2 _service: The Application Server to Process the Request As discussed in Chapter 3, the value of _service specifies which Application Server (or pool of Application Servers) to use for the request. The value must correspond to a service defined in the Application Best Practice: If a program generates a link or form, the value of _service should Broker configuration file. This value defines both what be defined using the macro variable kind of service to use for the request (i.e., socket, launch reference &_service. It should not be or pool) and which particular SAS Application Server hardcoded in the program. should be used to process the request (i.e., the server and port that the Application Server is listening on). A default value for _service can be defined in the Application Broker configuration file. That value is used by the Application Broker whenever the user request does not explicitly define which service to use.
Best Practice: Don’t define a default value for _service except in limited situations. Specifying a default value, while convenient, enables requests to be sent to those servers without requiring the requestor to know the name of the services at your site.
When a program has implemented sessions, the Application Server to process the request is more precisely defined. If the service contains multiple Application Servers, then it is necessary to define exactly which Application Server and exactly which port (as well as an identifier of the created SAS session). Those values are defined using the special fields _server, _port, and _sessionid. When sessions are being used, these fields should be used in addition to _service. Note: Programs that use sessions that generate a link or form to reconnect to the session must use the macro variables _server, _port, and _sessionid. When generating a hyperlink as opposed to form fields, the special variable _thissession can also be used to define the name/value pairs for _server, _port and _sessionid as well as _url. Other special fields created by the Application Broker and Application Server are discussed in Sections 5.3 and 5.4.
5.2.3 _debug: The Output to Display The value of _debug defines what output is returned to the user’s browser as well as how the output is displayed. Values are powers of two define distinct values each of which turns on a specific option. In order to turn on multiple options, you need to add values together to get the value that turns on all the desired options. The values can be categorized. Selected details are provided in Table 5.1 for the more commonly used values. See the SAS documentation for details on the list of all the values along with the options they control.
66 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Table 5.1 Selected Values of the _debug Parameter To control What output to display and how to display it
Enter the value 0
1
Echoes the field values passed from the Application Broker to the Application Server.
8
Tells the Application Dispatcher not to execute the requested program. This can be useful when it is necessary to see all the fields being passed to the Application Server by the Application Broker (i.e., a value of 1), but when you do not want to run the program. In order to do this, use a value of 9 (equal to 8+1).
16
Displays the output in hexadecimal. Most typically used for debugging problems with the HTTP header or non-text Internet content such as graphics, PDF, comma-separated values, etc.
128 The display of the SAS Powered Logo and Execution Details
Advanced features
Information about the environment defined for the Application Broker
The result Displays only the output generated and written to the fileref _webout (or _grphout) by the requested program.
Returns the SAS log for the requested program as HTML.
2
Displays the Application Broker version number and elapsed time after each run. The Powered by SAS logo is also displayed if the location of the logo is defined in the Application Broker configuration file.
32
Displays the Powered by SAS logo without Application Broker version or elapsed time information if the location of the logo is defined in the Application Broker configuration file.
256, 512, or 2048
Traces socket connection attempts. These are advanced options and are rarely used (they are typically used at the suggestion of SAS Technical Support).
1024, 4096, or 8192
Performs debugging for earlier versions. Used either prior to Version 8 or for debugging. Values 4096 and 8192 are specific to Launch Services. They are most commonly used at the advice of SAS Technical Support.
4
Lists definitions of all services defined in the Application Broker configuration file. The specified program is not run.
16384
Displays Web server environment variables that have nonblank values and that can be made available for export.
Chapter 5: Communicating with the Application Dispatcher 67
Here are some typical scenarios and the appropriate values of _debug to use:
Use a value of 0 when no extra content is to be generated: the only content to be displayed is the output generated by the program.
If HTML is being generated to be followed by only the SAS Powered logo, use a value of 32. If the time and broker version are also desired, use a value of 2.
To see what values are passed to the program, followed by the output, the SAS log, the SAS Powered logo, the time, and the Application Broker version, use a value of 1+128+2 = 131. Note that this value can be used even with non-HTML output (e.g., PDF or graphics). However, the non-HTML output is not displayed in a readable format (since the inclusion of 1 in the value causes a text or HTML content header to be sent to the user’s browser).
To see what values are being passed to the program and then have the output displayed as hexadecimal, use a value of 1+16 = 17. ®
Note: The Application Broker that shipped with SAS 9 allows for mnemonic values for selected _debug values: 1: 2: 4: 16: 128: 1024: 2048: 16384:
FIELDS TIME SERVICES DUMP LOG ECHO TRACE ENV
To turn multiple options on, each mnemonic is included, separated by commas. The value sent to the Application Server is the corresponding numeric value. The _debug parameter gives a great deal of control to Best Practice: For each service, determine the requestor to get additional information. Often the exactly what values are to be allowed and developer or administrators for such applications want specify the sum of those values as the to control users’ access to get such output (e.g., ServiceDebugMask. protecting the SAS log from being seen by others). The DebugMask parameter (defined in the Application Broker configuration file using the DebugMask or ServiceDebugMask directive) allows the developer to control which values of _debug are allowed. The DebugMask parameter applies to all the services defined in the Application Broker configuration file. There is a comparable parameter (ServiceDebugMask) that can be used to define a service-specific value. The DebugMask value is additive, just like the value of _debug is. For example, if the only values to be allowed for _debug are 0, 2, or 32, then setting DebugMask (or ServiceDebugMask) to 34 (=0+2+32) accomplishes that.
68 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
5.2.4 Program-Specific HTML Name/Value Pairs When the requested program begins execution, macro variables are used to make name/value pairs available to the SAS program that is to be run. The macro variable names correspond to the HTML names and the values of macro Best Practice: For SCL entries, the name/value pairs are variables are the HTML values. The also available in an SCL list passed into the program. Application Dispatcher automatically While it can be easier to use the SCL list functions, the creates the macro variables corresponding to same name/value pairs are available as macro variables. the HTML name/value pairs. As a result, the If the SCL program accesses the macro variables instead of the SCL list, the program can be more easily used in SAS programmer need not be concerned other environments (e.g., the SAS Stored Process with obtaining the values specified by the Server). In addition, macro variable values can be overuser on the HTML page. However, HTML ridden and augmented in the REQUEST INIT program. names must correspond to valid SAS names since non-valid SAS names are rejected by the Application Broker. The Application Server provides a facility to prevent certain special characters (e.g., single and double quotes, semicolons, and the percent sign and ampersand, which are used as macro triggers) from being included in a value. When specified special characters are found in a value, the Application Server strips those characters out of the value. The UNSAFE option of PROC APPSRV statement is used to specify what those characters are. There are several cases where it is not possible to directly map the values from an HTML page to a single macro variable. Here are two:
the same HTML name being used multiple times in the HTML form or URL
long text values
Best Practice: Do not remove any of the default special characters that the Application Server strips out. Doing so could make programs less stable and could enable a sophisticated hacker to do damage. Instead, for those parameters where such characters are possible, use the APPSRV_UNSAFE function to get the original value and use caution when referencing or using the values. See Chapter 6 for more information.
5.2.4.1 Multiple Values for a Single HTML Name HTML allows multiple values to be passed using a single HTML name; however, SAS macro variables do not allow multiple values. Macro variables can contain a list of values which a SAS program can parse to recreate the distinct values. However, the Application Dispatcher uses a different method to handle multiple values. The Application Broker appends a suffix to the original name creating multiple macro variables when it receives multiple values for a single name. Consider an example where the HTML has five check box fields, all called var:
TYPE=”checkbox” TYPE=”checkbox” TYPE=”checkbox” TYPE=”checkbox” TYPE=”checkbox”
VALUE=“name”> Name VALUE=“sex”>Sex VALUE=“age”>Age VALUE=“height”>Height VALUE=“weight”>Weight
Chapter 5: Communicating with the Application Dispatcher 69
If all five values are checked, the Application Dispatcher defines the following macro variables and values (note that you cannot assume that the values are passed in the indicated order, e.g., the third check box could be the last value passed):
VAR0: 5 VAR: name VAR1: name VAR2: sex VAR3: age VAR4: height
Best Practice: Programs that have check box fields as input name/value pairs should define those using a %GLOBAL statement in order to ensure that the variable exists with a null value if the check box is not selected. Note that the macro variable is global only to the Request Executive for this particular execution of the program.
VAR5: weight
The macro variable VAR0, referred to as the Suffix 0 variable, is created to contain the total number of values received. Note that both VAR and VAR1 (referred to as the Suffix 1 variable) have the same value. In a case where a check box is not selected, the browser does not send a blank value for the name and the SAS program must be prepared for such a scenario. In a similar situation, if only the third check box is selected, the Application Dispatcher recognizes only a single value:
VAR: age.
The Application Dispatcher does not know that there could have been multiple values, so it does not create the Suffix 0 (the number of name/value pairs) variable nor does it create the Suffix 1 variable. Thus the program needs to check if the Suffix 0 variable exists to determine if multiple values were passed in. A simple way to check this is to include the Suffix 0 variable in a %GLOBAL statement and then check for a null value. For most situations, it is recommended that the HTML page not use a name more than once. However, there are at least two situations where this is not possible. Note: There are cases where using a name more than once is desired, as in the example given where the check boxes correspond to a variable list. The macro presented in Section 5.2.4.2 provides an example where this is done. First are SELECT tags (i.e., list boxes) that allow multiple selections. The selected values are passed as multiple values for a single name. Thus, if a list box (e.g., lbox) allows for multiple selections and only one selection is made, the value is passed with a name of lbox. If three selections are made, the number of selections is passed as the value of lbox0 and the three values (in no predictable order) are passed as lbox1/lbox, lbox2 and lbox3. Second, are fields where the length of the value can be long, e.g., TEXTAREA tags. Only one value is passed from the browser. The Application Dispatcher treats these as multiple name/value pairs if the value is longer than a specified width. In such cases, multiple macro variables are th created by splitting the value at the first blank before the n character, or at character n if there are no preceding blanks. Note: Application Dispatcher defined fields have names that begin with an underscore (_). Such fields are not split and the entire value is passed as a single name/value pair. By prefixing a program-specific name with an underscore, you ensure that the name/value pair is always passed as a single name/value pair. Care must be taken, however, to choose names that are not already used by the Application Dispatcher (or that may be used in future releases).
70 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Best Practice: Consider using two underscores in program-specific names that should not be split. This avoids conflicts with both current and future Application Dispatcher special names.
The value for n can be specified in a number of ways (the criteria are used in the order listed below and the first one defined is used):
a name/value pair is included using a name of _fldwdth in the request the ServiceFieldWidth parameter defined in the Application Broker configuration file the FieldWidth parameter defined in the Application Broker configuration file th
the string is split at the 32K character (the Version 6 Application Broker splits the string th at the 200 character because character variables are limited to 200 characters in Version 6 of SAS)
The number of values passed is stored in the Suffix 0 variable, a described above. The original HTML names must be chosen with care when new macro variables are created as a result of multiple values. Here are some tips for choosing names.
ensure that the names, once suffixes have been added, are not longer than 32 (in Version 6 this limit is 8).
avoid names that end in numbers. For example, the names LBOX and LBOX1 should not be used in the same HTML form or link because of unavoidable confusion if new numbered macro variables were created as a result of multiple values.
5.2.4.2 Macro Tool to Handle Multiple Names The need to handle name/value pairs where there may be multiple values is a common occurrence. A good way to handle such values is to use a macro tool, instead of including the code in each program. Such a macro, multipleNames, is provided as part of the sample environment. This macro can serve as the basis for such a tool. It handles multiple names by doing several things:
Best Practice: Define and use an autocall macro that is available to the Application Server that handles multiple name/value pairs. Define the autocall location using the sasautos option in the program specified in the REQUEST INIT= parameter.
ensuring that the Suffix 0 variable always exists with the following values:
a value of 0 if the field is not defined (e.g., multiple check boxes with the same name and none selected)
a value of 1 if only one value is defined
ensuring that the Suffix 1 variable always exists and has the same value as the field without the suffix (allowing the program to always refer to the Suffix 1 variable)
allowing for an option to collapse all the values into a single space-delimited field (e.g., if multiple name/value pairs are used for a variable list)
It can be called repeatedly in the same program if, for example, some names are to be collapsed to a single name and some are not. The options for the macro include the following:
the list of parameter names that can potentially have multiple values. a parameter (singleList) that specifies whether the multiple values are to be collapsed into a single space-delimited field. A non-blank value turns this option on.
Chapter 5: Communicating with the Application Dispatcher 71
To see an example of the features of the multipleNames macro, go to the sample environment and select Chapter 5. Then select Demo multipleNames Macro. Try the following combinations (plus others) to determine how to use the maro.
Select no values and note how the macro creates macro variables for both the original name and the Suffix 1 name. That allows the program code to refer to either the original name or the Suffix 1 name. Note how the Suffix 0 variable has a value of 0. When used in the upper bound of a DATA step or macro DO loop, the loop is never be entered.
Select only one value for one or more of the fields and note how the values are set. Again the original name and the Suffix 1 name both exist and have the same value, which means that the Suffix 1 value exists.
Select more than one value. When selecting more than one value, also check the check box to Combine into a single field and note that the variables with the suffixes have each individual value, while the original name, as a result of the macro execution, includes them all as a spacedelimited list. Also use this option with the radio box option to print the SASHELP.CLASS data set.
Figure 5.1 shows the output produced when three check boxes (used to specify the variables to include) are selected from the above link.
Figure 5.1 Output Demonstrating the Use of the multipleNames Macro
72 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Consider the example above where a check box was used for each variable in a data set. If the macro is applied to that variable, your program can do the following:
If it is necessary to loop over the names, then either a macro or DATA step DO loop could be used with the Suffix 0 variable as the upper bound. The looping logic correctly handles the following cases:
no values (the loop is never be entered)
one value since the Suffix 1 variable has the same value as the original variable name
multiple values
Alternatively, if a variable list is needed, then the singleList parameter can be used. In this case, the list is the values of the original name. If looping over the list of variables is still required, those values are also available in the suffix variables. The sample environment provides an option to see the use of the macro to create the variable list in a single macro variable.
5.3 Name/Value Pairs Defined by the Application Broker The Application Broker can define fields that should be passed to the Application Server as if they were provided as HTML name/value fields. There are three different classes of such fields:
Note: _server, the server name as defined in the Application Broker configuration file, and _port, the port the current Application Server is listening on, are also passed as name/value pairs to the Application Server.
5.3.1 Application Broker Administrative Fields The following fields are created by the Application Broker (defined in the Application Broker configuration file), and the values can be customized by editing the Application Broker configuration file:
_ADMAIL contains the e-mail address of an administrator. A global value (defined in the AdministratorMail directive) can be provided as well as service-specific values (defined in the ServiceAdminMail directive). The global value is used only when no servicespecific value is defined. One example use of this value is when the requested program needs to generate a MAILTO tag.
_ADMIN corresponds with _ADMAIL and contains the name of the administrator (set in the Administrator and ServiceAdmin statements). Note: If the statements for both the global and service-specific values are commented out, the name/value pairs are not defined.
Chapter 5: Communicating with the Application Dispatcher 73
_URL Best Practice: Use the macro variable reference the URL for the Application Broker &_url in programs that need to generate links or component of the Application Dispatcher. forms. The value should never be hardcoded. The Application Broker determines this Using the macro variable reference minimizes value dynamically. The SelfURL directive the changes needed if the location changes. in the configuration file provides a facility to define an alternative value. Typically the value determined by the Application Broker is correct and the SelfURL directive is not needed.
_VERSION an internal version number for the Application Broker component of the Application Dispatcher. It cannot be updated locally and is typically not used.
5.3.2 Environment Variables Environment variables can also be made available to Application Dispatcher programs. The values of these variables (also known as Web server environment variables) can be made available using an Export directive in the Application Broker configuration file. Here is the syntax: Export environment-variable-name sas-macro-variable-name The Application Broker configuration file contains a number of Export statements. However many of them are commented out. To see this example, go to the sample environment and select Chapter 5. Then select Show Available Environment Variables, which shows all the environment variables accessible by the Application Broker (i.e., _debug=16384), and select Show Application Broker Fields, which shows the list of values being exported by the Application Broker (i.e., _debug=1). These fields can be used to address common requirements. Two fields that are often exported are REMOTE_USER and SERVER_NAME. The default macro variable names for these, as defined in the Application Broker configuration file, are _RMTUSER and _SRVNAME. A Best Practice was suggested in Section 5.3.1: always use the macro variable reference &_url when a program needs to build a link or a form that executes another Application Dispatcher program. Quite often, it is necessary when building such links to have the complete path, starting with the protocol (e.g., http). The information needed to do that is available from the following server variables:
SERVER_PROTOCOL (e.g., http or https)
SERVER_PORT (typically 80) SERVER_NAME
Best Practice: Define and use an autocall macro that is available to the Application Server that builds the complete name for the Broker, including the protocol, port, and server name.
The macro code provided with the sample environment, completeBrokerName, builds such a string using the exported values for the above fields. The macro can be demonstrated by a program that contains the following: %put %completeBrokerName;
To see the results of the %PUT statement, go to the sample environment and select Chapter 5. Then select Demo completeBrokerName Macro, which includes _debug=128 to cause the results (e.g., the SAS log) to be returned to the browser. Figure 5.2 shows the output produced by this macro.
74 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 5.2 SAS Log Output of Sample completeBrokerName Macro Call
5.3.3 Installation Dependent Fields In addition to the values of Web server environment fields, there are quite often other values that programs need to reference. Some examples might include the following:
location of a style sheet that should be used by all generated output directory path for utility graphics (e.g., arrows, folders, buttons) contact person
Instead of hardcoding these in programs, specify them in the Application Broker configuration file using either the Set or ServiceSet directive. Here is the syntax: Set name value ServiceSet name value Tip: Such fields can also be defined as macro variables using %LET statements in the Application Server REQUEST INIT program. This might be appropriate for values that are specific to the Application Server (as opposed to the Web server). If a Set directive is used, the name/value pair is generated by the Application Broker and passed to all services. If a ServiceSet directive is used, the name/value pair is generated by the Application Broker and passed to only the specific service. The default installation of SAS/IntrNet includes several such parameters that are used by SAS/IntrNet samples and applications: Best Practice: Use SET statements for global type _mrvimg: the directory that parameters (e.g., the corporate style sheet) and contains the images used by the ServiceSet statements for parameters that are specific to a service (e.g., a contact person for the MDDB Report Viewer service or application). _grfaplt: the complete path for the graph applet
_grafloc: the directory that contains the SAS/GRAPH applets
These parameters have default values, but can be changed by a site as desired by editing the Application Broker configuration file. Note that if multiple values are defined (e.g., two SET statements for the same name, or both a SET and ServiceSet statement for the same name), multiple values are created by the broker using the rules as discussed in Section 5.2.4.1 with the values defined in SET statements defined as the Suffix 1 values.
Chapter 5: Communicating with the Application Dispatcher 75
As a security precaution, fields that are defined in the Application Broker using any of the following take priority over any value defined in the URL:
Export Set ServiceSet
This prevents a user from, for example, spoofing who they are by providing a value for _rmtuser. To see this example, go to the sample environment and select Chapter 5. Then select Spoofing _RMTUSER, which uses a URL like this: http://server-name/scripts/broker.exe?_debug=9&_service=appdisp&_rmtuser=Iam-the-Boss
Even if authentication is not turned on, the first value passed to the Application Server for _RMTUSER is a null value, as the Web server environment variable is null. The relevant part of the output is shown in Figure 5.3. Note how the spoofed value is shown in the Suffix 2 variable, not in _RMTUSER.
Figure 5.3 Attempt (Failed) to Spoof the Value of _RMTUSER
Note: The SAS Process Server provides a facility to provide default values that are used if no value is defined in the URL or form. The Application Dispatcher does not include such a facility. Each program must add logic to assign default values. Best Practice: Use the macro setDefaultValue, which is provided with the sample environment, to facilitate assigning default values. Call the macro and specify the name and the default value. Select Demo setDefaultValue Macro (see Figure 5.4), which provides an example that shows its use, in combination with the multipleNames macro to create a single list containing all the variables whose check boxes were selected, with a default value of _ALL_ if no check boxes were selected.
Figure 5.4 Sample Use of the setDefaultValue Macro
76 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
5.4 Name/Value Pairs Defined by the Application Server The Application Server also creates name/value pairs that can be referenced by a program. To see this example, go to the sample environment and select Chapter 5. Then select Show all the Name/Value Pairs Available in the Request Executive - No Sessions, which shows all the available name/value pairs with no sessions. Select Show all the Name/Value Pairs Available in the Request Executive - With Sessions, which shows the available name/value pairs when a session has been created. In order to identify the fields that are created by the Application Server it is necessary to disregard fields that were created by the user request or the Application Broker. A value of 1 is included in _debug so the name/value pairs passed from the Application Broker can be compared with the ODS output of all the available macro variables. A portion of the output is shown in Figures 5.5 and 5.6.
Figure 5.5 Partial Listing of Name/Value Pairs—No Sessions
Chapter 5: Communicating with the Application Dispatcher 77
Figure 5.6 Partial Listing of Name/Value Pairs—With Sessions
The fields can be grouped into several categories. The following fields are more generally used:
The value of _program (the currently executing program) parsed into its components:
Best Practice: Use the macro, programName, provided with the sample environment to build a program name that can point to another program in the same library (or to the same program in another library).
_pgmlib: the library
_pgmcat: the name of the SAS catalog. This field has a null value if an external file (e.g., a .sas program) is being executed
_pgm: the name of the actual program in the directory or catalog
_pgmtype: the type of program
To see an example of the Best Practice, go to the sample environment and select Chapter 5. Then select Demo programName Macros. The results are shown in Figure 5.7.
78 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 5.7 Sample Use of the programName Macro
Fields that define which Application Server is processing the request:
_thissrv: a string that can be used instead of _url when building a link. It contains the values for _url, _service, _server and _port. When this value is used such links are always submitted to the same Application Server, even if the service has multiple Application Servers defined for it. Therefore, it should be used only when that is appropriate. The inclusion of _server and _port prevents the Application Broker and Load Manager from selecting which Application Server to use. Note: The field _thissrv should be used with care. It is not available in the SAS Process Server and even in the Application Server its use is less reliable than using the individual fields.
_replay: a complete link which is used to invoke the utility REPLAY program. The REPLAY program is used to replay a catalog entry such as a graph. It is used by ODS.
_tmpcat: the name of a temporary catalog in the APSWORK library that can be used during the current request. The catalog is not created until the executing program references it to create an entry.
Fields that define the session being used or that are updated to reflect the current session. These fields point back to a particular session for an Application Server:
_replay: a complete link which is used to invoke the utility REPLAY program. This macro variable is updated when a user session is created. The REPLAY program is typically used to replay an entry that is stored in a catalog (e.g., in the catalog referenced by the macro variable _tmpcat).
_thissession: a string that can be used instead of _url when building a link. It is the value of _thissrv with the session (i.e., _sessionid) included.
_sessionid: the unique identifier for the particular session. This field is created only by the Application Server when the session is first created. In later requests, it is passed in from the user request.
_tmpcat: the name of a temporary catalog in the SAVE library that can be accessed by any request in the session. The catalog is not created until the executing program references it to create an entry. This catalog also exists when no sessions are involved. Note that it is located in the APSWORK library when there is no session or when the session is a lightweight session created by ODS.
A field called _apslist is also created and is available as a macro variable. It is a comma-separated list of all the other macro variables created by the Application Dispatcher and is available in the Request Executive.
Methods You Can Use to Access and Reference Input Parameters 81
Chapter
7
Various Techniques to Generate HTML 93
Chapter
8
Creating Pages with Mixed and Alternative Content Types 131
Chapter
9
Using REQUEST INIT and REQUEST TERM to Specify Set-up and Shut-down Behavior 155
Chapter 10
How to Create and Use Sessions 165
Part 3 discusses techniques and examples illustrating the features and capabilities of the SAS/IntrNet Application Dispatcher. A variety of tools and best practices are provided. Many of ® these techniques apply to the SAS 9 SAS Stored Process server as well. Chapter 6 provides a basic overview of how a program can access or reference the parameters (i.e., the name/value pairs) passed to the Application Server and extends some of the concepts presented in Chapter 5. Chapter 7 discusses a variety of techniques that can be used to generate HTML with a particular emphasis on the quoting issues that surround HTML generation. A single example application is used throughout the chapter: paging through a SAS data set displaying only a set number of observations at a time. A number of tools and techniques are presented to facilitate generating HTML. Many of these are used throughout the remainder of the book. The chapter concludes with
80 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
a SAS Server Page application that can be used to page through any data set, allowing the user to select the library, the member in that library, and the variables to include. Chapter 8 provides a discussion of generating output other than HTML (e.g., PDF, RTF, Excel) as well as output with mixed types (e.g., HTML text and images). Tools to facilitate generating other content types are provided with the examples. Chapter 9 provides an overview of the facility to define programs that are run before and after each request submitted to an Application Server. Using this facility (running specified programs before and after any request) to address common application needs is shown through examples. Chapter 10 discusses sessions from an abstract perspective. It describes how they work as well as some common problems encountered with trying to use sessions. A variety of tools and techniques that make using sessions easier are presented. Chapters 9 and 10 include material that discusses how the Application Dispatcher works. These two chapters are included in Part 3 instead of Part 2 so the discussion can leverage some of the techniques presented in Part 3. You may wish to briefly review these chapters after reading Part 2.
C h a p t e r
6
Methods You Can Use to Access and Reference Input Parameters 6.1 Introduction 81 6.2 Accessing Parameters as Macro Variables 82 6.2.1 Using and Referencing the Multiple Values for a Single Parameter (the Suffix Variables) 85 6.2.2 Using the APPSRV_UNSAFE Function 87 6.3 Accessing Parameters in SCL Programs 91
6.1 Introduction Recall from Chapter 5 that name/value pairs from a request are made available to the SAS program to be run as macro variables. The Application Dispatcher creates these variables, assigns their values, runs the program, and clears the values after the program has run. Name/value pairs are also available in programs that are SCL entries, through an SCL list which is an input parameter to the SCL program.
82 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
These parameter values can be accessed in any of the following ways: as macro variable references the DATA step SYMGET function the SUPERQ macro function the APPSRV_UNSAFE function In SCL entries, the SCL SYMGETN, SYMGETC, GETNITEMC, and GETITEMC functions can also be used to access the values.
6.2 Accessing Parameters as Macro Variables For parameters whose values are used to fill in values in the program (e.g., data set names, values to subset in a WHERE clause) access the value of a macro variable by simply referencing it. For example, consider an HTML page (see Figure 6.1) that prompts the user for both the name of a data set as well as a value to subset the data on (state).
Figure 6.1 Sample HTML Input Form
In this example, the values could be referenced with the following code: proc print data=&data; title “Print of &data for &state”; where state = “&state”; run;
Note: Macro variable references within single quotes do not resolve. If you must quote macro variable references, use double quotes. You can also use the SUPERQ macro function to substitute the value of a macro variable into code: proc print data=%superq(data); title “Print of %superq(data) for %super(state)”; where state = “%superq(state)”; run;
Chapter 6: Methods You Can Use to Access and Reference Input Parameters 83
The argument that you use with the SUPERQ function is the macro variable name, not a macro variable reference. Use the SUPERQ function whenever its value could contain values that might need macro quoting. For example, if the value is to be used in macro logic, use this form of the argument: %if &state = NC %then
. . .
In this example, if the value for the macro variable state is NE or OR, the reference causes a macro syntax error since the macro processor interprets the values NE and OR as operators and not as the values (Nebraska and Oregon, respectively) to be compared. To handle a situation like this, use the SUPERQ function (or other macro quoting functions): %if %superq(state) = NC %then
. . .
Note: Macro variable references, including quoting such references, are beyond the scope of this book. For more information on macro variable references, see support.sas.com/pubs for a list of current titles such as SAS Macro Language Reference. When the parameter values appear in a DATA step, you can often use the SYMGET function if you don’t need the value until the DATA step execution time. Consider the following data entry example, shown in Figure 6.2, where a comment field is captured.
Figure 6.2 Sample HTML Input Form Including a Free-Form Text Entry
Each of the following assignment statements results in a DATA step character userComment variable having the value entered for Comment on the HTML form: userComment = “&Comment”; userComment = “%superq(Comment)”; userComment = symget(‘Comment); Note: The DATA step compiler reads the first two references as an assignment of character literals. If this is the first reference to the variable name, the length of the variable is defined to be the length of the value. For the SYMGET and APPSRV_UNSAFE functions, the length will default to character 200.
84 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
All three statements assign the value of the specified parameter to the DATA step variable called userComment. These three methods assume that the value does not contain certain specified special characters (something that is not likely to be true for a comment field). As a security measure, the Application Server strips characters defined by the UNSAFE option on PROC APPSRV from the value. Here is a list of the default characters that were removed, along with the rationale for removing them: ;
a semicolon, since it can cause a statement to end prematurely;
% a percent sign, since it can be interpreted as triggering a macro call; & an ampersand, since it can be interpreted as triggering a macro variable reference; “
a double quote, since it can end a character literal;
‘
a single quote, since it can also end a character literal
If the unaltered value is required, the APPSRV_UNSAFE function (discussed in Section 6.2.2) can be used as follows: userComment = appsrv_unsafe(‘Comment’);
Best Practice: Do not remove any of the characters from the default unsafe list. Consider what would happen with the following simple program: proc print data=&data; title “&title”; run;
if a hostile user entered this value for title: gotcha”;proc delete data=&data;*
the following code would be executed: proc print data=&data; title “gotcha”; proc delete data=&data; *”; run;
The data set would be printed with a title of “gotcha” and would then be deleted. With the unsafe characters removed, the following code would be run: proc print data=&data; title “gotchaproc delete data=data*”; run;
which prints the data using a TITLE statement that does no damage.
Chapter 6: Methods You Can Use to Access and Reference Input Parameters 85
Because these characters are removed from user input values, it is usually safe to use macro variable references, e.g., &userComment, that allow the SAS word scanner to process them as code in Application Dispatcher programs (for Version 8 and later). ®
Note: The SAS 9 Stored Process Server does not remove these special characters. Instead, it uses macro quoting to hide the value. The unquoted values are returned by the APPSRV_UNSAFE function. If the APPSRV_UNSAFE function is used to get the value of userComment seen in Figure 6.2, the apostrophe (single quote) is included in the value (i.e., the value is It’s up to the author ☺). If either SYMGET or a macro variable reference is used, the value retrieved will not include the apostrophe (single quote) (i.e., the value is Its up to the author ☺) If you need to assign values to a numeric DATA step variable, it’s simplest use a macro variable reference. Suppose that in addition to prompting for the Comment field, the HTML form also prompts for Rank: Rank = &Rank;
Using a macro variable reference is reasonably safe if it can be assumed that only numeric values can be provided for Rank (e.g., the value comes from an HTML radio box or select tag, or the value has been validated using JavaScript). Alternatively, the SYMGET function, combined with the INPUT function, can be used: Rank = input(symget('Rank'),8.);
Using the SYMGET and INPUT functions enables you to perform additional editing to the value and also protects the program from hostile users as described in Best Practice above (since the value is not inserted into the program as text).
6.2.1 Using and Referencing the Multiple Values for a Single Parameter (the Suffix Variables) Section 5.2.4.2 discussed how HTML name/value pairs may result in the creation of multiple values for a single parameter name. The multipleNames macro was provided as a tool to help deal with the nuances of such situations. Note: If the multipleNames macro is not used, the Suffix 0 and the Suffix 1 variable will exist only if two or more values are passed from the user request. By forcing them to exist, you can use the looping constructs described below regardless of how many values are created by the user request. Here are some features of the multipleNames macro: Ensures that the Suffix 0 variable always exists with the following conditions:
A value of 0 if the field is not defined.
A value of 1 if only one value is defined.
Ensures that the Suffix 1 variable always exists and has the same value as the field without the suffix (allowing the program to always refer to the Suffix 1 variable). Provides an option to collapse all the values into a single space-delimited field.
86 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Note: The macro can be easily extended to create a space-delimited list of quoted values. Such a list could be used to construct a WHERE clause from a list of selected values. Consider the example HTML form shown in Figure 6.3 that allows the user to select variables using check boxes.
Figure 6.3 HTML Form Showing Multiple Selections Using Check Boxes
For such cases where the name/value pairs that can have either no or multiple values, you can use any of the following methods to reference the values: A DATA step DO loop with the SYMGET (or APPSRV_UNSAFE) function do i = 1 to &var0; variable (or array) = symget(‘VAR’||left(put(i,5.))); ….. other statements end;
If the multipleNames macro has been used, &Var0 always resolves to the number of values passed in (including 0 if none are). Both &Var1 and &Var are also defined, allowing either to be used. The above loop accesses all the values. A macro %DO loop using either macro variable references or the SUPERQ function %do i = 1 %to &var0; &&var&i other macro (or data step) logic %end; or %do i = 1 %to &var0; %superq(var&i) other macro (or data step) logic %end;
Note: The reference &&var&i within a loop is a commonly used macro construct (delayed resolution) when you want to reference &Var1, then &Var2, and so on. Processing from left to right, the rule is that && becomes an &, any text (e.g., “var”) is carried along, then &i resolves to 1 (or 2, or 3, . . . ). The result is that &Var1 (or &Var2) gives the desired behavior.
Chapter 6: Methods You Can Use to Access and Reference Input Parameters 87
Note: Since the argument to the SUPERQ function is the macro name, it is only necessary to construct a reference to the macro name, var&i (i.e., delayed resolution is not required). Since it’s simpler to construct such references, using the SUPERQ function may be desirable. If the values are to be used as a space-delimited list, the multipleNames macro can be used to provide a macro variable which can be referenced in order to return the whole list. To see this example, go to the sample environment and select Chapter 6. Then select Collapsing a list of names into a single reference. This link uses an _debug value of 129 (= 1 + 128) to show the name/value pairs created by the Application Broker for the multiple values chosen for Var. You can also see the SAS log that shows the output from %PUT statements used to write the values for all the Var suffix variables. Figure 6.4 shows the output of the %PUT statements when all five variables are selected. Note that the multipleNames macro was called with the option to update the original variable (e.g., Var) to contain all the values as a space-delimited list.
6.2.2 Using the APPSRV_UNSAFE Function The APPSRV_UNSAFE function can be used whenever the original input value is needed and unsafe characters are expected or allowed to be part of the value, e.g., when the value is a last name such as O’Conner. The function should be used with great care however: the program should make sure to access or reference the value in a way that does not permit the problem highlighted in the Best Practice mentioned in Section 6.2. The APPSRV_UNSAFE function can be used in both the DATA step and in SCL. In such cases if the returned value is data as opposed to SAS code the adverse effects of using the value are minimized. The APPSRV_UNSAFE function can also be used with the %sysfunc (or %qsysfunc) macro functions to reference the value as a snippet of SAS code. Consider two examples where the user is prompted for a title for their output as well as the name of a person which should be used in a WHERE clause. title “%sysfunc(appsrv_unsafe(title))”; or title “%qsysfunc(appsrv_unsafe(title))”;
Generate a TITLE statement whose value is the value of the name/value pair title. As mentioned in the Best Practice above, this usage can permit security issues to occur. where name = “%sysfunc(appsrv_unsafe(name))”; or where name = “%qsysfunc(appsrv_unsafe(name))”;
The value of the name/value pair name is used to generate a WHERE clause.
88 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
In both of these cases, the values with the unsafe characters included are required. However, there are ways to meet the requirements (e.g., a user-specified TITLE or WHERE clause) without requiring the values to be included in the job Best Practice: Whenever possible use SAS stream as code. Consider the two examples functions in the DATA step or SCL instead of above. For the WHERE clause example, the referencing the original value (before the unsafe statement can be coded so that the value for the characters are removed) in SAS code. name/value pair is not seen by the SAS word scanner at all: where name = appsrv_unsafe(‘NAME’);
This usage (in a DATA step) prevents the SAS word scanner from seeing or processing the value of the macro variable name because the macro variable reference is processed once during the compilation of the DATA step. The APPSRV_ UNSAFE function is used as an execution time function and may be executed respectedly (e.g., for each observation). For the example where the title is passed in, SAS functions can be used to directly use the value instead of letting the SAS word scanner see the value. The SETTITLE SCL function can do this. Unfortunately this function cannot be used in the DATA step. But a very simple SCL program can be used: init: call settitle(1,appsrv_unsafe('title')); return;
This program can then be executed in any SAS program via the DISPLAY procedure: proc display c=library.catalog.entry.scl; run;
See the member setttitle.scl contained in the Chapter 6 catalog of the sample environment. Note: This example can also be implemented using the %qsysfunc macro function, e.g., Title “%qsysfunc(appsrv_unsafe(title))”;
For cases where the %qsysfunc macro function is not an option, the use of simple SCL programs and tools should be considered. This example illustrated a technique to prevent the SAS word scanner from seeing the values. To see this example, go to the sample environment and select Chapter 6. Then select Special Characters in Titles. Figure 6.5 shows the output produced when the value for Title includes the unsafe characters.
Figure 6.5 PROC PRINT Output with Unsafe Characters in a Title
Chapter 6: Methods You Can Use to Access and Reference Input Parameters 89
6.2.2.1 Using APPSRV_UNSAFE to Run User-Specified Code Recall that the semicolon is one of the special characters that is removed. That is why a user cannot pass any arbitrary SAS statements to the Application Server for execution. However, if you use the APPSRV_UNSAFE function you can create a program which executes any specified user code. To see this example, go to the sample environment and select Chapter 6. Then select Run User Defined Code. A text area HTML field (called line) is defined to allow the user to enter any arbitrary SAS statements. The following SAS program is executed and uses the APPSRV_UNSAFE function as the call execute argument to retrieve the original values and execute them as SAS code, with the unsafe characters (e.g., the semicolon (;), the percent sign (%), the ampersand (&), etc.) included: %global ods; %multipleNames(names=line) data _null_; /* if ODS parameter set, generate an ODS statement */ if "&ods" ne " " then call execute('ods html file=_webout style=sasweb;'); call execute(appsrv_unsafe('line')); /* loop thru the others submitted lines */ do i = 2 to &line0; call execute(appsrv_unsafe(trim('line'||left(put(i,4.))))); end; /* close ODS if the parameter was set */ if "&ods" ne " " then call execute('ods html close;'); stop; run;
The first value cannot be referenced as line1 since line1 might have been created by the multipleNames macro. If so, APPSRV_UNSAFE returns a value without the unsafe characters, as they were not included when line1 was created from line. See Figure 6.6 for an example HTML page that allows the user to enter code to be run. Figure 6.7 shows the output produced by the code shown in Figure 6.6.
90 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
Figure 6.6 Sample HTML Interface Allowing User to Enter SAS Code
Figure 6.7 Output Produced from User-Entered SAS Code
Chapter 6: Methods You Can Use to Access and Reference Input Parameters 91
Providing such functionality can compromise security because it allows the user to run any arbitrary code. The example provided with this book is for illustrative or academic purposes only and is stored in a separate catalog from the other examples in order to isolate this functionality. The catalog containing this program should be defined only in a PROGLIBS or ADMINLIBS statement with great care. In the sample environment, this catalog is defined in an ADMINLIBS statement. The HTML form requires that the Application Server password, as discussed in Sections 4.5.2.4 and 4.6, be entered in order to execute the code.
6.3 Accessing Parameters in SCL Programs If your program is written in SCL, another method is available for referencing or accessing the variable values. An SCL list is passed to an Application Dispatcher program written in SCL. Such SCL programs contain the following statement: entry inputlist 8;
This list contains named character items that correspond to the name/value pairs. SCL programs can use either this input list or the macro variables. For example, you could use this statement to access value for the name of the input data set: data=getnitemc(inputlist,'DATA',1,1,' ');
Note: The GETNITEMN function (for numeric list items) produces an error message, because all the items are inserted as character values. The Application Server cannot infer the type from the current value. It is the responsibility of the program to know when or if to convert list items to numeric values. The arguments specify that the value to be returned is the first value provided for DATA, with a default of blank (the fifth argument) if no value is provided. As with the macro variables, this SCL list is cleaned up by the Application Server when the Application Dispatcher program has run. Once the value is available as an SCL variable, it can be used in SCL functions for additional validation. Here is an example: data_exists = exist(data); if not data_exists then . . . . . . .
Note: The SCL EXIST function can also be used in the DATA step, or you can use a %sysfunc macro call to perform such validation. The value that is retrieved from the list has the unsafe characters removed. If the program needs to get the values, including those characters, you can use the APPSRV_UNSAFE function. data = appsrv_unsafe(‘DATA’);
Note: If the SCL entry uses the macro variables to retrieve the values instead of accessing them from the SCL list, it is possible to access (and change) the macro variable values in the entry defined by the REQUEST INIT statement.
92 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
The values can also be retrieved from the macro variables using the SYMGETC, SYMGETN or SYMGET functions, e.g.: data = symget(‘DATA’); data_exists = exist(data); if not data_exists then . . . . . .
When an SCL program includes a reference to a variable prefixed with an ampersand, the context of the reference is important in determining how the value is resolved. An SCL program can submit statements to SAS for execution using a submit block. Consider the following example: submit [options]; proc print data=&data; title “Print of &data” for &state”; where state = “&state”; run; endsubmit;
If SCL variables data and state exist, the values of the SCL variables are substituted for the & references in the above submit block. If there are no SCL variables that correspond to the & references in the submit block, the code is submitted to SAS and the SAS word scanner will handle them as macro variable references. Note that if SCL programmers want to make sure that any & references are always passed to the SAS word scanner for resolution as macro variables, they should reference them using two ampersands (e.g., &&data) in the submit block. For more information on SCL, including examples, see support.sas.com/pubs for a list of titles. References to macro or SCL variables in a submit block should not be confused with such references in SCL code itself where the value is resolved when the SCL program is compiled. For example, in the following SCL statement, the value of the macro variable password is resolved at compile time: If password = “&password” then
. . .
The value of an SCL variable password is compared to a literal value corresponding to how &password was resolved when the SCL program was compiled; it is not compared to the value passed to the SCL program from the user’s browser. See Section 12.2.2 for an example that illustrates how macro variables can be resolved when compiling SCL programs.
C h a p t e r
7
Various Techniques to Generate HTML 7.1 Introduction 94 7.1.1 The Problem with Generating Valid HTML 95 7.2 Simple PUT and FILE Statements 96 7.2.1 The generateFormTag and generateInputTag Sample Macros 101 7.3 Extending the Output Delivery System 102 7.3.1 FORM Tags Via TITLE and FOOTNOTE Statements 102 7.3.2 Character Variables with HTML Form Text 105 7.4 SCL Submit Blocks 107 7.5 Including Static HTML from External Sources 110 7.5.1 A Macro Tool to Include External HTML 114 7.6 SAS Server Pages 116 7.6.1 The SAS Server Page Macro 116 7.6.2 Sample Server Page: List Libraries 118 7.6.3 A Macro to Generate Data-Driven SELECT Tags 119 7.6.4 Sample Server Page: List the Data Sets in the Selected Library 121 7.6.5 Sample Server Page: List the Variables in the Selected Data Set 122 7.6.6 A Macro to Generate Checkboxes for Variables in a SAS Data Set 124 7.6.7 A Program to Page Through the Selected Data Set 125 7.7 SAS Design-Time Controls 127
94 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
7.1 Introduction You can use numerous techniques to generate HTML. The range of techniques includes using simple PUT and FILE statements, using the ODS facility, using and customizing HTML templates, and using macro tools. These techniques are illustrated by a common example: paging through a SAS data set. The basic program uses the PRINT procedure and the Output Delivery System (ODS), directing the output to the requestor’s browser by using the reserved fileref _webout. To run the example in this section, go to the sample environment and select Chapter 7. Then select Base Program. %setDefaultValue(firstobs,1) %setDefaultValue(atATime,5) %setDefaultValue(data,sashelp.class) %let obs = %eval(&firstobs + &atATime - 1); ods listing close; /* no listing output*/ ods html file = _webout (title="Base Program") style=sasweb; proc print data = &data(firstobs=&firstobs obs=&obs); X title “Observations &firstobs-&obs of &data”; run; ods html close;
X In order to add a paging facility, the firstobs and obs SAS options are used to specify what observations to display. The setDefaultValues macro presented in Section 5.3 is used to provide values if they are not provided by the requesting HTML page (or link). Figure 7.1 shows the output produced by selecting the above link.
Figure 7.1 Sample PROC PRINT Output
Chapter 7: Various Techniques to Generate HTML 95
This program will be enhanced and extended by generating additional HTML that includes an HTML form to allow paging through the data set. Here are the form fields:
the required fields (e.g., _service, _program, etc.) for any Application Server request data – the name of the data set to page through (a hidden field) atATime – the number of observations to display (a hidden field) firstobs – the first observation to display (a radio button field for the previous or next
page)
a Submit button
7.1.1 The Problem with Generating Valid HTML Generating valid HTML can be complicated by the fact that both SAS and HTML require strings to be quoted. For HTML, the double quote (“) character is used. For SAS, either a single (‘) or double quote (“) can be used. In addition, SAS uses the ampersand (&) as a trigger to indicate that the next word or token should be interpreted as a macro variable reference. However, in HTML, the & is interpreted as the separator character for name/value pairs in links and as the indicator for HTML character entities (e.g., - a non-breakable space). For example, the following HTML string invokes the Application Dispatcher to execute a program and pass the values A and B as the values for parameters one and two: http://server-name/scripts/broker.exe?_program=a.b.c.source&one=A&two=B
When SAS sees this string, depending on how the values are quoted, SAS might attempt to resolve &one and &two as macro variable references instead of allowing the &s to remain as the HTML separator characters. In these cases, SAS does not produce the desired results. The solution is to use single quotes. However, there are typically cases where the desired values for name/value pairs are macro variable references, e.g., if the generated URL is to include the value of _debug. The value of _debug to be used is the value of the macro variable reference &_debug. In the following URL string, the second reference to &_debug is to a macro variable reference, while the first one should be treated as a character literal: &_url?_program=a.b.c.source&_debug=&_debug&one=A&two=B
In this case, &_url should be resolved, and the first &_debug reference is to be taken literally: the generated text should be the text &_debug. However, the second reference should be resolved by the macro processor. The first reference must be single quoted in SAS to prevent macro resolution, while the second reference must be double quoted to allow resolution. These two are in conflict. Now consider another type of HMTL string for a FORM tag field in the following example.
Here we want some value to resolve from the macro variable reference &_debug. This would mandate that we use double quotes to quote this string; yet this is at conflict with the requirement that the quoted string include embedded double quotes. The following sections introduce techniques to address these issues. Although the examples have been coded to illustrate the various techniques, you should adopt a consistent approach when implementing an application; i.e., use a single technique consistently.
96 Building Web Applications with SAS/IntrNet: A Guide to the Application Dispatcher
7.2 Simple PUT and FILE Statements The following DATA step illustrates the use of PUT and FILE statements to generate HTML content (specifically the form controls to enable paging through the data set). This DATA step is included after the PROC PRINT step described in Section 7.1, and it augments the HTML generated by ODS. Figure 7.2 shows the resulting output. To run the example in this section, go to the sample environment and select Chapter 7. Then select Simple PUT/FILE Example.
Figure 7.2 PROC PRINT Output with Paging Controls Generated with PUT and FILE Statements
data _null_; length string $256; file _webout; /* get the number of observations */ if 0 then set &data nobs=nobs; put '