Atomia Automation Server

hourglassjurorMechanics

Nov 5, 2013 (3 years and 7 months ago)

122 views

1
Atomia Automation Server
Atomia AB
29 March 2012, Version 12.4.1
Table of Contents
1. Overview ................................................................................................................................ 1
1.1. What is Atomia Automation Server? .............................................................................. 1
1.2. Architecture .................................................................................................................. 2
2. Features ................................................................................................................................. 2
2.1. Brief overview .............................................................................................................. 4
2.2. Accounts ...................................................................................................................... 5
2.3. Service Description ....................................................................................................... 5
2.4. Package Description ..................................................................................................... 7
2.5. Resource Description .................................................................................................... 8
2.6. Module ......................................................................................................................... 8
2.7. Resource description examples ..................................................................................... 9
2.8. Provisioning description examples ................................................................................. 9
3. Installation .............................................................................................................................. 9
3.1. Prerequisites ................................................................................................................ 9
4. Usage ..................................................................................................................................... 9
4.1. Configuring Communication Channel ............................................................................. 9
4.2. Using Atomia Automation Server Core API .................................................................... 9
5. Developers Giude .................................................................................................................. 11
5.1. API and SDK Reference ............................................................................................. 11
5.2. Code Examples .......................................................................................................... 12
5.3. Getting Started ........................................................................................................... 32
6. Configuration ......................................................................................................................... 56
6.1. Package Description ................................................................................................... 56
6.2. Resource Description .................................................................................................. 59
6.3. Service Description ..................................................................................................... 65
7. Administrators Guide ............................................................................................................. 91
7.1. Before you begin ........................................................................................................ 91
7.2. Introduction ................................................................................................................ 91
7.3. Preparation phase ...................................................................................................... 92
7.4. Engine phase ............................................................................................................. 93
7.5. Fixing broken requests ................................................................................................ 93
8. FAQ ..................................................................................................................................... 95
8.1. How do I add a new resource that will be used by default by new users? ........................ 95
Index ........................................................................................................................................ 96
1. Overview
 What is Atomia Automation Server?
 Architecture
1.1. What is Atomia Automation Server?
The Atomia Automation Server gives you a standardized way of automating your IT infrastructure, allowing
it to communicate with any kind of resource (web server, DNS server, etc) that the Automation Server
knows how to talk to. You can expand that knowledge by writing an Automation Server module . In some
cases a resource will provide an interface for its configuration, in which case a module is enough. When no
such interface exist, you will also need to write a resource agent - it acts as a prolonged arm of the module.
In the hosting industry, setting up an ASP.NET site includes configuring an IIS web server, DNS server,
FTP server and so on. These actions can be described to the Atomia Automation Core with a provisioning
description. From this point, adding a ASP.NET site becomes a one-step action for the end-user.
Atomia Automation Server
2
1.2. Architecture
This is simplified view of the Atomia Automation architecture used for hosting, and its interaction with the
environment.
Clients send requests to the Atomia Automation Server, which are, with the help of modules and agents,
translated into resource configurations.
2. Features
 Brief overview
 Accounts
 Service Description
 Simple service
 Complex service
 Logical and physical structure of service representation
 Package Description
 Resource Description
 Module
Atomia Automation Server
3
 Understanding the Provisioning module
 Resource description examples
 Provisioning description examples
The following are key concepts in understanding the Atomia Automation Server, all of which will be
described in detail below.
 accounts
 service description
 package description
 resource description
 module
Atomia Automation Server
4
2.1. Brief overview
1.An account is a person or a company using Automation Server.
2.A service is a configuration/installation/setup on a resource (for example a web site on a web server,
or a DNS zone on a name server). Every service belongs to some account. Available types of services
are listed in the Service Description - an XML definition of available service types. A set of services that
one account may have is limited by packages activated for that account.
3.A package is basically a set of limitations that applies to account owning that package (for example,
5 web sites, 100 email accounts, and 3 databases). One account may have several packages. All
available packages are listed in the package description - XML file with definition of available packages.
Atomia Automation Server
5
4.A resource has services configured (provisioned) on it (example resources: web server, name server,
storage, mail server, etc.). For a device to be considered a resource, Automation Server must know
how to communicate with it.
5.The package description lists available services (services defined in the service description) and their
limitations.
6.The resource description lists available resources.
7.The service description lists available services and their relations.
8.A module is a software plugin used by the Atomia Automation Server to perform actions on a resource.
Both the resource description and the service description depend on the module.
2.2. Accounts
An Atomia account is a container of packages, services and settings for one company/person. All services
must belong to an account, which in turn can have one or more packages.
2.3. Service Description
The Atomia Automation Server uses Provisioning Description files to describe available services, their
relations, limitations, initialization instructions and termination instructions. There are two types of services:
 Simple services
 Complex services
2.3.1. Simple service
A simple service is a single Atomia building block. It can represent one e-mail account, one domain name,
one DNS record or one Linux website - anything that can be configured on a resource. It is described with
a name and a list of properties. Simple services have a parent-child structure. A child service can not be
added without a parent service being added first.
Examples
WebSite is the name of one simple service. WebSite has the following properties: Name , PortNumber ,
etc. VirtualDirectory is the child of a service WeSite , hence VirtualDirectory cannot exist without
WebSite .
Atomia Automation Server
6
2.3.2. Complex service
A complex service consists of a set of complex services, simple services and their configuration.
It also contains limitations which apply to enclosed services, property transformations (how you can
"calculate" properties of enclosed services based on the complex service property values) and initialization
instructions. In general, a complex service is not located on a particular resource, but rather it's simple
services are.
Here is a simplified illustration for a Windows Hosting Service:
An organization using Atomia Automation server must model its own services according to their specific
needs.
2.3.3. Logical and physical structure of service representation
Internally, Atomia Automation Server has two types of service representations:
 Logical service representation
 Physical service representation
Logical and physical representations are shown below:
Atomia Automation Server
7
The image above shows an example of the logical structure of services. The number or letter in the right
bottom corner of each box represents the type of service specified: complex services are marked with
letters, simple services with numbers. As you can see, the complex service WebSite has two DnsRecord
services. The complex service MailSupport also has two DnsRecord services. One of these records is the
same for both. Also, the parent of these records - DnsZone - is the same. So, the physical structure of these
services will be:
The logical structure of these services is important because the system must know the logical relations
between services. For example - if a user wants to delete MailSupport , the system should only delete
DnsRecord with ID 4 and the MailSupport complex service. DnsZone , DnsRecord with ID 2 and DnsRecord with
ID 3 are required for the WebSite complex service.
2.4. Package Description
Simply put, a package is something a customer buys. The package description contains a list of services,
their limitations and the service settings values. An extra package is a package that can extend other
packages.
Example of a hosting package:
Service
Quantity
E-mail Accounts
2000
FTP Accounts
Unlimited
MySQL Databases
10
Addon Domains
Unlimited
Atomia Automation Server
8
Service
Quantity
Sub Domains
Unlimited
Parked Domains
Unlimited
2.5. Resource Description
A resource description describes resources that the Atomia Automation Server knows about, binding a
resource with a specific module. A resource is defined by a list of properties that helps the system to
determine where to configure a specific service. As explained previously, a resource can be a server, a
file, an ADSL central, etc.
Atomia uses a Resource Description File [$attachmentFilename] to describe available resources for
simple services.
2.6. Module
2.6.1. Understanding the Provisioning module
A module is a plugin used by the Atomia Automation Server to perform actions on a resource. Each module
works with one type of resource. For example, the IIS module configures websites and bindings on a
IIS server resource, the MSSQL module configures databases and database users on a MSSQL server
resource, etc.
Atomia Automation Server
9
The Atomia Automation Server sends a provisioning request to the Provisioning module every time it needs
a service on some resource. Communication between the Atomia Automation Server and the Provisioning
module is based on Service Description XML which describes services that can be or are provisioned.
The provisioning module then parses the request and calls an agent to do the actual provisioning. Then
it returns information about the provisioned service.
The Atomia Automation Server will always send a whole Module Service subtree to the module. E.g. if the
Automation Server wants to add a new service, it will send the appropriate Module Service with all its child
services. The module must make sure the service it received contains all children and whether it should
execute module commands for each one.
2.7. Resource description examples
The Resource Description Examples page shows different ways to create a resource description file.
2.8. Provisioning description examples
Visit the Provisioning Description Examples page to view more examples on how to create Service and
Package description sections.
3. Installation
 Prerequisites
3.1. Prerequisites
To install Atomia Automation Server 1.0 your system must meet following criteria:
 Microsoft Windows Server 2008 or newer [http://www.microsoft.com/windowsserver2008/en/us/
default.aspx] .
 Microsoft .NET Framework 3.5 SP1 [http://www.microsoft.com/downloads/details.aspx?
FamilyID=333325FD-AE52-4E35-B531-508D977D32A6&displaylang=en] .
 Microsoft SQL Server 2008 (Express or better) [http://www.microsoft.com/sqlserver/2008/en/us/] .
 Internet Information Services 7 (IIS 7) [http://www.iis.net/] with Basic and Anonymous authentication
enabled.
 ASP, ASP.NET, .NET Extensibility, ISAPI extensions, ISAPI filters features installed.
4. Usage
 Configuring Communication Channel
 Using Atomia Automation Server Core API
4.1. Configuring Communication Channel
For an explanation on how to create a channel for communication with Atomia Automation Server, please
look at the following pages:
 [WHATIS0100:Connecting to Atomia applications using Basic Authentication]
 [WHATIS0100:Connecting to Atomia applications using Federated Authentication]
4.2. Using Atomia Automation Server Core API
 Introduction
 Sample of using Atomia Automation Server Core API
4.2.1. Introduction
The Atomia Automation Server Core API is an IIS hosted SOAP [http://en.wikipedia.org/wiki/SOAP]
service written using Windows Communication Foundation framework [http://msdn.microsoft.com/en-
Atomia Automation Server
10
us/netframework/aa663324.aspx] . It provides a set of methods for listing, adding, modifying and deleting
accounts, packages and services.
4.2.2. Sample of using Atomia Automation Server Core API
In order to use the Atomia Automation Server Core API, a service reference pointing to the API must be
added to the Microsoft Visual Studio project. Visual Studio will automatically generate necessary classes
to simplify the use of the API. It will also add WCF configuration sections to the configuration file, however,
the WCF configuration must be additionally manually modified so that the API can be used. To read more
about Atomia Automation Server service WCF configuration, please visit the Configuring Communication
Channel . In the following examples it will be shown how to connect to CoreApi, List services, and add
a sample service.
 Create channel
ChannelFactory<ICoreApi> factory = new \
ChannelFactory<AtomiaProvisioning.ICoreApi>("WSFederationHttpBinding_ICoreApi");
\
factory.Credentials.UserName.UserName = -"Administrator";
\
factory.Credentials.UserName.Password = -"Administrator";
\
ICoreApi coreApi = factory.CreateChannel();

 Search specific service
In this example we will search for services with the name MySQLDatabase that are located at CsDatabase/
CsMySqlDatabase (from root) and have utf8_general_ci as a value of the property Collation . This search
will be done for account with ID 300500
long total;
\
ServiceSearchCriteria criteria = new ServiceSearchCriteria();
\
criteria.ParentService = null;
\
criteria.ServiceName = -"MySQLDatabase";
\
criteria.ServicePath = -"CsDatabase/CsMySqlDatabase";
\
criteria.ParentService = null;
\
Dictionary<string, string> props = new Dictionary<string, string>();
\
props["Collation"] = -"utf8_general_ci";
\
var res = coreApi.FindServicesByPathWithPaging(out total, new \
ServiceSearchCriteria[] { criteria -}, props, -"300500", null, true, 0, 10);

 List of services that we can add as root services for a specific account.
var possibleServices = coreApi.ListPossibleServices(null, -"300500");
 Create service, fill properties and add this service.
if (possibleServices.Where(possibleService => possibleService.Name \
== -"CsDomainParking").Count() > 0)
\
{
\
-// Create service CsDomainParking (service is just created with properties \
that needs to be fill.
\
-// Service is not added in system yet.
\
Atomia Automation Server
11
var newlyCreatedService = coreApi.CreateService("CsDomainParking", \
null, -"300500");
\
-// Fill service properties
\
newlyCreatedService["DnsZone"] = -"foocompany.com";
\
newlyCreatedService["Domain"] = -"sell.foocompany.com";
\
newlyCreatedService["DnsZone"] = -"sell";
\
-// Add service on resource
\
var addedService = coreApi.AddService(newlyCreatedService, null, -"300500", \
null);
\
Console.WriteLine("Service with ID -'" + addedService.LogicalID + -"' just \
added");
\
-}

Note: In order to use the indexer for service properties you need to add a reference to
Atomia.Provisioning.Base.dll and to reuse classes from this library when you add service references to
the Atomia Automation Server services.
A demo project for this sample can be downloaded here [$attachmentFilename]
5. Developers Giude
These resources are for software developers who want to extend the Atomia Automation Server system
and/or create their own plugins, extensions and modules for Atomia.
 API and SDK Reference
 Code Examples
 Getting Started
5.1. API and SDK Reference
 Atomia Automation Server APIs
 Atomia Automation Server Core API
 Atomia Automation Server Native API
 Atomia Automation Server Config API
 Atomia Automation Server Authorization API
 Atomia Automation Server SDK
 Full Atomia Automation Server Reference
Here you can find links to the Atomia Automation Server APIs and SDK.
5.1.1. Atomia Automation Server APIs
Atomia Automation Server system provides four APIs: Core API, Config API, Native API and the
Authorization API.
5.1.1.1. Atomia Automation Server Core API
Atomia Automation Server Core API represents main API which exposes a set of methods
for managing accounts, their packages and services. A list of all methods can be found in
the Atomia Automation Server Core API reference [http://doc.atomia.com/provisioning/2.0/html/
Methods_T_Atomia_Provisioning_Service_ICoreApi.htm] .
Atomia Automation Server
12
5.1.1.2. Atomia Automation Server Native API
Atomia Automation Server Native API is a set of methods for bulk operations over accounts,
packages and services. Native API is used for operations over large set of Provisioning objects not
connected to just one account, as Provisioning Core API does. A list of all methods is found in
the Atomia Automation Server Native API reference [http://doc.atomia.com/provisioning/2.0/html/
AllMembers_T_Atomia_Provisioning_Service_INativeApi.htm] .
5.1.1.3. Atomia Automation Server Config API
Atomia Automation Server Config API exposes a set of methods for managing Provisioning descriptions
and Resource descriptions . A list of all methods is found in the Atomia Automation Server Config API
reference [API/Index.html] .
5.1.1.4. Atomia Automation Server Authorization API
Atomia Automation Server Authorization API exploses a set of methods for listing and
setting permissions per user or per user groups. A list of all methods is found in the
Atomia Automation Server Authorization API reference [http://doc.atomia.com/provisioning/2.0/html/
Methods_T_Atomia_Provisioning_Service_IAuthorizationApi.htm] .
5.1.2. Atomia Automation Server SDK
Atomia Automation Server SDK reference links:
 Atomia Automation Server SDK [http://doc.atomia.com/provisioning/2.0/html/
N_Atomia_Provisioning_Base.htm]
 Atomia Automation Server Module SDK [http://doc.atomia.com/provisioning/2.0/html/
N_Atomia_Provisioning_Base_Module.htm]
 Atomia Automation Server Plugin SDK [http://doc.atomia.com/provisioning/2.0/html/
N_Atomia_Provisioning_Base_Plugins.htm]
 Atomia Automation Server Resource Assignment Policy SDK [http://doc.atomia.com/provisioning/2.0/
html/N_Atomia_Provisioning_Base_ResourceAssignmentPolicy.htm]
 Atomia Automation Server Basic Operation layer [http://doc.atomia.com/provisioning/2.0/html/
N_Atomia_Provisioning_BasicOperations.htm]
5.1.3. Full Atomia Automation Server Reference
Atomia Automation Server API reference and Atomia Automation Server SDK can be found on the following
page: Atomia Automation Server Reference [http://doc.atomia.com/provisioning/2.0/Index.html]
5.2. Code Examples
 Atomia Automation Server Modules - Code Examples
 Atomia Automation Server Resource Assignment Policy Agents - Code Examples
5.2.1. Atomia Automation Server Modules - Code Examples
 ModuleBase methods examples
 Provide service example
 Begin transaction example
 Commit transaction example
 Module commands examples
 Add command example
 Remove command example
 Complete module example
Atomia Automation Server
13
5.2.1.1. ModuleBase methods examples
5.2.1.1.1. Provide service example
public void ProvideService(ModuleService service, ResourceDescription \
resource)
\
{
\
this.PrepareCommandList(service, null, resource, null, \
ModuleCommandType.Add);
\
foreach (ModuleCommand command in this.commands)
\
{
\
command.Prepare();
\
-}
\
try
\
{
\
foreach (ModuleCommand command in this.commands)
\
{
\
command.Execute();
\
-}
\
-}
\
catch
\
{
\
-// if something goes wrong during the execution of the commands,
\
-// rollback all performed actions and throw the exception up to the UCPCore
\
RollbackTransaction();
\
throw;
\
-}
\
-}
\
private void PrepareCommandList(ModuleService service, ModuleService \
newServiceSettings, ResourceDescription resource, string commandType)
\
{
\
if (commandType -!= ModuleCommandType.Remove)
\
{
\
this.commands.Add(this.GetModuleCommand(resource, commandType, service, \
newServiceSettings));
\
-}
\
if (service.Children -!= null)
\
{
\
for (int i = 0; i < service.Children.Length; i++)
\
{
\
ModuleService childService = service.Children[i];
\
ModuleService newChildSettings = null;
Atomia Automation Server
14
\
if (newServiceSettings -!= null && newServiceSettings.Children -!= null && \
newServiceSettings.Children.Length > i)
\
{
\
newChildSettings = newServiceSettings.Children[i];
\
-}
\
this.PrepareCommandList(childService, newChildSettings, resource, \
commandType);
\
-}
\
-}
\
if (commandType == ModuleCommandType.Remove)
\
{
\
this.commands.Add(this.GetModuleCommand(resource, targetResource, \
commandType, service, newServiceSettings));
\
-}
\
-}
\
private ModuleCommand GetModuleCommand(ResourceDescription resource, \
string commandType, params ModuleService[] childService)
\
{
\
ModuleCommand command = null;
\
switch (commandType)
\
{
\
case ModuleCommandType.Add:
\
switch (childService[0].Name)
\
{
\
case ModuleServiceName.LiteSpeedWebSite:
\
command = new AddLiteSpeedWebSiteCommand(childService[0], resource);
\
break;
\
case ModuleServiceName.LiteSpeedListener:
\
command = new AddLiteSpeedListenerCommand(childService[0], resource);
\
break;
\
-....
\
-}
\
break;
\
case ModuleCommandType.Remove:
\
switch (childService[0].Name)
\
{
\
case ModuleServiceName.LiteSpeedWebSite:
\
command = new RemoveLiteSpeedWebSiteCommand(childService[0], resource);
\
break;
\
case ModuleServiceName.LiteSpeedListener:
\
Atomia Automation Server
15
command = new RemoveLiteSpeedListenerCommand(childService[0], resource);
\
break;
\
-....
\
-}
\
break;
\
case ModuleCommandType.Modify:
\
switch (childService[0].Name)
\
{
\
case ModuleServiceName.LiteSpeedWebSite:
\
command = new ModifyWebSiteCommand(childService[0], resource, \
childService[1]);
\
break;
\
case ModuleServiceName.LiteSpeedListener:
\
command = new ModifyLiteSpeedListenerCommand(childService[0], resource, \
childService[1]);
\
break;
\
-....
\
-}
\
break;
\
-}
\
return command;
\
-}

5.2.1.1.2. Begin transaction example
public void BeginTransaction()
\
{
\
if (this.commands.Count > 0)
\
{
\
throw ExceptionHelper.GetModuleException("ID400002", null, null);
\
-}
\
-}

5.2.1.1.3. Commit transaction example
public void CommitTransaction()
\
{
\
foreach (ModuleCommand command in this.commands)
\
{
\
command.CleanUp();
\
-}
\
Atomia Automation Server
16
this.commands.Clear();
\
-}
\
h3. Rollback transaction example
\
{newcode:csharp}public void RollbackTransaction()
\
{
\
int size = this.commands.Count;
\
for (int i = size -- 1; i >= 0; i--)
\
{
\
if (this.commands[i].Status == ModuleCommandStatus.Executed)
\
{
\
this.commands[i].Undo();
\
-}
\
this.commands[i].CleanUp();
\
-}
\
this.commands.Clear();
\
-}

5.2.1.2. Module commands examples
5.2.1.2.1. Add command example
internal class AddLiteSpeedWebSiteCommand -: ModuleCommand
\
{
\
-/// <summary>
\
-/// Initializes a new instance of the <see \
cref="AddLiteSpeedWebSiteCommand"/> class.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <param name="resource">Server resource.</param>
\
public AddLiteSpeedWebSiteCommand(ModuleService service, \
ResourceDescription resource) -: base(service, resource)
\
{
\
-}
\
-/// <summary>
\
-/// Prepares everything to be able to call undo and validate data.
\
-/// </summary>
\
public override void Prepare()
\
{
\
LSValidation.ValidateWebSiteProperties(this.service);
\
-}
\
-/// <summary>
\
Atomia Automation Server
17
-/// Executes this command.
\
-/// </summary>
\
public override void Execute()
\
{
\
this.status = LiteSpeedHelperMethods.AddWebSite(this.service, \
this.resource);
\
-}
\
-/// <summary>
\
-/// Undoes this command.
\
-/// </summary>
\
public override void Undo()
\
{
\
LiteSpeedHelperMethods.RemoveLiteSpeedWebSite(this.service, this.resource);
\
-}
\
-/// <summary>
\
-/// Cleans up.
\
-/// </summary>
\
public override void CleanUp()
\
{
\
-}
\
-}

5.2.1.2.2. Remove command example
internal class RemoveLiteSpeedWebSiteCommand -: ModuleCommand
\
{
\
-/// <summary>
\
-/// Initializes a new instance of the <see \
cref="RemoveLiteSpeedWebSiteCommand"/> class.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <param name="resource">Server resource.</param>
\
public AddLiteSpeedWebSiteCommand(ModuleService service, \
ResourceDescription resource) -: base(service, resource)
\
{
\
-}
\
-/// <summary>
\
-/// Prepares everything to be able to call undo and validate data.
\
-/// </summary>
\
public override void Prepare()
\
{
Atomia Automation Server
18
\
-}
\
-/// <summary>
\
-/// Executes this command.
\
-/// </summary>
\
public override void Execute()
\
{
\
this.status = LiteSpeedHelperMethods.RemoveWebSite(this.service, \
this.resource);
\
-}
\
-/// <summary>
\
-/// Undoes this command.
\
-/// </summary>
\
public override void Undo()
\
{
\
LiteSpeedHelperMethods.AddLiteSpeedWebSite(this.service, this.resource);
\
-}
\
-/// <summary>
\
-/// Cleans up.
\
-/// </summary>
\
public override void CleanUp()
\
{
\
-}
\
-}

5.2.1.3. Complete module example
This example represents a simple implementation of a provisioning module which "provisions" file and
folder services. This example is also downloadable as a full Microsoft Visual Studio 2008 project here:
Atomia.Examples.Modules.FolderMapper [$attachmentFilename] .
-/// <summary>
\
-/// Folder mapper agent.
\
-/// </summary>
\
public class FolderMapperAgent -: ModuleBase
\
{
\
-/// <summary>
\
-/// Action executed.
\
-/// </summary>
\
private Action action;
\
-/// <summary>
\
-/// Root folder for creating folder-service structure.
\
Atomia Automation Server
19
-/// </summary>
\
private string rootFolder;
\
-/// <summary>
\
-/// List of files and folders that was created/deleted.
\
-/// </summary>
\
private List<FileContent> actions;
\
-/// <summary>
\
-/// Initializes a new instance of the FolderMapperAgent class.
\
-/// </summary>
\
public FolderMapperAgent()
\
{
\
this.actions = new List<FileContent>();
\
string configFilePath = \
Path.GetDirectoryName(Assembly.GetAssembly(typeof(FolderMapperAgent)).Location) + -"\
\FolderMapper.txt";
\
try
\
{
\
-// Create an instance of StreamWriter to write text to a file.
\
using (StreamReader sr = new StreamReader(configFilePath))
\
{
\
this.rootFolder = sr.ReadLine();
\
-}
\
-}
\
catch
\
{
\
this.rootFolder = -"c:\\";
\
-}
\
-}
\
-/// <summary>
\
-/// Module actions type.
\
-/// </summary>
\
private enum Action
\
{
\
-/// <summary>
\
-/// Create service action.
\
-/// </summary>
\
Create,
\
-/// <summary>
\
-/// Delete service action.
\
-/// </summary>
Atomia Automation Server
20
\
Delete,
\
-/// <summary>
\
-/// Modify service action.
\
-/// </summary>
\
Modify
\
-}
\
-/// <summary>
\
-/// Service type. Document or folder.
\
-/// </summary>
\
private enum FileFolder
\
{
\
-/// <summary>
\
-/// File type.
\
-/// </summary>
\
File,
\
-/// <summary>
\
-/// Folder type.
\
-/// </summary>
\
Folder
\
-}
\
#region ModuleBase Members
\
-/// <summary>
\
-/// Begins transaction. After this method is executed and before <see \
cref="CommitTransaction"/> or <see cref="RollbackTransaction"/> method, only one method \
must be called.
\
-/// </summary>
\
public void BeginTransaction()
\
{
\
this.actions.Clear();
\
-}
\
-/// <summary>
\
-/// Commits transaction. Successfully finishes transaction.
\
-/// </summary>
\
public void CommitTransaction()
\
{
\
this.actions.Clear();
\
-}
\
-/// <summary>
\
-/// Rollbacks transaction. Cancel transaction and rolls back in case of an \
error.
Atomia Automation Server
21
\
-/// </summary>
\
public void RollbackTransaction()
\
{
\
switch (this.action)
\
{
\
case Action.Create:
\
{
\
-// delete all created file/folers
\
int size = this.actions.Count;
\
for (int i = size -- 1; i >= 0; i--)
\
{
\
FileContent fc = this.actions[i];
\
if (fc.fileFolder == FileFolder.File)
\
{
\
System.IO.File.Delete(fc.fileName);
\
-}
\
else if (fc.fileFolder == FileFolder.Folder)
\
{
\
System.IO.Directory.Delete(fc.fileName, true);
\
-}
\
-}
\
-}
\
break;
\
case Action.Delete:
\
{
\
int size = this.actions.Count;
\
for (int i = 0; i < size; i++)
\
{
\
FileContent fc = this.actions[i];
\
if (fc.fileFolder == FileFolder.File)
\
{
\
using (StreamWriter sw = new StreamWriter(fc.fileName, false))
\
{
\
sw.WriteLine(fc.content);
\
-}
\
-}
\
else if (fc.fileFolder == FileFolder.Folder)
\
{
\
Atomia Automation Server
22
System.IO.Directory.CreateDirectory(fc.fileName);
\
-}
\
-}
\
-}
\
break;
\
case Action.Modify:
\
{
\
foreach (FileContent fc in this.actions)
\
{
\
if (fc.fileFolder == FileFolder.File)
\
{
\
using (StreamWriter sw = new StreamWriter(fc.fileName, false))
\
{
\
sw.WriteLine(fc.content);
\
-}
\
-}
\
-}
\
-}
\
break;
\
default:
\
break;
\
-}
\
this.actions.Clear();
\
-}
\
-/// <summary>
\
-/// Provides specific service.
\
-/// </summary>
\
-/// <param name="service">Module service to provide.</param>
\
-/// <param name="resource">Resource associated with this service.</param>
\
public void ProvideService(ModuleService service, ResourceDescription \
resource)
\
{
\
this.action = Action.Create;
\
-// create resource folder if it does not exist.
\
string currentFolder;
\
Stack<string> pathStack;
\
this.GetFolderPath4Service(service.Parent, resource, out currentFolder, out \
pathStack);
\
-// we should have all folders till new one
\
if (!System.IO.Directory.Exists(currentFolder))
Atomia Automation Server
23
\
{
\
throw new ModuleException("Cannot find folder with name -" + currentFolder);
\
-}
\
-// we have all necessery folders. we should create new one
\
currentFolder += this.GetFolderName(service) + -"\\";
\
-// if it is exist it is an error
\
if (System.IO.Directory.Exists(currentFolder))
\
{
\
-// throw new Atomia.Provisioning.Base.Exceptions.ModuleException("Service \
already exist. Service path: -" + currentFolder);
\
-}
\
else
\
{
\
System.IO.Directory.CreateDirectory(currentFolder);
\
-}
\
FileContent fc = new FileContent();
\
fc.fileFolder = FileFolder.Folder;
\
fc.fileName = currentFolder;
\
this.actions.Add(fc);
\
-// write folder properties
\
-// prepear string
\
string propertyFileText = CreatePropertiesFileText(service);
\
-// write to file
\
using (StreamWriter sw = new StreamWriter(currentFolder + -"properties.txt", \
false))
\
{
\
sw.WriteLine(propertyFileText);
\
-}
\
fc = new FileContent();
\
fc.fileFolder = FileFolder.File;
\
fc.fileName = currentFolder + -"properties.txt";
\
this.actions.Add(fc);
\
-}
\
-/// <summary>
\
-/// Creates the properties file text.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <returns>Property file text.</returns>
\
private static string CreatePropertiesFileText(ModuleService service)
\
Atomia Automation Server
24
{
\
string propertyFileText = string.Empty;
\
foreach (ModuleServiceProperty property in service.GetAllProperties())
\
{
\
propertyFileText += property.Name + -"=" + property.Value + -"\r\n";
\
-}
\
return propertyFileText;
\
-}
\
-/// <summary>
\
-/// Gets the folder path4 service.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <param name="resource">The resource.</param>
\
-/// <param name="currentFolder">The current folder.</param>
\
-/// <param name="pathStack">The path stack.</param>
\
private void GetFolderPath4Service(ModuleService service, \
ResourceDescription resource, out string currentFolder, out Stack<string> pathStack)
\
{
\
pathStack = new Stack<string>();
\
string resourceFolder = this.GetFolderName(resource);
\
pathStack.Push(resourceFolder);
\
currentFolder = this.rootFolder + resourceFolder + -"\\";
\
ModuleService currentService = service;
\
string reversePath = string.Empty;
\
while (currentService -!= null)
\
{
\
pathStack.Push(this.GetFolderName(currentService));
\
reversePath = this.GetFolderName(currentService) + -"\\" + reversePath;
\
currentService = currentService.Parent;
\
-}
\
currentFolder += reversePath;
\
-}
\
-/// <summary>
\
-/// Removes specific service from the resource.
\
-/// </summary>
\
-/// <param name="service">Module service to remove.</param>
\
-/// <param name="resource">Resource associated with this service</param>
\
public void RemoveService(ModuleService service, ResourceDescription resource)
\
{
\
Atomia Automation Server
25
this.action = Action.Delete;
\
string currentFolder;
\
Stack<string> pathStack;
\
this.GetFolderPath4Service(service, resource, out currentFolder, out \
pathStack);
\
-// we should have all folders
\
if (!System.IO.Directory.Exists(currentFolder))
\
{
\
throw new ModuleException("Cannot find folder with name -" + currentFolder);
\
-}
\
-// current folder should not have subfolders
\
if (System.IO.Directory.GetDirectories(currentFolder).Length > 0)
\
{
\
throw new ModuleException("Child services exist. Currnet folder for \
delete: -" + currentFolder);
\
-}
\
System.IO.Directory.Delete(currentFolder, true);
\
FileContent fc = new FileContent();
\
fc.fileFolder = FileFolder.Folder;
\
fc.fileName = currentFolder;
\
this.actions.Add(fc);
\
string propertyFileText = CreatePropertiesFileText(service);
\
fc = new FileContent();
\
fc.fileFolder = FileFolder.File;
\
fc.fileName = currentFolder + -"properties.txt";
\
fc.content = propertyFileText;
\
this.actions.Add(fc);
\
-}
\
-/// <summary>
\
-/// Modifies given module service.
\
-/// </summary>
\
-/// <param name="service">Module service containing old service properties \
and settings.</param>
\
-/// <param name="resource">Resource associated with this service.</param>
\
-/// <param name="newServiceSettings">New service settings.</param>
\
public void ModifyService(ModuleService service, ResourceDescription \
resource, ModuleService newServiceSettings)
\
{
\
this.action = Action.Modify;
\
string currentFolder;
\
Stack<string> pathStack;
Atomia Automation Server
26
\
this.GetFolderPath4Service(service, resource, out currentFolder, out \
pathStack);
\
-// we should have all folders
\
if (!System.IO.Directory.Exists(currentFolder))
\
{
\
throw new ModuleException("Cannot find folder with name -" + currentFolder);
\
-}
\
string propertyFileText = string.Empty;
\
foreach (ModuleServiceProperty property in service.GetAllProperties())
\
{
\
propertyFileText += property.Name + -"=" + property.Value + -"\r\n";
\
-}
\
using (StreamReader sr = new StreamReader(currentFolder + -"properties.txt"))
\
{
\
FileContent fc = new FileContent();
\
fc.fileFolder = FileFolder.File;
\
fc.fileName = currentFolder + -"properties.txt";
\
fc.content = sr.ReadToEnd();
\
this.actions.Add(fc);
\
-}
\
-// write to file
\
using (StreamWriter sw = new StreamWriter(currentFolder + -"properties.txt", \
false))
\
{
\
sw.WriteLine(propertyFileText);
\
-}
\
-}
\
-/// <summary>
\
-/// Moves service from one resource to another. Module should also remove \
all related child and parent simple service resources.
\
-/// If this operation failed, module must rollback service status as before.
\
-/// </summary>
\
-/// <param name="service">Service that should change resource location.</
param>
\
-/// <param name="currentResource">Resource where service is currently \
located.</param>
\
-/// <param name="targetResource">Resource where service will be moved.</
param>
\
public void MoveToResource(ModuleService service, ResourceDescription \
currentResource, ResourceDescription targetResource)
\
{
\
-// TODO add code for moving resources
Atomia Automation Server
27
\
-}
\
-/// <summary>
\
-/// Lists the services no children.
\
-/// </summary>
\
-/// <param name="serviceName">Name of the service.</param>
\
-/// <param name="targetResource">The target resource.</param>
\
-/// <returns></returns>
\
public List<ModuleService> ListServicesNoChildren(string serviceName, \
ResourceDescription targetResource)
\
{
\
return null;
\
-}
\
-/// <summary>
\
-/// Lists the services.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <param name="maxDepth">The max depth.</param>
\
-/// <param name="targetResource">The target resource.</param>
\
-/// <returns></returns>
\
public ModuleService ListServices(ModuleService service, int maxDepth, \
ResourceDescription targetResource)
\
{
\
return service;
\
-}
\
-/// <summary>
\
-/// Calls the operation.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <param name="operationName">Name of the operation.</param>
\
-/// <param name="operationArgument">The operation argument.</param>
\
-/// <param name="targetResource">The target resource.</param>
\
-/// <returns></returns>
\
public string CallOperation(ModuleService service, string operationName, \
string operationArgument, ResourceDescription targetResource)
\
{
\
return string.Empty;
\
-}
\
-/// <summary>
\
-/// Gets the service description of services supported by this module. Root \
element of this XML is simpleServiceList node.
\
Atomia Automation Server
28
-/// </summary>
\
-/// <returns>Module service description.</returns>
\
public string GetModuleServiceDescription()
\
{
\
return null;
\
-}
\
#endregion
\
#region IDisposable Members
\
-/// <summary>
\
-/// Performs application-defined tasks associated with freeing, releasing, \
or resetting unmanaged resources.
\
-/// </summary>
\
public void Dispose()
\
{
\
throw new NotImplementedException();
\
-}
\
#endregion
\
-/// <summary>
\
-/// Gets the name of the folder.
\
-/// </summary>
\
-/// <param name="resource">The resource.</param>
\
-/// <returns></returns>
\
private string GetFolderName(ResourceDescription resource)
\
{
\
return resource.Name;
\
-}
\
-/// <summary>
\
-/// Gets the name of the folder.
\
-/// </summary>
\
-/// <param name="service">The service.</param>
\
-/// <returns></returns>
\
private string GetFolderName(ModuleService service)
\
{
\
string folderName = service.Name;
\
folderName += -" -" + service.PhysicalID;
\
return folderName;
\
-}
\
-/// <summary>
\
-/// File content structure.
\
Atomia Automation Server
29
-/// </summary>
\
private struct FileContent
\
{
\
public string fileName;
\
public string content;
\
public FileFolder fileFolder;
\
-};
\
-}

5.2.2. Atomia Automation Server Resource Assignment Policy Agents - Code Examples
 Atomia Provisioning Resource Assignment Policy Agents example
5.2.2.1. Atomia Provisioning Resource Assignment Policy Agents example
This is an example Resource Assignment Policy Agent. It implements the DefaultResource policy for
resource assignment. This example is also available for download as a working Microsoft Visual Studio
2008 project here: Atomia.Examples.RAPA.DefaultResource [$attachmentFilename] .
-/// <summary>
\
-/// Atomia DefaultResource resource assignment plug-in
\
-/// </summary>
\
public class DefaultResourcePolicyPlugin -: ResourceAssignmentPolicyAgentBase
\
{
\
-/// <summary>
\
-/// Resource description manager. Needed to get list of available resources \
for specific service.
\
-/// </summary>
\
private IResourceDescriptionManager resourceDescriptionManager;
\
-/// <summary>
\
-/// Service context resolver. Provides the context for the service.
\
-/// </summary>
\
private IServiceContextResolver serviceContextResolver;
\
#region IResourceAssignmentPolicyAgent Members
\
-/// <summary>
\
-/// Gets or sets a name of the resource assignment policy that realizes \
this agent.
\
-/// </summary>
\
-/// <value>The name of the policy.</value>
\
public override string PolicyName
\
{
\
get { return -"DefaultResource"; -}
\
protected set { -}
\
-}
Atomia Automation Server
30
\
-/// <summary>
\
-/// Initializes resource assignment policy agent.
\
-/// </summary>
\
public override void Init()
\
{
\
-}
\
-/// <summary>
\
-/// Gets the resource.
\
-/// </summary>
\
-/// <param name="moduleName">Name of the module.</param>
\
-/// <param name="accountId">The account id of the service.</param>
\
-/// <param name="service">The service which needs to be provisioned.</param>
\
-/// <param name="resourceRequest">Null or <see \
cref="ResourceRequestDescription"/> object that can help this agent to make decision.</
param>
\
-/// <param name="resourceHelperProvider">The resource helper provider.</
param>
\
-/// <returns>
\
-/// Resource description of resource that will be used for hosting \
<paramref name="service"/>.
\
-/// </returns>
\
public override ResourceDescription GetResource(
\
string moduleName,
\
string accountId,
\
ProvisioningService service,
\
ResourceRequestDescription resourceRequest,
\
ResourceHelperProviderBase resourceHelperProvider)
\
{
\
this.serviceContextResolver = \
resourceHelperProvider.GetHelper<IServiceContextResolver>();
\
-// get the provisioning description
\
string provDescription = service.ProvisioningDescription;
\
if (String.IsNullOrEmpty(provDescription))
\
{
\
provDescription = \
this.serviceContextResolver.GetProvisioningDescriptionVersionName(service);
\
-}
\
-// create provisioning description -- package string
\
string provDescPackage = provDescription + -"." + \
this.serviceContextResolver.GetPackageName(service);
\
ResourceDescription resDescription = null;
\
if (String.IsNullOrEmpty(moduleName))
Atomia Automation Server
31
\
{
\
throw new ArgumentNullException("moduleName", -"Module name cannot be null.");
\
-}
\
-// get resources for the module and specified policy
\
this.resourceDescriptionManager = \
resourceHelperProvider.GetResourceDescriptionManager(this.ResourceDescriptionManagerName);
\
ResourceDescription[] resourcesDescriptions = \
this.resourceDescriptionManager.GetResources(accountId, moduleName, this.PolicyName);
\
if (resourcesDescriptions.Length < 1)
\
{
\
return null;
\
-}
\
int i = 0;
\
bool finish = false;
\
-// find first resource which can be default for the service
\
while ((i < resourcesDescriptions.Length) && (!finish))
\
{
\
List<ResourceDescriptionPropertyList> propertyList = \
resourcesDescriptions[i].PropertyList.FindAll(pl => pl.PropertyListName \
== -"DefaultResource.Packages");
\
if (propertyList.Count > 0)
\
{
\
if (propertyList[0].PropertyListItems.FindAll(pli => pli == \
provDescPackage).Count > 0)
\
{
\
resDescription = resourcesDescriptions[i];
\
finish = true;
\
-}
\
-}
\
i++;
\
-}
\
-// if none is chosen, choose default one
\
if (resDescription == null)
\
{
\
foreach (ResourceDescription resourcesDescription in resourcesDescriptions)
\
{
\
string isDefault = resourcesDescription["DefaultResource.Default"];
\
if (isDefault -!= null && isDefault.ToLowerInvariant() == -"true")
\
{
\
return resourcesDescription;
\
-}
Atomia Automation Server
32
\
-}
\
-}
\
-// if none is chosen, choose first
\
if (resDescription == null)
\
{
\
resDescription = resourcesDescriptions[0];
\
-}
\
return resDescription;
\
-}
\
#endregion
\
-}

5.3. Getting Started
 Atomia Automation Server Action Hooks
 Atomia Automation Server Modules
 Atomia Automation Server Resource Assignment Policy Agents
 How to obtain Atomia Automation Server SDKs
5.3.1. Atomia Automation Server Action Hooks
 Introduction
 Classes used in action hooks development
 Class ActionHookBase2 [32]
 Creating action hook
 Installing Resource Assignment Policy Agent
5.3.1.1. Introduction
Atomia Automation Server allows developers to write action hooks. With action hooks, you can add your
own code that will run when specific actions occur within the provisioning system. Using action hooks
allows developers to extend the functionality of the Atomia Automation Server.
At the moment the following events are monitored:
 OnBeforeAddService - Occurs before a service is being added to the Provisioning system.
 OnBeforeChangePackage - Occurs before an account package is changed.
 OnBeforeSwitchService - Occurs before a service is replaced with another one.
5.3.1.2. Classes used in action hooks development
Class ActionHookBase2
Abstract class all classes must inherit in order to be able to be injected in provisioning process.
Atomia Automation Server
33
5.3.1.3. Creating action hook
All action hooks must inherit the ActionHookBase2 [http://doc.atomia.com/provisioning/2.0/html/
T_Atomia_Provisioning_Base_Plugins_ActionHookBase2.htm] class.
-/// <summary>
\
-/// The base class that should be derived for implementing action hooks
\
-/// </summary>
\
public abstract class ActionHookBase2
\
{
\
-/// <summary>
\
-/// Gets or sets the tag. THIS IS FOR SYSTEM USE. DO NOT CHANGE THIS \
PROPERTY;
\
-/// </summary>
\
public object Tag { get; set; -}
\
-/// <summary>
\
-/// Gets or sets the action hook bridge. It is used to acquire plug-ins \
necessary interfaces.
\
-/// </summary>
\
protected ActionHookBridgeBase ActionHookBridge { get; set; -}
\
-/// <summary>
\
-/// Initializes the specified action hook bridge base.
\
-/// </summary>
\
-/// <param name="actionHookBridgeBase">The action hook bridge.</param>
\
public virtual void Init(ActionHookBridgeBase actionHookBridgeBase)
\
{
\
this.ActionHookBridge = actionHookBridgeBase;
\
-}
\
-/// <summary>
\
-/// Called before adding service. Services are prepared for adding but not \
added to database or on resource, yet.
\
-/// </summary>
\
-/// <param name="service">The service that has to be added. It is instance \
of <c>UcpServiceLogical</c> class.</param>
\
-/// <param name="argument">The argument string from configuration.</param>
\
-/// <param name="overridesDefaultBehavior">If set to <c>true</c> plug-in \
will override default behavior of provisioning.</param>
\
public virtual void OnBeforeAddService(Service service, string argument, out \
bool overridesDefaultBehavior)
\
{
\
overridesDefaultBehavior = false;
\
-}
\
-/// <summary>
\
Atomia Automation Server
34
-/// Called before changing a package.
\
-/// </summary>
\
-/// <param name="package">The existing package. It is instance of \
<c>Package</c> class.</param>
\
-/// <param name="newPackageName">Name of the new package.</param>
\
-/// <param name="argument">The argument string from configuration.</param>
\
-/// <param name="overridesDefaultBehavior">If set to <c>true</c> plug-in \
will override default behavior of changing package.</param>
\
-/// <returns>New package instance.</returns>
\
public virtual Package OnBeforeChangePackage(Package package, string \
newPackageName, string argument, out bool overridesDefaultBehavior)
\
{
\
overridesDefaultBehavior = false;
\
return null;
\
-}
\
-/// <summary>
\
-/// Called before switch service.
\
-/// </summary>
\
-/// <param name="service">The service to change.</param>
\
-/// <param name="newServiceName">New name of the service.</param>
\
-/// <param name="arguments">The arguments passed from API.</param>
\
-/// <param name="configurationArgument">The configuration argument from \
configuration file.</param>
\
-/// <param name="overridesDefaultBehavior">If set to <c>true</c> overrides \
default behavior.</param>
\
-/// <returns>New service instance.</returns>
\
public virtual Service OnBeforeSwitchService(Service service, string \
newServiceName, Dictionary<string, string> arguments, string configurationArgument, out \
bool overridesDefaultBehavior)
\
{
\
overridesDefaultBehavior = false;
\
return null;
\
-}
\
-/// <summary>
\
-/// Return instance event if it is under proxy
\
-/// </summary>
\
-/// <returns>Instance of <see cref="ActionHookBase2"/>.</returns>
\
public virtual ActionHookBase2 This()
\
{
\
return this;
\
-}
\
-}
Atomia Automation Server
35

5.3.1.3.1. Installing Resource Assignment Policy Agent
In order to use the newly created Action Hook, the following steps must be followed:
1.Build Action Hook project.
2.Open any file explorer (Windows Explorer i.e.) and navigate to the Atomia Provisioning installation
folder.
3.Copy Action Hook and all other needed libraries to the following folder: Atomia Automation Server
installation folder (usually : C:\Program Files (x86)\Atomia\AutomationServer)\Web\bin
5.3.2. Atomia Automation Server Modules
 Introduction
 Classes used in module development
 Class ModuleService [35]
 Class ModuleServiceProperty [35]
 Class ResourceDescription [35]
 Creating a Provisioning Module
 Installing Provisioning Modules
 Transaction model
 Recommendations
 Examples
5.3.2.1. Introduction
The p rovisioning module is a plugin written using .NET framework. It does the actual provisioning of
services on a specific resource such as a web server, database, DNS, etc.
Each module is specified to work with one type of resource. For example, IISModule is in charge of
provisioning and managing services on the Microsoft IIS platform.
5.3.2.2. Classes used in module development
Class ModuleService
ModuleService class is used to describe services that have been, or will be, provisioned by the
module.
Class ModuleServiceProperty
Represents a property of a service that was, or will be, provisioned by the module.
Class ResourceDescription
Objects of this class are used to specify the resource where provisioning operations should be done.
5.3.2.3. Creating a Provisioning Module
1.Download Atomia Provisioning SDK, Atomia Provisioning Module SDK and Atomia Provisioning Module
template project for Microsoft Visual Studio 2008 [$attachmentFilename] . Instructions on how to obtain
SDKs can be found on How to obtain Atomia Automation Server SDKs .
1.Create a new project in Visual Studio.
Atomia Automation Server
36
a.Project type should be Class Library project.
2.Add a reference to Atomia.Provisioning.Base and Atomia.Provisioning.Base.Module libraries.
3.Classes that should represent a module must inherit the ModuleBase class.
The simplest implementation of a module class would be:
public class SimpleModule -: ModuleBase
\
{
\
-/// <summary>
\
-/// Begins transaction. After this method is executed and before <see \
cref="CommitTransaction"/> or <see cref="RollbackTransaction"/> method, only one method \
must be called.
\
-/// </summary>
\
void BeginTransaction()
\
{
\
-// start transaction
\
-}
\
-/// <summary>
\
-/// Commits transaction. Successfully finishes transaction.
\
-/// </summary>
\
void CommitTransaction()
\
{
\
-// do cleaning up and commit transaction
\
-}
\
-/// <summary>
\
-/// Rollbacks transaction. Cancel transaction and rolls back in case of an \
error.
\
-/// </summary>
\
void RollbackTransaction()
\
{
\
-// put code for reverting resource into previous state in case of \
provisioning failure
\
-}
\
-/// <summary>
\
-/// Provides specific service.
\
-/// </summary>
\
-/// <param name="service">Module service to provide.</param>
\
-/// <param name="resource">Resource associated with this service.</param>
\
void ProvideService(ModuleService service, ResourceDescription resource)
\
{
\
-// add some code for provisioning services on resource
\
Atomia Automation Server
37
-}
\
-/// <summary>
\
-/// Removes specific service from the resource.
\
-/// </summary>
\
-/// <param name="service">Module service to remove.</param>
\
-/// <param name="resource">Resource associated with this service</param>
\
void RemoveService(ModuleService service, ResourceDescription resource)
\
{
\
-// add some code for removing specific services from resources
\
-}
\
-/// <summary>
\
-/// Modifies given module service.
\
-/// </summary>
\
-/// <param name="service">Module service containing old service properties \
and settings.</param>
\
-/// <param name="resource">Resource associated with this service.</param>
\
-/// <param name="newServiceSettings">New service settings.</param>
\
void ModifyService(ModuleService service, ResourceDescription resource, \
ModuleService newServiceSettings)
\
{
\
-// add some code for modifying specific services on resource
\
-}
\
-/// <summary>
\
-/// Moves service from one resource to another. Module should also remove \
all related child and parent simple service resources.
\
-/// If this operation failed, module must rollback service status as before.
\
-/// </summary>
\
-/// <param name="service">Service that should change resource location.</
param>
\
-/// <param name="currentResource">Resource where service is currently \
located.</param>
\
-/// <param name="targetResource">Resource where service will be moved.</
param>
\
void MoveToResource(ModuleService service, ResourceDescription \
currentResource, ResourceDescription targetResource)
\
{
\
-// implement logic for moving service from one resource to another one
\
-}
\
-/// <summary>
\
-/// Lists all services with the name <paramref name="serviceName"/> on the \
specific resource without linking them with their child services.
\
-/// </summary>
\
Atomia Automation Server
38
-/// <param name="serviceName">Name of the root simple service. If required \
service is not root exception will be thrown.</param>
\
-/// <param name="resource">The resource description of resource where \
services are located.</param>
\
-/// <returns>List of services.</returns>
\
List<ModuleService> ListServicesNoChildren(string serviceName, \
ResourceDescription resource)
\
{
\
-// implement logic for returning all root services with given name
\
-}
\
-/// <summary>
\
-/// Creates service tree for specific service. This function should create \
tree structure of children for specific service.
\
-/// </summary>
\
-/// <param name="service">Specific service for which to build a service \
tree.</param>
\
-/// <param name="maxDepth">Maximum depth of services. If this value is --1 \
module should list all children services.</param>
\
-/// <param name="resource">The resource description of resource where is \
service located.</param>
\
-/// <returns>Service with connected children tree structure.</returns>
\
ModuleService ListServices(ModuleService service, int maxDepth, \
ResourceDescription resource)
\
{
\
-// implement logic for listing children subtree of a given service
\
-}
\
-/// <summary>
\
-/// Calls the specified operation on specific service.
\
-/// </summary>
\
-/// <param name="service">Specified service.</param>