The PSI is a set of web services. They provide a programmatic interface to the Project Server data and functionality. Here’s a high level schematic of the PSI architecture:

The server architecture is layered, the PWA tier being the presentation tier, the middle tier hosting all the business logic and the databases taking shape of the data tier.
The presentation tier, or PWA, is responsible for authentication. So, all clients have to pass through the PWA tier before they can access the server data.  The PWA processes runs as a specific system user, which I will refer to as the “PWA User”. The middle tier trust the “PWA User” account and honors any requests made by it. So, after authenticating the user, the PWA tier, instead of impersonating the user, invokes the middle tier functionality as the “PWA User” account. It passes the user information to the middle tier by packaging it in a “Context” object. The middle tier retrieves the user information from the “Context” object and runs the middle tier processes as that user. All authorizations checks are performed for that user.

The actual PSI web services are present on the application server machine (i.e. the middle tier). And, they are accessible only to those processes that run as “PWA User” – PWA being one of them. So, how does a client application (which is not running with the “PWA User” credentials) access the PSI web services? Well, the PWA hosts “proxy” PSIs – using an HTTP handler that “manifests” the PSIs on the PWA (the PSI proxies are available under the http://servername/projectwebaccess/_vti_bin/psi/). The clients reference and make functions calls to the PSIs appearing on PWA as if they were hosted on the presentation tier. PWA forwards these requests to the middle tier in the appropriate format (after authenticating the requestor.

The following diagram should explain the sequence of operations involved in invoking a PSI method.

Before I get to the section on how to program with the PSI, here’s a list of all the PSIs that are available in Beta2 (caveat: this list may change at RTM). http://servername/projectwebaccesssite/_vti_bin/psi/Admin.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Archive.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Calendar.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/CubeAdmin.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/CustomFields.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Events.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/LookupTable.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Notifications.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/ObjectLinkProvider.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Project.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/QueueSystem.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Resource.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/ResourcePlan.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Rules.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Security.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/Statusing.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/StatusReports.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/TimeSheet.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/View.asmx
http://servername/projectwebaccesssite/_vti_bin/psi/WssInterop.asmx

Now onto a simple sample application that demonstrates the PSI at work. Set a web reference to the Project web service (Project.asmx) – say ProjectWS.

            //Instantiate the project web service object

            ProjectWS.Project _project = new ProjectWS.Project();

            //set the url property to the project.asmx web service to  the appropriate project server instance.

            _project.Url = "http://myserver/projectserver/_vti_bin/psi/project.asmx";

            //passing the default windows credentials

            _project.Credentials = CredentialCache.DefaultCredentials;

            //reading a list of all the projects on the server into a project dataset object

            ProjectWS.ProjectDataSet _projectDataSet = _project.ReadProjectList();

            //write the # of project records retrieved.

            Console.Write("Total projects = {0}", _projectDataSet.Project.Count.ToString());

Next post, I’ll write a little bit about the primary data structures used by the PSI to ferry data back and forth – the typed datasets. And a fully working sample solution.