***  This package contains classes that provide Binary Compatibility only, not Source Compatibility  ***

Note:
Extension of the classes in this package is prohibited unless otherwise documented. Similarly, extension or implementation of the interfaces in this package is prohibited except as documented.

Package com.sas.services.storedprocess

Execute stored processes.

See:
          Description

Interface Summary
Execution2Interface This interface describes various aspects associated with the execution of a stored process.
ExecutionBaseInterface This interface describes various common aspects associated with the execution of a stored process.
ExecutionInterface Deprecated. Use Execution2Interface instead.
ExecutionStatusListener2Interface This interface is implemented by clients who need to be notified of stored process execution status changes.
ExecutionStatusListenerInterface Deprecated. Use ExecutionStatusListener2Interface instead.
OutputParameterInterface This interface describes an output parameter.
StoredProcess2Interface This interface describes the second generation of the stored process service object.
StoredProcessBaseInterface This interface describes various common aspects of the stored process service object.
StoredProcessInterface Deprecated. Use StoredProcess2Interface instead.
StoredProcessServiceInterface This interface describes a stored process service.
 

Class Summary
GenericStream Describes a GenericStream data source or target.
PermanentPackageResultHints Deprecated.  
ResultHints Deprecated.  
SASLog A collection of SAS log or listing lines.
StoredProcessServiceFactory Factory used to manufacture a stored process service.
StoredProcessServiceProxy Stored Process service proxy.
TransientPackageResultHints Deprecated.  
WebDAVPackageDAVServerResultHints Deprecated.  
WebDAVPackagePRResultHints Deprecated.  
WebDAVPackageURLResultHints Deprecated.  
XMLStream Describes a XMLStream data source or target.
 

 

Exception Summary
AlertProcessingException This class describes exceptions thrown while creating and updating the StoredProcessAlert item and may wrap an underlying exception
ExecutionException This base class describes exceptions thrown when StoredProcessInterface.execute() or StoredProcess2Interface.execute() is invoked.
ExecutionStatusListenerException This class wraps exceptions thrown while invoking methods in the user supplied listener.
InvalidParameterValueException This exception is thrown when a parameter has a non-conforming value.
MissingParameterException This exception is thrown when a required parameter has not been assigned a value.
ResultsBindingException This class wraps exceptions thrown when trying to bind to the results.
SASServerException This class wraps exceptions thrown while accessing the SAS Server.
SessionNotAvailableException This exception is thrown when the StoredProcessService knows about the session described in the message, but you are supplying the wrong user context.
SessionNotFoundException This exception is thrown when the StoredProcessService cannot find the session described in the message.
 

Package com.sas.services.storedprocess Description

Execute stored processes.

Stored Process Service

Overview

The Stored Process Service enables a client to execute stored processes. A stored process is a SAS language program that is stored on a SAS server or in metadata. Input parameters (name/value pairs) and input data (via a streaming interface, client-side file or client-side data-set) can be passed to the stored process. Output can be returned to the client in a package, via a streaming interface or to a client side file or client-side data-set. Stored processes can also access any SAS data source or external file and create new data sets, files, or other data targets supported by SAS.

Note: The Stored Process Service cannot be used to execute a SAS language program stored on a client.

Model

The Information Service is used to search for and identify stored processes that meet specified criteria. A stored process is then selected for exploitation. Alternatively, the Information Service can be used to access a stored process at a known location in metadata. Input parameters, if present, can be assigned values. For package-capable stored processes, the package location can be specified via input parameters. The locations of input and output tables and filerefs can also be be specified. The stored process can then be executed either synchronously or asynchronously. A package might be generated. If executed asynchronously, streaming input might be provided to the stored process and streaming results might be available during execution. An alert might be created in the Personal Repository to capture the execution of the stored process.

Stored Processes can also be manually created for exploitation though this is not the normal usage pattern: methods are provided to completely specify certain types of stored processes. For more information about manually creating a stored process, see the sample code provided.

The following sections apply to the exploitation of stored processes defined in a SAS Metadata Repository, though some sections are also applicable to manually created stored processes.

Starting the Service

The Stored Process Service is one of the SAS Foundation Services, though not one of the core services. To use it within the Discovery Service framework, the Stored Process Service must be specified in the service deployment being used. No specific configuration information is needed for the Stored Process Service.

At initialization, the Stored Process Service determines whether the Logging Service is available and, if it is, various items related to the use of the Stored Process Service can be logged. Service deployments are typically created using the Foundation Services Manager Plug-in in the SAS Management Console and that plug-in automatically adds a dependency on the Logging Service.

Metadata format changed in 9.2 and 9.3

To provide enhanced capabilities, the format of the metadata describing stored processes was changed in version 9.2 and again in 9.3. As a result there have been various changes to the API, including the creation of new interfaces in 9.2 and the enhancement of those interfaces in 9.3. The version of the stored processes metadata format introduced in 9.2 was version 1 and the version introduced in 9.3 was version 2. Hence 9.2 stored processes are also known as version 1 stored processes and 9.3 stored processes may be called version 2 stored processes. Both version 1 and version 2 stored processes can be present in a 9.3 metadata repository. Summaries of the changes for 9.2 and the changes for 9.3 are available.

Defining a Stored Process

Stored process definitions can be created in a SAS Metadata Repository using the Folder View of the SAS Management Console or by any SAS component that has the ability to create stored process metadata. A design time Java api based on the stored process smart object is provided to programmatically create and modify stored processes.

The Stored Process Service is used to execute stored processes that exist in a SAS Metadata Repository. The typical pattern is to obtain a smart object corresponding to the stored process of interest and then create a service object (in other words, an object that implements StoredProcess2Interface) from the smart object. A StoredProcess2Interface contains all of the information needed to execute a stored process. This includes the location of the stored process program, the server to be used to execute the stored process, any input parameters, and the desired output. Detailed information about that stored process, if needed, can be obtained from the smart object.

A StoredProcess2Interface can also be manually initialized by obtaining an empty object which implements StoredProcess2Interface from the Stored Process Service and then calling various setter methods with appropriate values to create a version 1 stored process, though this is not the anticipated use of the service.

Input Parameters

Stored processes accept input parameters. Input parameters at the stored process (SAS code) level have string names and string values. Input parameters are optionally defined in stored process metadata and might include default values and / or lists of valid values which may be statically specified or dynamically obtained. Values for input parameters can be set programmatically using the setParameterValue() method call.

If defined at the metadata level, input parameters metadata is compatible with that used by the Prompting Framework. The SMC support for defining and modifying stored processes uses a design time component provided by the Prompting Framework and the term input parameters is used interchangably with "prompts". And, since StoredProcess2Interface surfaces a com.sas.prompts.PromptValuesInterface, parameter values can be initialized and modified by components that support the Prompting Framework. An example of such components would be com.sas.prompts.components.webapp.visuals.PromptPropertiesPanel and com.sas.prompts.visuals.swing.PromptPropertiesPanel, which can be used to display a visual so that parameter values can be entered in the servlet and Swing environments respectively.

Parameter Name Case-sensitivity

SAS is not case-sensitive in its treatment of macro variable names. However, the Prompting Framework is case-sensitive. The approach taken by the SMC Folder View is to store macro (prompt) names as is. This means if a name is entered in mixed-case, the name is saved in mixed-case. No normalization is done. However, for the purposes of checking for duplicates, name comparisons are done in a case-insensitive way.

Therefore, at execution time, when a stored process object is instantiated from metadata, parameter names are in the case used to enter them in the SMC Folder View. However, the various flavors of the setParameterValue method function in a case-insensitive way. e.g. if StoredProcess2Interface's setParameterValue() method is invoked, case insensitive comparisons are performed to determine if a parameter of that name exists in the deserialized stored process. If you directly manipulate Prompting Framework objects you need to keep this case-sensitivity issue in mind.

Parameter Value Escaping

Parameter value validation is done by the Service for Version 1 stored processes run on a SAS Workspace Server. The following algorithm is used:

The value is examined to see if there are any unsafe characters such as a percent sign (%), ampersand (&), single quotation mark ('), double quotation marks ("), or semicolon (;). If an unsafe character is present, the character is enclosed by the %NRSTR() macro. If the unsafe character is a percent sign, single quotation mark or double quotation marks then the unsafe character is escaped using a percent sign before being enclosed by a %NRSTR() macro.

Processing similar to that described above is done on the server for all other stored processes.

Dynamic Data Source Parameter Validation

If a parameter is to be constrained to the set of values specified by a dynamic data source, run-time parameter value validation against this data source will be performed provided a data provider is available to the StoredProcess2Interface. The controlling application can make such a data provider available by binding an object which implements com.sas.prompts.DataProviderInterface to the session context using the name com.sas.prompts.DataProviderInterface.DATA_PROVIDER_KEY. When the validatePromptValues() method of StoredProcess2Interface is called, the session context is examined to see if a DataProviderInterface is bound to DataProviderInterface.DATA_PROVIDER_KEY. If a DataProviderInterface is bound, a DynamicPromptValueValidator is constructed using the data provider for value validation; if one is not bound, a DynamicPromptValueValidator is constructed without a data provider and validation against dynamic data sources will not be done.

Supported Servers

A version 2 stored process is associated with a specific Application Server; a version 1 Stored Process is associated with a specific Stored Process Server or a specific Workspace Server. Also, the Workspace Server was enhanced in 9.3 to provide functionality similar to that provided by the Stored Process Server including output parameters and streaming input and output. However, there are two areas where the functionality provided by the two types of servers is different:

Given these differences between the servers and the performance characteristics of each type of server, the writer of the stored process may choose to restrict the execution of the stored process to a certain type of server. If the stored process is not restricted, default behavior of the service for a version 2 stored process is to attempt to first obtain a connection to a Stored Process Server and if that fails (either because no such server is defined in metadata or a connection to the server could not be obtained), an attempt is made to obtain a connection to a Workspace Server.

Version 1 stored processes are directly associated with either a Workspace Server or a Stored Process Server and an attempt is only made to obtain a connection to the server associated with the stored process.

A version 2 stored process can also be designated to run on other Application Servers (in addition to the one specified in metadata). For such stored processes, the setServerContext() method allows the run time specification of the Application Server to be used for execution.

If a client supplies a connection to a pooled Workspace servers, the available feature set is similar to that available on a Workspace server.

Result Capabilities, generated Input Parameters and Result Selection

The Stored Process service provides methods to access certain types of results (packages and streams) if the stored process is defined in metadata to possess those capabilities and if any needed parameters have appropriate values at execution time. StoredProcess2Interface surfaces two methods (isPackageCapable() and isStreamCapable()) which can be used to determine the result capabilities of the stored process. Stored processes defined in metadata possess the capabilities specified in their definition; manually created stored processes are version 1 and are created with package only capability on a Workspace server and with both capabilities (stream and package) on a Stored Process server.

The following section describes the input parameters generated by the service when the execute() method or executeAsynch() method of StoredProcess2Interface is called. It also lists which of these input parameters the client is allowed to set. The combination of client set and service generated values is a set of name-value pairs that are passed, along with other input parameters, to the stored process to be used by the STPBEGIN / STPEND macros and can be ignored if these macros are not used. And, for certain types of packages, additional parameters recognized by the STPBEGIN and STPEND macros can be set by the client (consumer of this API).

The only output parameter relevant to result capabilities is _ARCHIVE_FULLPATH which must be set by the stored process to the path of the archive (the STPBEGIN / STPEND macros, if used, automatically do this) in the case of "PACKAGE_TO_ARCHIVE" on a Stored Process server. On completion of execution, the service uses the value of _ARCHIVE_FULLPATH to bind to the result package.

Redirecting the Output of the Stored Process

As discussed in the previous section, the type of any result (package or stream) and destination (if package) is determined by a combination of the capabilities of the stored process and the presence and values of various parameters. Provided the capabilities permit it the type and destination (if applicable) can be changed by suitable changes to the parameter values. StoredProcess2Interface's setParameterValue() can be used to add a parameter or modify the value of an existing parameter. Alternatively, the parameter hierarchy can be directly manipulated by obtaining a handle to it via StoredProcess2Interface's getPromptValues()

Generated Input Parameters

In addition to the result capability based input parameters described above, the following input parameters are generated by the service:

If the client does set a value on an input parameter which the service would typically set and if the value set by the service is different, the client value will be overridden unless explicitly described otherwise. If overridden, a warning is logged in all cases except _PROGRAM and _METAFOLDER.

Data Sources and Data Targets.

Multiple data sources and data targets are supported and can be defined in metadata. Data sources and data targets are used to model SAS files and SAS datasets.

SAS files:

A file is defined in metadata either as a data source or a data target depending on whether it provides input to or gets output from the stored process. Each such metadata entry has a fileref and the fileref is bound to data at run time in one of two ways. In both ways, the stored process program is written to read from or write to the fileref.
  1. Various flavors of setInputFileref() and setOutputFileref() exist on StoredProcess2Interface to associate the fileref with either a server side location or a client side file. If the file is on the client side the association is done via a client-supplied Reader or InputStream for a data source and a client-supplied Writer or OutputStream for a data target. For input from the client, the content is obtained from the client-supplied Reader or InputStream and copied to a temporary location on the server and the fileref programmatically associated with that temporary file. For output to the client, the fileref is programmatically associated with a temporary location and after the stored process has completed execution, output is copied from that temporary location to the client-supplied OutputStream or Writer.
  2. If none of the setInputFileref() or setOutputFileref() methods is called on a fileref, then the service assumes that the fileref will be handled in streaming fashion by the client using the CACHE access method. The client application is coded to write to OutputStreams (this is input to the SAS stored process) and read from InputStreams (output from the SAS stored process). Execution2Interface provides methods for the client to obtain the InputStream or OutputStream corresponding to the fileref as well as interfaces to access the stream headers, if needed. Data is either a byte stream or in xml format (typically handled by the XML Libname engine). Because input and output can be streamed while the stored process executes, streaming stored processes are normally executed asynchronously.

    Streaming input and output is not supported for version 1 stored processes that run on a Workspace Server but is supported for all other stored processes. This streaming feature is independent of the result capability of the stored process and the stored process should only be marked stream capable if it coded to use that capability. That capability is equivalent to the stored process streaming output to a fileref of name _WEBOUT.

    For data sources, the expected content type specified in metadata is set in the stream headers at the time the stream is constructed using the header property name "HTTP:Content-type". If no expected content type is specified in metadata, the service sets a default value of "text/xml" for XMLStreams and "application/unknown" for GenericStreams. The client can override the value set by the service by invoking the setHeader() method on the corresponding OutputStreamHeaderInterface.

SAS datasets:

A dataset, modeled in metadata as a data table entry, is either a data source or a data target depending on whether it provides input to or gets output from the stored process. Each data table entry has a table parameter name, which should be thought of as a logical name. At run-time, the service associates a two level dataset name for each logical name and generates a macro name-value pair corresponding to the modified table parameter name and the two level dataset name. The table parameter name is modified by prefixing it with "_SOURCE_" or "_TARGET_", depending on whether it is a data source or data target. This results in separate name spaces for source and target table parameter names. As an example, for a table name CARTAB which is a data source and which the client wishes to associate with Sashelp.Cars, the the name-value pair generated by the service at run time would be ("_SOURCE_CARTAB","Sashelp.Cars"). The SAS code would consume this via a statement such as "SET &_SOURCE_CARTAB;".

At run time the actual name of the dataset is associated with the prefix added table parameter name in one of the following ways:

Detailed metadata about the data sources and data targets defined in a stored process can be obtained from the getDataSourcesAndTargets() method of the smart object for those consumers which need this information.

Executing the Stored Process

Executing a stored process creates an Execution2Interface object. This object is a placeholder for the stored process that is executing or has completed execution and contains the execution status and results of the stored process. A single stored process can be executed multiple times; each execution returns a new Execution2Interface.

For stored processes defined by metadata, a connection to the server is obtained by the Stored Process service via the Connection service. However, the client can override this behavior by supplying a connection. A connection based on stored process metadata can be obtained by calling the getConnection() method.

Stored process execution can be synchronous or asynchronous. If synchronous, the execute() method blocks until execution is completed. If asynchronous, the method returns immediately. An execution listener interface is provided to notify the caller when execution starts and completes. Alternatively, the caller can poll the Execution2Interface associated with the execution for a completion status or call one of the waitForCompletion() methods.

After the stored process has completed execution, the consumer can obtain the values of output parameters, test the completion status (the SAS return code), or fetch the SAS log or SAS listing.

Stored processes that run on Workspace Servers can be run synchronously or asynchronously. Stored processes that run on Stored Process Servers that deal with streams (for the reasons noted in Data Sources and Data Targets) are typically executed asynchronously. If the stored process that generates a package is run asynchronously, the package is not available until the stored process has completed execution.

Aborting execution

The execution of a stored process can be interrupted. The execute() method when run synchronously blocks until execution is complete. To be able to abort an executing stored process, the execute() method has to be run asynchronously. The abort() method can then be called on the Execution2Interface returned from the call to execute() when the stored has to be aborted.

Alert Creation

The execution of the stored process can be captured in the MyInbox folder of the Personal Repository by a StoredProcessAlertItemInterface object.

Alerts are described in complete detail later in this document.

Lifecycle Issues

The Execution2Interface is closed with an explicit call to its destroy() method after the client application has completed processing results.

The StoredProcess2Interface is closed with an explicit call to its destroy() method when there is no further need for it. Unless the client intends to re-execute the stored process, there is no further use for this object after the execute method has returned.

Note: The Stored Process service locks the Session Context associated with the stored process for the duration of the execution of the stored process. After execution is complete, it unlocks the Session Context and then attempts to destroy the Session Context. "Best practices" associated with the Session Service for Context sharing require applications which use the Session Context to lock it for the duration of their use, therefore the Stored Process Service's attempt to destroy the Session Context should not affect the controlling application's use of it. If the controlling application does not lock the Session Context, the Stored Process Service will destroy the Session Context and any attempt to retrieve artifacts (e.g. a package which depends on the Session Context) after the execute method has returned may result in errors.

If desired, notification of completion of execution can be provided by installing a listener.

Package Lifecycle

Packages generated by certain package capable stored processes are surfaced by Execution2Interface's getResultPackage() method. The package can be either SAS server based or WebDAV based depending on various prompt settings. Package surfaced by getResultPackage() are automatically closed by Execution2Interface's destroy method.

If there is a need for the package to have a life-span independent of the Execution2Interface, Execution2Interface's setResultPackageLifeCycleBound() method can be used. If this method is used to unbind the life cycle of the package from the Execution2Interface, the Stored Process service copies the package to the mid-tier for SAS server based packages since access to the package is lost once the connection to the server is closed; for WebDAV based packages no such copy is needed and setLifecycleBound() is a directive to the Stored Process service to not close the package when Execution2Interface's destroy method is called. The Usage section contains a code example.

Alerts provide a more permanent mechanism to access a package beyond the life-span of Execution2Interface and the SessionContext session. If the application requires the creation of an alert, "best practices" recommend accessing the package via the alert if access is needed beyond the life-span of Execution2Interface, and not via Execution2Interface's setResultPackageLifeCycleBound() method as described above.

Permissions Issues

The Stored Process Service uses one or more of the following services depending on the usage pattern:

Routines which require specific permissions to run if a security manager is installed that the service calls are:

These methods are called from within "privileged code" in the service. Refer to the documentation for those methods to determine the permissions which need to be given to the CodeSource associated with the Stored Process Service.

Logging and Monitoring

The Stored Process Service uses the Logging Service to log usage under a logging context of "com.sas.services.storedprocess".

The context used for output directed to the SAS Management Console Application Monitor plug-in is "ApplicationMonitor.StoredProcessService".

Locale

The Stored Process follows Foundation services best practices in its locale usage. If a locale needs to be supplied (e.g. when interacting with the prompting framework) one is obtained from the User Service via the UserContext's getLocale() method. When establishing a connection to a Workspace or Stored Process server there is no explicit locale passing to the Connection service as the Connection service also follows Foundation services best practices in its locale handling.

Usage

Code fragments to perform various operations are as follows:

Obtaining a Stored Process for exploitation via the Information Service

Manually Defining a Stored Process

The Stored Process Service is intended to be used to run stored processes described in metadata. Certain circumstances (running a replay stored process with stored process server sessions) warrant the use of manual stored processes and for such usage version 1 stored processes are adequate. There is no need for and hence no way to create a version 2 stored process manually.

Parameter Manipulation

Executing a Stored Process

Package stored process example

The following code sample executes a stored process that produces a package. The stored process accepts two input parameters.

    // The stored process is named "ResultPackageDemo".  Locate this stored process.
    import com.sas.services.storedprocess.metadata.StoredProcessFilter;
    ...
    StoredProcessFilter filter =
       new StoredProcessFilter("Name",
       com.sas.services.information.FilterComponent.EQUALS,
       "ResultPackageDemo");
    java.util.List list = informationService.search(userContext, filter);
    // Assume we have one object returned from the search.
    // Get a Stored Process Service object from the smart object.
    com.sas.services.storedprocess.metadata.StoredProcessInterface
       spSmartObject = (com.sas.services.storedprocess.metadata.StoredProcessInterface)list.get(0);
    com.sas.services.storedprocess.StoredProcess2Interface spi =
       spSmartObject.newServiceObject();
    // Set the values of the two parameters.
    spi.setParameterValue("pyear", "1993");
    spi.setParameterValue("pcountry", "US");
    // We are now ready to execute.
    // The first parameter (true) determines whether the execution is synchronous.
    // The call to execute blocks until the stored process completes.
    com.sas.services.storedprocess.Execution2Interface ei =
       spi.execute(true, null, false, null);
    // In a real case, you would test the status code using
    // ei.getStatus() before proceeding to get the package.
    // You can use the status code to determine whether any
    // additional processing is needed.
    // For example, an application might choose to dump out
    // exceptions / get the SAS log if errors are encountered.
    com.sas.services.publish.ResultPackageInterface rpi = ei.getResultPackage();
    // You can now process the results.
    ...
    rpi.close();
    // Destroy the Stored Process Service objects that are created.
    ei.destroy();
    spi.destroy();
 

Package Lifecycle control:

Package lifetime is discussed here. The following code fragment shown how one can obtain a Package which outlives the Execution2Interface object. The example assumes "storedProcess" contains a reference to a com.sas.services.storedprocess.StoredProcess2Interface service object that has been constructed from metadata.
    ...
    Execution2Interface ei = storedProcess.execute(...);
    // the following call to setResultPackageLifeCycleBound() should be made before a reference 
    // to the result package is obtainted via the getResultPackage() call on Execution2Interface
    ei.setResultPackageLifeCycleBound(false);
    // now the result package can be obtained for processing
    com.sas.services.publish.ResultPackageInterface rpi = ei.getResultPackage();
    ...
 
The package obtained will now have a life-time under consumer control and is no longer automatically closed when Execution2Interface.destroy() is called. The code to process the result package is no different.

Streaming Stored Process Example

The following code sample executes a stored process that streams results back. The stored process accepts three fixed input parameters.

    // The stored process is named "StreamingDemo".  Locate this stored process.
    import com.sas.services.storedprocess.metadata.StoredProcessFilter;
    ...
    StoredProcessFilter filter = new StoredProcessFilter("Name",
       com.sas.services.information.FilterComponent.EQUALS, "StreamingDemo");
    java.util.List list = informationService.search(userContext, filter);
    // Assume we have one object returned from the search.
    // Next, get a Stored Process Service object from the smart object.
    com.sas.services.storedprocess.metadata.StoredProcessInterface spSmartObject =
       (com.sas.services.storedprocess.metadata.StoredProcessInterface)list.get(0);
    com.sas.services.storedprocess.StoredProcess2Interface spi =
       spSmartObject.newServiceObject();
    // Set the values of the three parameters.
    spi.setParameterValue("ODSSTYLE", "boring");
    spi.setParameterValue("CHARTTYPE", "vbar");
    spi.setParameterValue("TIMEUNIT", "weeks");
    // We are now ready to execute.
    // The first parameter (false) determines whether the execution is synchronous.
    // The call to execute does not block but returns with an Execution2Interface from which
    // input and output streams can be accessed to supply data to the stored process and
    // read data from the stored process.
    com.sas.services.storedprocess.Execution2Interface ei =
       spi.execute(false, listener, false, null);
    // Get the InputStream associated with "_WEBOUT."
    InputStream is = ei.getInputStream("_WEBOUT");
    // If a Reader is desired it may be obtained as shown in the next three
    // statements (which are commented out):
    // InputStreamHeaderInterface ishi = ei.getInputStreamHeader("_WEBOUT");
    // String encoding = ishi.getCharacterEncoding();
    // InputStreamReader r = new InputStreamReader(is, encoding);
    // You can now can process the input stream - read until end-of-file
    // [code to process the input stream is not shown]
    // Wait for completion of the stored process.
    // The stream closing does not necessarily mean that the stored process has completed.
    int status = ei.waitForCompletion();
    // You can use the status code to determine whether any additional processing is needed.
    // For example, an application might choose to dump out
    // exceptions / get the SAS log if errors are encountered.
    // Destroy the Stored Process Service objects that are created.
    ei.destroy();
    spi.destroy();
 

Streaming Input

Version 1 stored processes that run on a Stored Process Server and all version 2 stored processes can accept one or more streams of input. The following code fragment is based on one input stream, "_webin", being defined in the metadata. The execute() is called to specify asynchronous execution so that control returns to the code following the call to execute() after which input may be streamed to the stored process.

    // ... find the stored process and specify parameter values if needed
    // We are now ready to execute.
    // The first parameter (false) specifies asynchronous execution
    com.sas.services.storedprocess.Execution2Interface ei =  spi.execute(false, null, false, null);
    // Get the OutputStream associated with "_WEBIN".
    OutputStream os = ei.getOutputStream("_WEBIN");
    OutputStreamWriter osw = new OutputStreamWriter(os);
    osw.write("line1: some text for line 1\n");
    osw.write("line2: and this is line 2\n");
    osw.write("line3: and here's the third and last line\n");
    osw.close();
    // ... process results as before
 

Alert Details

The execution of the stored process can be captured by an alert in the MyInbox folder of the Personal Repository by a StoredProcessAlertItemInterface object. You can view a code example which describes how the creation of an alert is requested. The event contained in the StoredProcessAlertItemInterface provides information about various aspects of the stored process (e.g., its name, description, Information Service entity key, etc.), the particular execution (e.g., parameters values, package (if present)) that it describes and execution status. Do note that generated parameters are not captured by the alert.

The Alert is created as soon as the stored process begins execution and seeded with those elements of the event that are known. After the stored process has completed execution, the alert is updated and contains all of the elements appropriate to that stored process. If the listener mechanism provided by ExecutionStatusListener2Interface is used, the alert is created before executionStatusChanged() is called for the first time and is updated before executionStatusChanged() is called for the subsequent call(s). If the stored process is executed using the execute() method the alert is updated once after creation; if the executeAsynch() method is used the alert is updated twice after creation. A typical use case would be for the stored process to be executed asynchronously and for a separate application to examine and display the execution status of stored processes of interest to the user. If the stored process creates a package, this separate application can use StoredProcessAlertItemInterface's getResults() to materialize the package.

Alerts are persisted in the MyInbox folder of the Personal Repository. See the section about accessing alerts for more details about accessing the alert.

Alerts are described in XML with an "Event" structure defined by the Event Service. Version 2 stored processes create alerts using the same format as that used in alerts created by version 1 stored processes. The specification for an alert follows:

    <sas-event:Event xmlns:sas-event=
       "http://www.sas.com/xml/namespace/services.events-1.1"
       sas-event:name="com.sas.services.storedprocess.ExecutionStatusEvent">
       <sas-event:Header>
          <sas-event:Version>1.0</sas-event:Version>
          <sas-event:SentAt>timestamp</sas-event:SentAt>
          <sas-event:Response sas-event:type="none"/>
          <sas-event:Properties>
             <Version xmlns="http://www.sas.com/xml/namespace/services.alerts.sp-1.1">
                           2.0</Version>
             <ResultType xmlns="http://www.sas.com/xml/namespace/services.alerts.sp-1.1">
                           resultType</ResultType>
             <Status xmlns="http://www.sas.com/xml/namespace/services.alerts.sp-1.1">
                           status</Status>
             <StoredProcessName
                xmlns="http://www.sas.com/xml/namespace/services.alerts.sp-1.1">
                           storedProcessName</StoredProcessName>
             </sas-event:Properties>
       </sas-event:Header>
       <sas-event:Body>
          <sas-alerts-sp:StoredProcessAlert
             xmlns:sas-alerts-sp=
                           "http://www.sas.com/xml/namespace/services.alerts.sp-1.1"
             sas-alerts-sp:version="2.0"
             sas-alerts-sp:name=name
             sas-alerts-sp:startTime=startTime
             sas-alerts-sp:endTime=endTime>
             <sas-alerts-sp:AlertEntityKey>entityKey
                           </sas-alerts-sp:AlertEntityKey>
             <sas-alerts-sp:Description>description
                           </sas-alerts-sp:Description>
             <sas-alerts-sp:StoredProcessName>storedProcessName
                           </sas-alerts-sp:StoredProcessName>
             <sas-alerts-sp:StoredProcessDescription>
                           storedProcessDescription
                       </sas-alerts-sp:StoredProcessDescription>
             <sas-alerts-sp:Status>status</sas-alerts-sp:Status>
             <sas-alerts-sp:ResultType>resultType
                           </sas-alerts-sp:ResultType>
             <sas-alerts-sp:StoredProcessEntityKey>storedProcessEntityKey
                           </sas-alerts-sp:StoredProcessEntityKey>
             <sas-alerts-sp:StoredProcessPath>storedProcessPath
                           </sas-alerts-sp:StoredProcessPath>
             <sas-alerts-sp:StoredProcessParameters>
                <sas-alerts-sp:StoredProcessParameter>
                   <sas-alerts-sp:ParmName>parmName
                                     </sas-alerts-sp:ParmName>
                   <sas-alerts-sp:ParmValue>parmValue
                                     </sas-alerts-sp:ParmValue>
                </sas-alerts-sp:StoredProcessParameter>
                ...
             </sas-alerts-sp:StoredProcessParameters>
             <sas-alerts-sp:Package>
                <sas-alerts-sp:PackageEntityKey>packageEntityKey
                              </sas-alerts-sp:PackageEntityKey>
                <sas-publish:Package>
                ...
                </sas-publish:Package>
             </sas-alerts-sp:Package>
             <sas-alerts-sp:ExecutionExceptions>
                <sas-alerts-sp:Exception>exception message,
                              cause and stack trace</sas-alerts-sp:Exception>
                ...
             </sas-alerts-sp:ExecutionExceptions>
          </sas-alerts-sp:StoredProcessAlert>
       </sas-event:Body>
       </sas-event:Event>
  

The header elements are standard event elements as defined by the Event Services. The name of the event is "com.sas.services.storedprocess.ExecutionStatusEvent". The following table offers an explanation of those header elements, which vary by event. Descriptions of elements that are an intrinsic part of the Event structure are described in the Event Service.

Element/Attribute: Description:
sas-event:SentAt A time stamp indicating when the event was created.
sas-event:Properties Properties set by the stored process are
  • sas-alerts-sp:Version - the version of this stored process alert. Same as the value of the version attribute in the body (see below for details).
  • sas-alerts-sp:ResultType - the result type. Same as the value of the ResultType element in the body (see below for details).
  • sas-alerts-sp:Status - the execution status. Same as the value of the Status element in the body (see below for details).
  • sas-alerts-sp:StoredProcessName - the name of the stored process. Same as the value of the StoredProcessName element in the body.

Explanations of the body elements are in the following table. If an element does not have a value when the alert is created, or if its value changes when the stored process completes, the behavior is documented in the Description column.

Element/Attribute: Description:
sas-alerts-sp:name The name of the alert.
sas-alerts-sp:version The version number of the alert. Currently 2.0.
sas-alerts-sp:startTime The approx time at which the stored process began execution. The timezone is GMT and the format used is yyyy-MM-dd'T'HH:mm:ss'Z'.
sas-alerts-sp:endTime The approx time at which the stored process completed execution in the same format as startTime. Is blank if the stored process is still executing.
sas-alerts-sp:AlertEntityKey The Information Service entity key of the alert.
sas-alerts-sp:Description The description of the alert. It contains the name of the stored process. After execution completes, the text also has the completion time.
sas-alerts-sp:StoredProcessName The name of the stored process.
sas-alerts-sp:StoredProcessDescription The description of the stored process.
sas-alerts-sp:Status The status of this execution. When the alert is created, it is set to ExecutionBaseInterface.STATUS_EXECUTING. When execution is completed, it is set to ExecutionBaseInterface.STATUS_SAS_EXCEPTION_OCCURRED, ExecutionBaseInterface.STATUS_COMPLETED_WITHOUT_EXCEPTION, ExecutionBaseInterface.STATUS_EXCEPTION_OCCURRED, or Execution2Interface.STATUS_ABORTED.
sas-alerts-sp:ResultType The type of result generated by the stored process. One of the values from StoredProcessInterface2.RESULT_TYPE_*.
sas-alerts-sp:StoredProcessEntityKey The Information Service Entity Key of the stored process.
sas-alerts-sp:StoredProcessPath The SBIP URL of the stored process.
sas-alerts-sp:StoredProcessParameters Describes the parameters of the stored process. Contains zero or more StoredProcessParameter entries.
sas-alerts-sp:StoredProcessParameter Describes each parameter of the stored process.

If the parameter is a scalar it's described as follows:

  • sas-alerts-sp:ParmName - the name of the parameter
  • sas-alerts-sp:ParmValue - the value of the parameter

If the parameter is an array it's described as follows:

  • sas-alerts-sp:ParmName - the name of the parameter
  • sas-alerts-sp:ParmValues - the values of the parameter - this element contains one or more sas-alerts-sp:ParmValue elements.
sas-alerts-sp:Package Describes the package. This element is present only if the result type is a transient package, a SAS server based file package, or a WebDAV server based package.

When the stored process starts executing an empty Package element is created. After execution is complete, the following two elements are added:

  • sas-alerts-sp:PackageEntityKey - the Information Service entity key of the package
  • sas-publish:Package - an event as described in the Publish Service, which describes the package
sas-alerts-sp:ExecutionExceptions Describes any exceptions encountered in the execution of the stored process. Contains zero or more Exception entries. When the stored process starts executing an empty ExecutionExceptions element is created. After execution is complete, Exception elements are added if exceptions occurred.
sas-alerts-sp:Exception Describes the exception: the message, the cause, and a stack trace of the root exception.

A sample alert is shown:

    <?xml version="1.0" encoding="UTF-8"?>
    <sas-event:Event xmlns:sas-event=
       "http://www.sas.com/xml/namespace/services.events-1.1"
       sas-event:name="com.sas.services.storedprocess.ExecutionStatusEvent">
       <sas-event:Header>
          <sas-event:Version>1.0</sas-event:Version>
          <sas-event:SentAt>2008-04-02T20:16:48Z</sas-event:SentAt>
          <sas-event:Response sas-event:type="none"/>
          <sas-event:Properties>
             <ResultType xmlns=
                "http://www.sas.com/xml/namespace/services.alerts.sp-1.1">512
                </ResultType>
             <Status xmlns=
                "http://www.sas.com/xml/namespace/services.alerts.sp-1.1">3
                </Status>
             <Version xmlns=
                "http://www.sas.com/xml/namespace/services.alerts.sp-1.1">2.0
                </Version>              
             <StoredProcessName xmlns=
                "http://www.sas.com/xml/namespace/services.alerts.sp-1.1">SP2_PSR (PR Existing Instance - Workspace)
                </StoredProcessName>
          </sas-event:Properties>
       </sas-event:Header>
       <sas-event:Body>
          <sas-alerts-sp:StoredProcessAlert xmlns:sas-alerts-sp=
             "http://www.sas.com/xml/namespace/services.alerts.sp-1.1"
             sas-alerts-sp:version="2.0"
             sas-alerts-sp:name="Sd7458859"
             sas-alerts-sp:startTime="2008-04-02T20:15:39.638Z"
             sas-alerts-sp:endTime="2008-04-02T20:16:17.211Z">
             <sas-alerts-sp:AlertEntityKey>
                storedprocessalert+dav:RGWebDav/noname/PR/MyInbox/Sd7458859/storedprocessalert
                </sas-alerts-sp:AlertEntityKey>
             <sas-alerts-sp:Description>This alert describes the execution
                of stored process "SP2_PSR (PR Existing Instance - Workspace)" which completed at
                2008-04-02T20:16:17.211Z.</sas-alerts-sp:Description>
             <sas-alerts-sp:StoredProcessName>SP2_PSR (PR Existing Instance - Workspace)
                </sas-alerts-sp:StoredProcessName>
             <sas-alerts-sp:StoredProcessDescription>
                Sample Product Sales Report (PSR) Stored Process - to the Personal Repository reusing an exisiting instance.
                </sas-alerts-sp:StoredProcessDescription>
             <sas-alerts-sp:Status>3</sas-alerts-sp:Status>
             <sas-alerts-sp:ResultType>512</sas-alerts-sp:ResultType>
             <sas-alerts-sp:StoredProcessEntityKey>
                StoredProcess+omi://Primary/reposname=primary/ClassifierMap;id=A5Z6U1YS.AK0016D1
                </sas-alerts-sp:StoredProcessEntityKey>
             <sas-alerts-sp:StoredProcessPath>
                SBIP://METASERVER/WSP2/SP2_PSR (PR Existing Instance - Workspace)(StoredProcess)
                </sas-alerts-sp:StoredProcessPath>
             <sas-alerts-sp:StoredProcessParameters>
                <sas-alerts-sp:Parameter>
                   <sas-alerts-sp:ParmName>pCountry
                      </sas-alerts-sp:ParmName>
                   <sas-alerts-sp:ParmValue>Canada
                      </sas-alerts-sp:ParmValue>
                </sas-alerts-sp:Parameter>
                <sas-alerts-sp:Parameter>
                   <sas-alerts-sp:ParmName>pYear
                      </sas-alerts-sp:ParmName>
                   <sas-alerts-sp:ParmValue>1993
                      </sas-alerts-sp:ParmValue>
                </sas-alerts-sp:Parameter>
                <sas-alerts-sp:Parameter>
                   <sas-alerts-sp:ParmName>_result
                      </sas-alerts-sp:ParmName>
                   <sas-alerts-sp:ParmValue>PACKAGE_TO_WEBDAV
                      </sas-alerts-sp:ParmValue>
                </sas-alerts-sp:Parameter>
                <sas-alerts-sp:Parameter>
                   <sas-alerts-sp:ParmName>_publish_to_pr
                      </sas-alerts-sp:ParmName>
                   <sas-alerts-sp:ParmValue>true
                      </sas-alerts-sp:ParmValue>
                </sas-alerts-sp:Parameter>
                <sas-alerts-sp:Parameter>
                   <sas-alerts-sp:ParmName>_pr_collection_path
                      </sas-alerts-sp:ParmName>
                   <sas-alerts-sp:ParmValue>SPResults/collection1
                      </sas-alerts-sp:ParmValue>
                </sas-alerts-sp:Parameter>
             </sas-alerts-sp:StoredProcessParameters>
             <sas-alerts-sp:Package>
                <sas-alerts-sp:PackageEntityKey>
                   package+dav://RGWebDav/noname/PR/MyResults/SPResults/collection1/package
                   </sas-alerts-sp:PackageEntityKey>
                <sas-publish:Package xmlns:sas-publish=
                   "http://www.sas.com/xml/namespace/services.publish-1.1"
                   sas-publish:version="1.0" sas-publish:description=
                   "1993 Sales Report for Canada"
                   sas-publish:packageUrl=
                   "http://d14844.na.sas.com:80/DAVStuff/noname/PR/MyResults/SPResults/collection1"
                   sas-publish:transport="webdav" category="sales"
                   context="product">
                   <sas-publish:Entries>
                   <sas-publish:Entry 
                     sas-publish:description="Sales Report: Tabular" sas-publish:type="html">
                     <sas-publish:Html sas-publish:name="body.htm" sas-publish:type="body"
                     sas-publish:url="body.htm"/>
                   </sas-publish:Entry>
                   </sas-publish:Entries>
                </sas-publish:Package>
             </sas-alerts-sp:Package>
             <sas-alerts-sp:ExecutionExceptions/>
          </sas-alerts-sp:StoredProcessAlert>
       </sas-event:Body>
    </sas-event:Event>
 

Accessing Alerts

Alerts describing the execution of a stored process are placed in the MyInbox folder of the Personal Repository. The first step is to access the Personal Repository. Personal Repository documentation provides code fragments that show how to obtain a reference to MyInbox.

    FolderInterface myInbox = ... get a reference to "MyInbox".
    // A list of all alerts can be obtained.
    List list = myInbox.getItemsByClass(StoredProcessAlertItem.class);
    // These alerts might be presented to the user.
    // Alternatively, a specific alert can be obtained by name.
    StoredProcessAlertItem alert =
       (StoredProcessAlertItem)myInbox.getItemByClass(alertName, StoredProcessAlertItem.class);
    // Various elements of the alert can be obtained as follows from the getProperty() method:
    // Note: Constants.NS_STOREDPROCESS_ALERT_PREFIX_COLON maps to "sas-alerts-sp:"
    String prefix = "//" + com.sas.services.util.Constants.NS_STOREDPROCESS_ALERT_PREFIX_COLON;
    String statusStr = alert.getProperty( prefix + "Status" );
    String resultTypeStr = alert.getProperty( prefix + "ResultType" );
    int status = Integer.parseInt(statusStr);
    int resultType = Integer.parseInt(resultTypeStr);
    if (status ==  ExecutionBaseInterface.STATUS_COMPLETED_WITHOUT_EXCEPTION) {
       if (resultType == StoredProcess2Interface.RESULT_TYPE_PACKAGE) {
          PackageInterface pkg = alert.getResults();
          ResultPackageInterface rpkg = (ResultPackageInterface)pkg.newServiceObject();
          ... process the package ...
       }
    }
 

Changes for 9.3:

Changes for 9.2:

Using StoredProcessInterface to execute 9.2 stored process:

Stored processes created pre-9.2 were created using a pre-9.2 SMC and a StoredProcessInterface was used to execute them. Stored processes created by a 9.2 SMC have an improved model, are modeled differently in metadata and are executed by StoredProcess2Interface objects. The migration process converts stored processes from the pre-9.2 format to the 9.2 format. The implementation backing the original StoredProcessInterface object has been enhanced so that a stored processes migrated to the new format can be processed by it. This section describes how 9.2 stored processes are interpreted by StoredProcessInterface.

9.2 style prompts are converted to the pre-9.2 Entity based model using the convertPromptGroupToEntityconvertPromptGroupToEntity method of PromptToEntityConverter.

Data Sources and Data Targets are added to the list of output streams and input streams supported by the Stored Process.

Pre-9.2 stored processes had different result types. 9.2 stored processes have result capabilities with the type of result being driven by the capabilities allowed and prompt values. The following describes how different combinations of capability and prompts (converted to the Entity model) in a migrated stored process map to the pre-9.2 result type of StoredProcessInterface when a StoredProcessInterface is constructed.

If the "_result" parameter is missing or present with no value:

If the "_result" parameter has a non-empty value:

If the value of "_result" is not one of the values described above, an exception is thrown.

Do note the above functionality is provided for compatibility purposes, so that old code can run newly migrated stored processes. The functionality is not intended for newly created stored processes to be run using old code. And, StoredProcessInterface cannot be used to execute Version 2 stored processes introduced in 9.3.


***  This package contains classes that provide Binary Compatibility only, not Source Compatibility  ***

Note:
Extension of the classes in this package is prohibited unless otherwise documented. Similarly, extension or implementation of the interfaces in this package is prohibited except as documented.


Copyright © 2009 SAS Institute Inc. All Rights Reserved.