Once the access credentials and the default region are successfully stored, the main window of KAM is loaded. Here the user can decide which action he wants to take. Each individual action corresponds to a different Amazon service. As such the menu allows the user to create an EC2 instance with the latest Kentico CMS installed, to create and configure scalable relational databases with Kentico, to enable object storage and fast delivery network for Kentico or to see monitored statistics. Additionally, the user can decide to change his default region on the main screen. Every action leads to a unique set of consecutive steps that guide the user through customization process in a wizard-like fashion. One step of this wizard corresponds to one WPF page. To provide seamless navigation among the steps, I am using navigation window as an embedding container for individual pages. This way I can rely on navigation service that is an internal part of navigation window, exposed through one of its properties, to allow for asynchronous transition between pages. Another perk of using the navigation service is that it keeps the history of navigation steps and as such provides out-of-box methods for checking navigation entries (steps) as well as going back and forward between these entries. Much as simple navigate method these are all asynchronous. Moreover, each page contains a reference to the navigation service that was injected by the navigation window upon the page’s creation. This means that pages themselves can control the flow of navigating without the need of referencing their parent window, which adds additional simplicity.
In order to transfer messages between pages efficiently as well as reduce memory usage, I decide to introduce a concept of session in the application. Session refers to a semi-permanent interactive information interchange and is mostly used in computer networking and web applications. This technique allows keeping state with typically stateless HTTP protocol [21]. Unlike cookies, another state-retaining technique, session rather resides on the server side instead of client side. In my application, each individual page has access to the session object. This functionality is implemented by extending the page class and creating a new class with session property – so called abstract view. Additionally, each action (set of wizard-like steps) has associated a unique session, which works in conjunction with how navigation service is implemented. This behavior allows every action step, or view, to access session resources without interfering with another action’s session. The session itself is implemented as a disposable object that keeps track of existing resources and can create new ones on-demand. Individual views can then ask the session for necessary resources by invoking its generic get method with specific resource type. If the resource already exists it is injected in the view, otherwise the session creates the resource based on the provided type via reflection and provides it to the view. This distribution of responsibilities corresponds to what we know as Inversion of Control design pattern. The idea behind IoC is that classes don’t create their necessary resources but only ask for them. Then it is a responsibility of IoC container to create these resources and provide them to classes. In this way different components of applications are decoupled, which allows for better flexibility and supportability.
To be able to create EC2 instance with Kentico CMS installed and then to turn it into an AMI, several steps are required to take. First of all, it is essential to choose an underlying AMI. For our purposes it only makes sense to choose from Windows AMIs. Additionally, we want to make sure to have an AMI that support Microsoft SQL Server as this as well is the requirement for Kentico CMS. Since the supported version of .NET framework for Kentico CMS is 4.0 and higher only Windows Server 2008 R2 and Windows Server 2012 AMI satisfy this requirement. As far as database server goes the user can choose from Standard, Web or Express edition for both SQL Server 2008 and SQL Server 2012. In order to exploit benefits of PaaS, I decided to choose from Amazon-maintained AMI as these receive regular updates. Additionally, although AWS SDK for .NET offers utility methods enabling quick querying of Amazon images, I decided to write my own code, which would be asynchronous and also better suited to achieve above-mentioned combinations of OS and database servers. This code is part of EC2Manager, a service that encapsulates all the code necessary to configure and launch a new instance. This service exposes powerful API through several straight-forward methods while effectively hiding the complexity of this API and only exposing what is necessary. This way application logic (AWS calls, results pruning, multithreading) is nicely separated from presentation logic.
Once the underlying AMI is chosen, the application takes the user to another screen where he is allowed to configure both access to his soon-to-be-launched instance as well as an administrator password. As it was mentioned before, Amazon Elastic Cloud provides security groups as a mean of configuring AWS firewall access rights. In this case there are only four permissions that we need, each of them corresponding to one communication protocol. First two of them are HTTP protocols. Port 80 is generally used to by webserver, in this case Microsoft IIS23, to access running web sites. Here it will be used to access Kentico CMS. Port 8080 serves as a communication port with Kentico AWS API and is mainly used for progress messaging during installation of CMS. Port 1433 is generally reserved for MS SQL server that is bundled with the operating system, while port 3389 allows the user to connect to the running instance through Remote Desktop. KAM allows its user to specify for every individual port whether anyone can connect to it (IP address 0.0.0.0) or just user’s public address (and thus only his computer) will be allowed. In second step the user has an option to enter an administrator password with whom he will be able to connect to the instance once it launches. This password has to satisfy all the security criteria for typical Windows Server administrator password. If the password field remains empty a random password is generated and displayed to the user at the end of the installation.
Once both of these steps are completed, KAM lets the user to customize his Kentico CMS installation. By now all the essential choices for launching an instance were made and thus the rest of wizard focuses strictly on CMS installer. However, this customization is optional and user can decide to proceed to launching and installation process at any time. As such, this particular step was implemented with slightly different structure. This view is internally divided into several subviews. Subview class inherits from view class and thus has access to the session object. However, it benefits from separate navigation service that allows it to easily navigate to another subview or to return to previous one. Each subview remembers its immediate state and stores it in the session object. This way even if the user skips some steps his choices are remembered. With regards to CMS customization two subviews are of particular interest. First one allows the user to select a template for his Kentico site. The default option here is Corporate Site. Second subview enables modification of default IIS and database settings. Here the user can specify whether he wants to have Kentico CMS installed as a root application of IIS or specify target location if this is not the case. Additionally, he has power to choose the type of web project, which can be either a web site project or a web application project, and optionally to enable performance counters and health monitoring for Kentico. As far as database is concerned, the user can enter a name for his Kentico database.
After all these steps are completed new instance can finally be launched. In order to launch new instance, following information is passed to the EC2Manager – underlying AMI id, security group permissions as well as number of launching instances and their types. These last two options are currently hardcoded since they don’t play any significant role in Kentico AMI creation, but they are also editable, which could be exploited in the future. The rest of the user-provided information such as CMS installation details and administrator passwords are passed to the launching instance in form of user data. User data refers to a base-64 encoded script passed to the launching instance in order to be executed shortly after the instance has started running. In our case, this can be either a command prompt executable file or a PowerShell cmdlet. Since the latter possesses much more flexibility I decided to use it in my application. My user data thus consists of two PowerShell functions. First one uses native PowerShell libraries to set the user-specified administrator password. This approach eliminates the need to associate AWS public key with new instance in order to generate a temporary administrator password to use with Remote Desktop. As such, it reduces the complexity as well as improves speed of the launch process. Second PowerShell function is responsible for downloading, unpacking and launching Kentico AWS Installer with user-specified data. KAI is then responsible for configuration of the environment and installation of Kentico CMS. Because of the lack of backward compatibility in SQL Server administration libraries there are actually two versions Kentico AWS Utilities. Launching instance is then responsible for downloading the right one based on its version of SQL Server. Once the new instance is successfully running, control over the installation process is handed over to KAI.
Share with your friends: |