Parallels H-Sphere Documentation Developer Guide

 

Creating Resources for Winbox

 

Last modified: 28 Dec 2007

 

WARNING: This documentation covers Parallels H-Sphere versions up to 3.1. For the latest up-to-date Parallels H-Sphere documentation, please proceed to the official Parallels site.

Introduction

In terms of H-Sphere, any resource on a Windows server can be considered as a module (or a group of modules), and has to support the following functionalities:
- create and delete a physical resource;
- read and change parameters of the physical resource.
By physical resource, we mean any resource of the OS (IP address, account, etc), or additional software used as a part of the hosting service. Different physical resources can have the same functionality in terms of hosting (even if they are implemented in completely different ways), like Serv-U FTP server and MS FTP Server. Even for the same software, different versions of the physical resource implementation can exist with different functionality. As a result, each H-Sphere resource can have several implementations, i.e. modules working with a particular implementation of a physical resource. Yet, only one implementation of a particular H-Sphere resource can be active at a time. To put it simply, we will be using a resource to describe its physical implementation.

 

Requirements

To implement a new resource, the following is required:
- .NET Framework version 1.0.3705 and higher
- H-Sphere Windows package Installed or Psoft.HSphere.dll assembly available
You can use any .NET compatible language. Yet, since the core part of H-Sphere winbox is written in C#, all examples will be presented in C#.

 

Naming conventions

We recommend using the following naming conventions when developing new resources.

Namespaces

All resources should belong to Psoft.Hsphere.Resources or to namespaces inside it. If there are several implementations of the same resource, they should be placed in the same namespace.

Assemblies

The name of the assembly should have the following format:
Resources.<Resource class name> if assembly contains class of only one resource and the resource is located directly in the namespace Psoft.HSphere.Resources (e.g.: Resources.Diskquota for resource Psoft.HSphere.Resources.DiskQuota) Resources.<Namespace Name> if assembly contains several resources in this namespace. (e.g.: Resource.IIS.ColdFusion for the implementation of different versions of the ColdFusion resource)

Attributes

All names in attributes (logical name of the resource, physical name, parameter names in schemas) should be typed in lower case.

 

General Scheme of work for the resource

Each resource has a logical name known to the CP. If there are several implementations of the same resource, only one can be active at one time. The implementation is defined in the config file. The implementation of the resources should be in separate non-core assemblies that will be loaded dynamically. The class that implements resource and its assembly is defined in the config file. Also, in the config file, the attributes of the resource are defined, and each instance of the resource will get those attributes in addition to parameters. The attributes should represent constant parameters for a given implementation that are common for all instanaces. The resource (group of resources) has to be implemented as a public class (classes), inherited from abstract class Psoft.HSphere.Resources.Resource that can be found in the Psoft.HSphere.dll assembly and implemented as class library assembly. To do that, you need to add references to Psoft.HSphere.dll assembly during the compilation using option/reference.

Class Psoft.HSphere.Resources.Resource defines the set of methods that have to be implemented by the inherited resource:

public abstract void Create();
public abstract void Get();
public abstract void Update(Parameters newParams);
public abstract void Delete();
public abstract void Suspend();
public abstract void Resume();

The names of the methods describe their functionality (more details below). Besides that, each resource inherits a collection of parameteres from the abstract parent of the Psoft.HSphere.Transport.Protocols.Parameters type. That collection is expressed as a hash table, and the values of parameters can be retrieved via the parameter names. When a particular operation is executed on the resource (like create, delete, update parameters... etc), H-Sphere Windows engine creates instance of the corresponding resource and sets values for the parameters as they were passed from the CP. Besides that, the resource can have a collection of configurable attributes, which are defined in H-Sphere config file. H-Sphere Windows engine adds the attributes into collection of parameters as well. After that, the corresponding method is called on the resource. Due to that, during the call of any of those methods, instance of the resource has all the required information to perform the operation.

During the development of the resource, you have to consider that resource does not support statuses, and you should not save any type of info in the instance of the resource, as it can be destroyed as soon as the method is executed.

 

Methods

The above methods have to be implemented, as they are defined as abstract.

void Create()

This code should implement physical creation of the resource. Parameteres required to create the resource will be passed as parameters collection. The number and names of parameters are defined by specifics of physical resource and set in special attributes-schemas (defined later in this document).

void Get()

This method should implement the code to retrieve parameters of a physical resource. Retrieved values should be written into collection parameters. If such functionality is not required for the resource, it can be implemented as empty method:
void Get() {}

void Update(Parameters newParams)

This method should implement a way to change all or some parameters of a physical resource. The method accepts a collection of parameters that need to be changed. During the implementation of this method, you don't have to update the collection resource parameters (it will be done by H-Sphere Windows engine if the code is completed successfully). It is enough to update parameters of the physical resource.

If the given functionality is not required for the resource, it can be implemented as an empty method:

void Update(Parameters newParams) {}

void Delete()

This method should implement the deletion of the physical resource. If the given functionality is not required for the resource, it can be implemented as an empty method:

void Delete() {}

void Suspend()

This method should implement the suspension of the physical resource. If the given functionality is not required for the resource, it can be implemented as an empty method:

void Suspend() {}

void Resume()

This method should resume the physical resource. If the given functionality is not required for the resource, it can be implemented as an empty method:

void Resume() {}

 

Keys

H-Sphere Windows engine and resource class deal with terms like "resource keys". There are two types of keys, logical and physical. Logical key can be defined as a parameter which differentiates instance of the resource from the set of other instances for the resource user (i.e. CP). To operate with particular instance of the resource, in addition to all other parameters added to its methods, you need to pass the parameter that will uniquely identify the resource. Physical key is very much like a logical key, with the only difference that resource user (i.e. CP) knows nothing about it (there is no unique identifier). Sometimes physical resources require keys to operate with them, which makes sense only in the context of the given physical key. It can be exemplified by numeric IDs of virtual web or ftp hosts (unique numerical identifiers) in the IIS metabase, that are required to operate with a given host on the level of metabase.

On the other hand, for virtual web host uniqueness can be implemented by means of domain name, and for virtual FTP host - by means of IP. In that case domain name is a logical key for the resource that implements virtual web host. A number in the metabase - its resource's physical key. At the same moment H-Sphere Windows engine provides mechanisms for the translation of virtual key into physical key. In most cases, logical key can coincide with physical key.

As mentioned above, a resource has two types of parameters that eventually are stored in common collection of parameters - configuration (common to all instances) and instance (different for each particular instance of the resource). Instance parameters are passed during the method call and should contain logical key for the given resource.

Each key is implemented via subclass of abstract class Psoft.HSphere.Resources.Key. This class defines the following set of methods to be overloaded:

public abstract object Val { get; set; }
public abstract int Compare(object objVal);
public abstract Key Add(object objVal);
public abstract Key Sub(object objVal);
public abstract Key Inc();
public abstract Key Dec();

Those methods define basic operations for manipulating and comparing keys. In most cases, you don't need to create a new key class, as you can use two already existing classes: Psoft.HSphere.Resources.NumKey and Psoft.HSphere.Resources.StrKey, that correspondingly implement numeric and string keys.

Class Resource has two attributes, Pkey and Lkey, to represent physical and logical keys for the instance of the resource:
public Key PKey { get; set; }
public Key LKey { get; }

LKey is read-only, as the value of the logical key is automatically retrieved from the parameters collection.

 

Error handling

All the classes implementing exceptions that are connected with resources have to be inherited from class Psoft.HSphere.Resources.ResourceException. There are several types of error conditions that should be indicated when manipulating with resources:
- attempt to create resource that already exists
- attempt to do an operation on the resource that doesn't exist
- error in the data passed as parameters.

The first error type can appear only in method Create(). For that type, there is a class Psoft.HSphere.Resources.ResourceAlreadyExistsException inherited from ResourceException. During the implementation of the Create() method, you have to make sure that given exception is thrown in the situation when the physical resource exists and from the point of view of the resource's logic it is considered as an error. (For some resources, given condition may not be an error, e.g error that appears while adding an IP that has been already set up before can be safely ignored).

The second type of error conditions can appear in any method, but Create(). That type of errors is described by Psoft.HSphere.Resources.ResourceNotFoundException class. During the implementation of such methods, you have to make sure that those conditions are taken care of, and that the exception is thrown.

The third type of conditions is described by class Psoft.HSphere.Resources.ResourceInvalidParameterException. That type is used to describe situations when the problem is created by incorrect data entered by end user - to allow end user to fix them.

Class Resource has got a set of methods to generate exceptions of these types:

protected void ErrorNotFound()
protected void ErrorNotFound(string message)
protected void ErrorAlreadyExists()
protected void ErrorAlreadyExists(string message)
protected void ErrorInvalidParameter(string pName)

 

Resource Hierarchy

Based on H-Sphere logic, each resource belongs to hierarchy of resources. This hierarchy shows dependence of one resource on another. For example, to create the virtual webhost resource, it is required to specify an account name that will be the owner of that virtual host. It means that virtual host resource depends on resource account, and stands below it in the hierarchy of resources.

During the development of resource class, you can specify the place of the resource in the hierarchy using special attribute (attributes will be explained in details below). Even though the configuration of resource attributes is located in the config file, each resource has access to only its own set of attributes. Yet, it also inherits configuration parameters of its parent resource (in the hierarchy). Therefore, resource gets configuration parameters of all its parents in parameters collection.

This resource's quality does not depend on the instance of the resource, such as configuration parameters are common for all instances of the resource.

There is another aspect of using resource hierarchy. The child resource can access parent resource to retrieve parent resource's instance parameters. Each resource has instance parameter which is its logical key. That parameter uniquely identifies the instance of this resource. We can connect child resource with parent resource by means of parameter from the instance parameters set, that has the same name as key parameter. In such child resource we have access to instance of parent resource, using the Parent attribute inherited from Resource:
public Resource Parent { get; }

Accordingly, by means of the Pkey attribute, physical key of the parent resource instance can access the collection of parameters via the Params' property:
public Parameters Params {get; set;}

 

Logging

Each resource inherits method Log that can be used for logging. The log output will be placed in the common log file resource.log. Method has the following signature:
protected void Log(string format, params object[] args)

 

Resource Types

Resources can be of two types: those that support listing and those that don't support listing. In the case of listable resource, H-Sphere Windows engine will load all instances of the resource into cache. Cache will be used to consequently retrieve instances of the given resource. Listable resources do two important things: the information is cached that allows to optimize method Get(), and such resources support automatic generation of new physical keys during creation of resource. If resource has to support physical keys and it requires their automatic management, resource has to be listable. To notify that resource is listable, you have to overload a static method:
ArrayList Enum(Key parPKey, Parameters configParams, ResourceLogger log)

This method has to return list of physical keys for existing instances of resource. As parameters, the value of physical key of corresponding parent resource is passed (if there is no parent resource, or if parent resource doesn't support physical keys, the parameter can be ignored), configuration resource parameters and log object.

Resources that don't support physical keys can be listable as well.

Method Enum has to return list of logical keys, as they are also physical keys for those resources.

Listable resources support automatic access synchronization to their instances. They also provide additional level of checking the existing resource during creation, and missing resource check during other operations using cache. They will automatically generate ResourceAlreadyExistsException or ResourceNotFoundException exceptions.

 

Schemas

Schemas are used not only in resources, but we will discuss them only in the context of Resource. Schemas are descriptions of attributes of a particular object. Schemas are implemented by class Psoft.HSPhere.Configuraiton.Schema. Constructor of the given class accepts XML string as a parameter. That XML string describes the given schema. XML schemas consist of the following elements: schema tag, properties tag (prop), attributes of properties. Schema tag contains a prop tag which can have attribute tags. The prop tag has the following attributes:

  • "name" - required attribute, it defines name of the property
  • "description" - contains short description of the property
  • "type" - contains identifier of the property type. The following identifiers are supported:
    • str - string (default)
    • num - numeric
    • unum - non-signed numeric
    • bool - boolean
    • select - list (will be described bellow)
    • path - file system path
    • password - password
    • ip - IP address
    • domain - domain name
    • url - URL
    • mail - mailbox name
    • mask - IP mask
  • mac - MAC address
  • value - default value of the property
  • key - false by default. If false, it is not the key property. If true, property is a key property.
  • Optional - false by default. If false the property is optional, otherwise it is required.
  • "readonly" - deafult false. If false, the property can be changed (can be passed as the parameter), if true, the property is read-only.

If parameter has type "select", this tag has to contain list of tags that describe values of the list. Values by default are set to be equal to the name of the value.

There are two types of schemas for resources - schemas that describe configuration parameters, and schemas that describe instance parameters. A resource doesn't have to have a configuration parameters schema (for example, if it doesn't have config parameters), but schema of instantace parameters must always be defined.

Based on that schema, the input is validated on the presence of key and required parameters. The default values are also set at that stage for missing parameters. If the parameter is described in both config and instance schemas, then if parameter wasn't passed (it is possible, if it was described as optional), the value for it will be taken from the config file, otherwise, the input value has higher priority and is used as the parameter. Examples of schemas are in the section "Attributes".

 

Attributes

Resource has a list of attributes, some of them are required. Attributes define properties of the resource and define its behavior.

ResourceName

Required attribute that specifies logical name of the resource. It will be passed as the name to invoke that resource by the CP.
Example: [ResourceName("hosting")]

PhysicalName

Required attribute that contains implementation name of the given logical resource.
Example: [PhysicalName("iis5_website")]

LKey

Required attribute that defines logical key for the resource, or, more specifically, the name of the key parameter of the implementing class.
Example: [LKey("hostname", typeof(StrKey))]

ResourceDescription

Optional attribute that contains short description of the resource.
Example: [ResourceDescription("IIS 5.0 virtual web host")]
Even though this attribute is not required, we highly recommend using it.

ParentName attribute

Optional attribute that contains logical name of the parent resource.
Example: [ParentName("account")]
This attribute defines the place of the resource in the resource hierarchy. If it is not defined, the resource is considered to be root in the hierarchy.

ManagedPKey attribute

Optional attribute. Shows if physical keys will be automatically managed.
Example: [ManagedPKey]
If the attribute is not defined, the resource has to generate unique physical keys. If the resource doesn't support physical keys, this attribute is meaningless.

ResourceSchema attribute

Optional attribute. Describes the configuration schema and input parameters of the resource. Example:

[ResourceSchema(
@"<schema>
	<prop name='hostname' type='domain' description='Virtual web host name'/>
	<prop name='ip' type='ip' description='Virtual web host IP'/>
	<prop name='port' type='unum' value='80' description='Virtual web host port'/>
	<prop name='username' description='Owner account of virtual web host'/>
	<prop name='docroot' optional='true' description='Document root name of virtual web host'/>
	<prop name='docrootpath' readonly='true' description='Document root directory full path'/>
	<prop name='status' type='select' value='starting' description='Status of virtual web host'>
		<prop name='starting' value='1' description='Starting virtual web host'/>
		<prop name='stopping' value='3' description='Stopping virtual web host'/>
		<prop name='pausing' value='5' description='Pausing virtual web host'/>
		<prop name='continuing' value='7' description='Continuing virtual web host'/>
	</prop>
	<prop name='index' type='bool' value='false' description='Indexing flag'/>
	<prop name='idomian' optional='true' type='domain' description='Instant alias of virtual web host'/>
	<prop name='dedicatedip' type='bool' value='false' description='true if IP property is dedicated IP'/>
	<prop name='ss_lid' optional='true' description='Site Studio lid'/>
	<prop name='applevel' type='select' optional='true' description='Web applications isolating level'>
		<prop name='inproc' value='0' description='Inproc application'/>
		<prop name='outproc' value='1' description='Outproc application'/>
		<prop name='pooled' value='2' description='Pooled application'/>
	</prop>
</schema>",
@"<schema>
	<prop name='logsdir' type='path' description='Log files directory'/>
	<prop name='suspendskeleton' type='path' value='\skeleton\suspend' description='Suspned skeleton location'/>
	<prop name='inheritdefaultdocs' type='bool' value='false' description='Direct to inherit default documents 
from default web properties'/> <prop name='removecontent' value='false' type='bool' description='Force to remove all content from deleted
website'/> <prop name='enableparentpath' value='true' type='bool' description='If true using of absolute pathes (such
as \somedir\somescript.asp) in the ASP scripts will be enabled'/> <prop name='defaultdocs' value='default.htm, default.asp, default.html, index.html, index.htm, default.stm,
index.stm, default.shtml, index.shtml, default.shtm, index.shtm, default.aspx, index.aspx' description='List
of default documents'/> <prop name='applevel' type='select' value='pooled' description='Web applications isolating level'> <prop name='inproc' value='0' description='Inproc application'/> <prop name='outproc' value='1' description='Outproc application'/> <prop name='pooled' value='2' description='Pooled application'/> </prop> </schema>" )]

This attribute has two constructors. The first constructor accepts both schemas as shown in the example. The second constructor is used for resources that don't have configuration parameters and have only one schema.

Exclusive

Optional attribute. Specifies if synchronization should be used to access different instances of the resource.
Example: [Exclusive]
If the attribute is not defined, synchronization will not be performed. If the resource is listable, the attribute is ignored, because listable resources automatically support synchronization.

Offline

Optional attribute. Shows that all the operation on the resource has to be performed offline.
Example: [Offline]
Currently not implemented.

IgnoreExists

Optional Attribute. Affects the behaviour when there's an attempt to create an already existing resource.
Example: [IgnoreExists]
If the attribute is set, the already existing condition is not considered to be an error.

Cacheable

Optional attribute. Affects the cache behaviour during data access from cache for listable resources.
Example: [Cacheable(false)]
The default is true. If set to false, the data will not be caught. This can be useful for resources with read-only parameters, such as "usage" for disk quota. For non-listable parameters, this attribute is ignored.

CaseSensitive

Optional. Defines if logical keys are case sensitive.
Example: [CaseSensitive]
False by default.



© Copyright 2017. Parallels Holdings. All rights reserved.