Microsoft SQL Server Data Services (SSDS): First Contact

I have been reading about cloud computing quite a bit.  I found that Microsoft is doing something really interesting under the code name "Sitka" (there is now a public beta, so the code word is no longer internal).

Sitka, or SSDS, is cloud entity storage that offers SLA features to include massive scale, availability, performance, and security.   To read more about it, take a look at this.  Sitka is named such either because of a place in Alaska or because of this restaurant, located in Seattle.

I signed up for the beta and went to work creating a simple application that will create an entity in an authority and container I specify.  An authority is the top level of the containment hierarchy in SSDS, and is represented via a DNS name:

So, my SSDS authority is experiments.

Next is the container, which each authority can contain zero-to-many and which hold entities.  For the purposes of my little problem I created a container called "objects"**objects**

Entities are units of storage which implement the IEntity interface, which is below:

    1: public interface IEntity
    2: {
    3:     Guid Id { get; set; }
    4:     bool IsDirty { get; set; }
    5:     Dictionary<string, object> Fields { get; }
    6: }

An entity is essentially a bag of proprieties than can be uniquely identified.

In my "hello world" example, I created a class called Recommendation (I have an idea about how to use SSDS in a little side project I am working on to give recommendations on Microsoft Project usage depending on what is selected in Project and its surrounding context).

My goal today, given that I have a house full of kids, was to do simple CRUD operations in SSDS:  create a recommendation, update a recommendation, and delete a recommendation.  I searched around in our internal repository of presentations and found a couple good pieces by Eugenio Pace so I started reading his blog.  He created an SSDS blog provider for BlogEngine.Net, which I downloaded.  From the blog provider, I lifted several libraries (they are probably available somewhere else, but this is where I found them first):


My sample application includes an app.config that looks like the following:

    1: <?xml version="1.0" encoding="utf-8" ?>
    2: <configuration>
    4:   <appSettings>
    5:     <!-- Sitka Proxy-->
    6:     <add key="SitkaProxy" value="Shp.Runtime.Sitka.ServiceGateway.SitkaClient.SitkaSoapServiceClient, Shp.Runtime.Sitka.ServiceGateway" />
    7:     <!--<add key="SitkaProxy" value="Shp.Runtime.OfflineSitka.OfflineSitkaSoapService, Shp.Runtime.OfflineSitka"/>-->
    9:     <!-- Sitka Authority, Username & Password -->
   10:     <add key="SitkaUserName" value="SNIP" />
   11:     <add key="SitkaPassword" value="SNIP" />
   12:     <add key="DefaultAuthority" value="experiments" />
   13:   </appSettings>
   15:   <connectionStrings>
   16:     <add name="OfflineSitka" connectionString="Database=OfflineSitka;Server=(local)\SQLEXPRESS;Integrated Security=SSPI"
   17:         providerName="System.Data.SqlClient" />
   18:   </connectionStrings>
   20:   <system.serviceModel>
   21:     <bindings>
   22:       <basicHttpBinding>
   23:         <binding name="SitkaSoapEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
   24:             receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
   25:             bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
   26:             maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
   27:             messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
   28:             useDefaultWebProxy="true">
   29:           <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
   30:               maxBytesPerRead="4096" maxNameTableCharCount="16384" />
   31:           <security mode="TransportCredentialOnly">
   32:             <transport clientCredentialType="Basic" proxyCredentialType="None"
   33:                 realm="" />
   34:             <message clientCredentialType="UserName" algorithmSuite="Default" />
   35:           </security>
   36:         </binding>
   37:       </basicHttpBinding>
   38:     </bindings>
   39:     <client>
   40:       <endpoint address="" binding="basicHttpBinding"
   41:           bindingConfiguration="SitkaSoapEndpoint" contract="SitkaClient.ISitkaSoapService"
   42:           name="SitkaSoapEndpoint" />
   43:     </client>
   44:   </system.serviceModel>
   45: </configuration>

Note the Sitka proxy, which is a simple class library that fronts a WCF service.  SSDS supports both SOAP and REST, which is very neat.  Here is the source of my hello world program:

    1: DefaultTenantManager tenantManager = new DefaultTenantManager();
    2: SitkaProxyFactory proxFactory = new SitkaProxyFactory(tenantManager);
    3: EntityMapper<Recommendation> entityMapper = new GenericMapper<Recommendation>();
    4: Repository<Recommendation> repo = new Repository<Recommendation>(tenantManager, proxFactory, entityMapper);
    6: Recommendation recommend = new Recommendation {Name = "test"};
    7: repo.Insert(recommend);
    9: recommend.Name = "test2";
   11: repo.Update(recommend);
   13: repo.Delete(recommend.Id);


The DefaultTenantManager simply loads app.config data into a simple object that contains my user name, password, default authority (experiments) and the container ID (objects in this case).  The SitkaProxyFactory creates an instance of the Sitka webservice and configures it.  The EntityMapper wraps an entity for standard semantics.  The Repository<Of Type T> wraps the basic web service operations for T (Recommendation).

The SSDS SDK provides an SSDS Explorer, which is a simple graphical interface into an authority and container.  It also inserts XML templates for creating the two SSDS containment objects and for creating entities.  Finally, it will execute simple queries.

Here is the result of querying SSDS after the "repo.Insert()" on line 7 above:


On line 9, I change the name to "test2" and here is the results:


Finally, I delete the entity and here are the results:


There is huge potential here.  I have so many ideas I need to go stare at a wall for a while.  Eugenio Pace has created an offline cache that is really very cool.  Read about it here.