Jump to: navigation, search

Difference between revisions of "OpenStack-SDK-DotNet/HighLevelArch"

(A high level overview of the current architecture for the .NET SDK)
 
Line 1: Line 1:
 
__TOC__
 
__TOC__
 +
  
 
== High Level Goals==
 
== High Level Goals==
Line 6: Line 7:
 
# Provide a decoupled architecture, that allows for rapid and distributed development.
 
# Provide a decoupled architecture, that allows for rapid and distributed development.
 
# Strive for a [http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) SOLID] and sustainable design, that can grow with the project.  
 
# Strive for a [http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) SOLID] and sustainable design, that can grow with the project.  
 +
  
 
== Current Design ==  
 
== Current Design ==  
  
 
[[File:HighLevelArch.PNG|center]]
 
[[File:HighLevelArch.PNG|center]]
 +
  
 
The basic flow for consuming the API is:
 
The basic flow for consuming the API is:
Line 37: Line 40:
 
         Console.WriteLine(container.Name);
 
         Console.WriteLine(container.Name);
 
     }
 
     }
 +
  
 
== Extending the API ==
 
== Extending the API ==

Revision as of 21:29, 16 April 2014


High Level Goals

  1. Provide a simple, easily consumable, and intuitive surface area for the end user.
  2. Provide a flexible code base that can be easily extended by third parties, without altering the overall usage pattern of the end user.
  3. Provide a decoupled architecture, that allows for rapid and distributed development.
  4. Strive for a SOLID and sustainable design, that can grow with the project.


Current Design

HighLevelArch.PNG


The basic flow for consuming the API is:

  1. Create the appropriate credential based on the desired OpenStack instance.
  2. Ask the Client Manager for an instance of the appropriate client object using the credential.
  3. Connect the client.
  4. Ask the acquired client for the desired service client (i.e. storage, or identity, or compute).
  5. use the provided service client to communicate with the remote services.


A simple code example is:

   var authUri = new Uri("https://region.identity.host.com:12345/v2.0/tokens");
   var userName = "user name";
   var password = "password";
   var tenantId = "XXXXXXXXXXXXXX-Project";
   
   var credential = new OpenstackCredential(authUri, userName, password, tenantId);
   var client = OpenstackClientManager.Create(credential);
   await client.Connect();
   var storageServiceClient = client.CreateServiceClient<IStorageServiceClient>();
   var storageAccount = await storageServiceClient.GetStorageAccount();
   foreach(var container in storageAccount.Containers)
   {
       Console.WriteLine(container.Name);
   }


Extending the API

While the main goal is to create an easy to use API for the end user, it is equally important to provide a flexible code base that can be extended, and modified to provide additional features and functionality for the end user. The current design illustrated above is designed to introduce extensibility points throughout the stack. This design enables a number of extensibility scenarios (listed below), and empowers third parties to build on top of the core API.

There are two main ways to extend the API. The first method is to simply create types that implement the key interfaces (IOpenStackClient, IOpenStackServiceClient, etc). and use the Client and Service Manager classes to register the new implementations. The second method is to use the built in Service Location infrastructure to override (replace) the existing implementations for internal interfaces and alter the behavior of specific pieces of the stack while leaving others untouched. There are scenarios (see below) where each of these methods may or may not be needed. By using both methods, most if not all common extensibility scenarios can be achieved.

Scenario 1 - Extending authentication

'As a third party, I have an identity service that is different then the stock OpenStack identity service. I want to extend the API such that my custom authentication service can be used.'

For this scenario, the third party would create classes that derive from and implement the IOpenStackCredential, IIdentityServiceClient, and IOpenStackServiceClientDefinition interfaces. The third party would then use the Service Manager class to register their implementation of the IIdentityServiceClient using their derived service client definition. The end user would then need to create an instance of the third parties implementation of the IOpenStackCredential interface, pass it to the Client Manger to get an instance of a client. This is the same basic flow illustrated above. Once the user calls the Connect method on the instance of the client the stock code turns to the Service Manager class and asks it for an IIdentityServiceClient that knows how to handle the third parties credential object. The third parties implementation of the IIdentityServiceClient would be returned, and it's Authenticate method is called. To the end user, there is no difference to the standard flow, other then the construction of a specific credential for the system they wish to connect to.

Note:
If the third party needs to make more extensive changes to how the client interacts with the IIdentityServiceClient interface, they can extend the client itself, and register it with the Client Manager object.

Scenario 2 - Supporting third-party services

'As a third party, I have a service that is not a part of the standard OpenStack group of services. I want to extend the API to allow the user to interact with my custom service.'

For this scenario, the third part would create two classes. One class would derive from the IOpenStackServiceClient interface, and contain the implementation details for interacting with the custom service. The second class would derive from and implement the IOpenStackServiceDefinition interface. Using the derived service definition, the third party would register their service client with the Service Manager class. The end user, after creating a credential, getting a client, and connecting the client would then request the third parties service client.

 var thirdPartyServiceClient = client.CreateServiceClient<IThirdPartyServiceClient>();

This follows the same end user flow that was illistrated above, and offers a consistent way to access services (stock, third party, or otherwise).