Update spec on App dev framework to match the implementation

Change-Id: If27bc60d0f3d68572bee0df03ac430bbe8c9880c
This commit is contained in:
Valerii Kovalchuk 2016-09-19 16:28:47 +03:00
parent 7b05cd043a
commit a8240291ad
1 changed files with 192 additions and 201 deletions

View File

@ -69,35 +69,36 @@ the generic level as well as to implement it for the case of the Servers/VMs:
:: ::
+-------+ +-------+
| +-------+ | +-------+
| | +--------+ +------------------+ +-----------------+ | | +--------+ +------------------+ +-----------------+
| | | | | | | | | | | | | | | |
+-+ | Object <--+ ReplicationGroup +----> ReplicaProvider | +-+ | Object <--------+ ReplicationGroup +--------> ReplicaProvider |
+-+ | | | | | +-+ | | | | |
+--------+ +------+-----------+ +-+-------------+-+ +--------+ +---+--------------+ +-+--------+------+
^ ^ ^ ^ ^ ^
| | | | | |
| +--------------+----------+ | | +------------------+-----+ |
| | | | | | | |
+-------+ | | TemplateReplicaProvider | | +-------+ | | CloneReplicaProvider | |
| +-------+ | | +--+----+ | +-------+ | | | |
| | +----------+ | +----------+--------------+ | | | +----------+ | +------------------------+ |
| | | | | | CloneReplicaProvider | | | | | | |
+-+ | Instance +-----+ | | | +-+ | Instance | | |
+-+ | | | +--------+-------------+ +-+ | | |
+----------+ | | ^ +----+-----+ | |
| | | | | |
| | +-----------+------+ +-----+-------+ | |
| | | | | | | |
+-------+-----------+-+ | InstanceProvider +--+ | ServerGroup | | +---------------+--+
| +---------> | | | | | | Template |
| InstanceGroup | +-----+------------+ +---+ +-----^-------+ +---+----------+ | Server +--+
| | | | | | | Server +-------> Provider | |
+---------------------+ +---+-----------+ | +------------+ Replication | +-----+------------+ +---+
| Group | | | |
+--------------+ +---+---other---+ |
| | | |
+---------------+ +---------------+
(other replica providers)
@ -105,30 +106,27 @@ the generic level as well as to implement it for the case of the Servers/VMs:
**ReplicationGroup** **ReplicationGroup**
A base class which does the object replication. It holds the collection of A base class which does the object replication. It holds the collection of
objects in one of its InputOutput properties (so the objects may be both objects generated in runtime in one of its output properties and contains
generated in runtime and passed as the user input) and contains a reference a reference to a ``ReplicaProvider`` object which is used to dynamically
to a ``ReplicaProvider`` object which is used to dynamically generate the generate the objects in runtime.
objects in runtime.
Input properties of this class include the ``minReplicas`` and Input properties of this class include the ``minItems`` and ``maxItems``
``maxReplicas`` allowing to limit the number of objects it holds in its allowing to limit the number of objects it holds in its collection.
collection.
An input-output property ``requiredNumberOfReplicas`` allows to An input-output property ``numItems`` allows to declaratively change the
declaratively change the set of objects in the collection by setting its set of objects in the collection by setting its size.
size.
The ``deploy`` method of this class will be used to apply the replica The ``deploy`` method of this class will be used to apply the replica
settings: it will drop the objects from the collection if their number settings: it will drop the objects from the collection if their number
exceeds the specified by the ``requiredNumberOfReplicas`` or generate some exceeds the specified by the ``numItems`` or generate some new if there
new if there are not enough of them. are not enough of them.
**ReplicaProvider** **ReplicaProvider**
A class to generate the objects for a ``ReplicationGroup``. The base one A class to generate the objects for a ``ReplicationGroup``. The base one
is abstract, its inheritors should implement the abstract is abstract, its inheritors should implement the abstract
``createInstance`` method to create the actual object. The method may ``createReplica`` method to create the actual object. The method may
accept some index parameter to properly parametrize the newly created copy. accept some index parameter to properly parametrize the newly created copy.
The concrete implementations of this class should define all the input The concrete implementations of this class should define all the input
@ -136,39 +134,33 @@ the generic level as well as to implement it for the case of the Servers/VMs:
actually acts as a template of the object it generates. actually acts as a template of the object it generates.
**TemplateReplicaProvider**
An implementation of ``ReplicaProvider`` capable to create replicas based
on a user-provided template, being a yaml-based definition of some
arbitrary object.
**CloneReplicaProvider** **CloneReplicaProvider**
An implementation of ``ReplicaProvider`` similar to the An implementation of ``ReplicaProvider`` capable to create replicas by
``TemplateReplicaProvider``, capable to create replicas by cloning some cloning some user-provided object, making use of the ``template()``
user-provided object. The difference between this class and the contract.
``TemplateReplicaProvider`` is that for ``CloneReplicaProvider`` the target
object should be a real object (thus having all the properties valid,
matching all the contracts etc), while the template of
``TemplateReplicaProvider`` is just a dict which may be missing some of the
required properties etc.
**InstanceGroup** **ServerGroup**
A subclass of ``ReplicationGroup`` class to replicate the ``Instance`` A class that provides static methods for deployment and releasing
objects it holds. resources on the group of instances.
**ServerReplicationGroup**
A subclass of the ``ReplicationGroup`` class and the ``ServerGroup``
class to replicate the ``Instance`` objects it holds.
The ``deploy`` method of this group not only generates new instances of The ``deploy`` method of this group not only generates new instances of
servers but also deploys them if needed. servers but also deploys them if needed.
**InstanceProvider** **TemplateServerProvider**
A subclass of ``CloneReplicaProvider`` which is used to produce the objects A subclass of ``CloneReplicaProvider`` which is used to produce the objects
of ``Instance`` class by cloning them with subsequent parameterization of of ``Instance`` class by cloning them with subsequent parameterization of
the hostnames. May be passed as ``replicaProvider`` property to objects of the hostnames. May be passed as ``provider`` property to objects of the
``InstanceGroup`` class. ``ServerReplicationGroup`` class.
**other replica providers** **other replica providers**
@ -180,18 +172,12 @@ the generic level as well as to implement it for the case of the Servers/VMs:
Software Components Software Components
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
The main classes to handle the lifecycle of the application are the The class to handle the lifecycle of the application is the
``BaseSoftwareComponent`` and its subclasses: ``SoftwareComponent`` class which is a subclass of ``Installable`` and
``Configurable``:
:: ::
+-----------------------+
| |
| BaseSoftwareComponent |
| |
+---+---------------+---+
^ ^
| |
+-----------+-+ +-+------------+ +-----------+-+ +-+------------+
| | | | | | | |
| Installable | | Configurable | | Installable | | Configurable |
@ -225,12 +211,11 @@ two parts should improve the developers' experience and simplify the code of
derived classes. derived classes.
The standard workflows (such as Installation and Configuration) will be defined The standard workflows (such as Installation and Configuration) will be defined
by two subclasses of ``BaseSoftwareComponent`` - ``Installable`` and by the ``Installable`` and ``Configurable`` classes. The main implementation -
``Configurable``. The main implementation - ``SoftwareComponent`` will inherit ``SoftwareComponent`` will inherit both these classes and will define its
both these classes and will define its deployment workflow as a sequence of deployment workflow as a sequence of Installation and Configuration flows.
Installation and Configuration flows. Other future implementations may add new Other future implementations may add new workflow interfaces and mix them in
workflow interfaces and mix them in to change the deployment workflow or add to change the deployment workflow or add new actions.
new actions.
Installation workflow consists of the following methods: Installation workflow consists of the following methods:
@ -244,7 +229,7 @@ Installation workflow consists of the following methods:
| +------------------------------+ | +---------------+ | | | +------------------------------+ | +---------------+ | |
| +------------------------------+ | | +---------------+ +---------------+ | | +----------------------+ | | +------------------------------+ | | +---------------+ +---------------+ | | +----------------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | checkServerNeedsInstallation | +-+ +----> beforeInstall +----> installServer | +-+ +----> completeInstallation | | | | checkServerIsInstalled | +-+ +----> beforeInstall +----> installServer | +-+ +----> completeInstallation | |
| | +-+ | | | +-+ | | | | | +-+ | | | +-+ | | |
| +------------------------------+ +------+--------+ +------+--------+ +-----------+----------+ | | +------------------------------+ +------+--------+ +------+--------+ +-----------+----------+ |
| | | | | | | | | |
@ -257,66 +242,66 @@ Installation workflow consists of the following methods:
**install** **install**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``serverGroup``
* **Description:** * **Description:**
Entry point of the installation workflow. Entry point of the installation workflow.
Iterates through all the servers of the passed ServerGroup and calls the Iterates through all the servers of the passed ServerGroup and calls the
``checkServerNeedsInstallation`` method for each of them. If at least one ``checkServerIsInstalled`` method for each of them. If at least one
of the calls has returned `True` calls a ``beforeInstall`` method. Then, of the calls has returned `false` calls a ``beforeInstall`` method. Then,
for each server which returned `True` as the result of the for each server which returned `false` as the result of the
``checkServerNeedsInstallation`` calls the ``installServer`` method to do ``checkServerIsInstalled`` calls the ``installServer`` method to do
the actual software installation. the actual software installation.
After the installation has been completed on all the servers and if at After the installation has been completed on all the servers and if at
least one of the previous calls of ``checkServerNeedsInstallation`` least one of the previous calls of ``checkServerIsInstalled``
returned `True` the method runs the ``completeInstallation`` method. returned `false` the method runs the ``completeInstallation`` method.
If all the calls to ``checkServerNeedsInstallation`` returned `False` If all the calls to ``checkServerIsInstalled`` returned `true`
this method concludes without calling any others. this method concludes without calling any others.
**checkServerNeedsInstallation** **checkServerNeedsInstallation**
* **Arguments:** ``Server`` * **Arguments:** ``server``
* **Description:** checks if the given server requires a (re)deployment of * **Description:** checks if the given server requires a (re)deployment of
the software component. By default checks for the presence of attribute the software component. By default checks for the value of the attribute
`installed_at_%serverId%` being set by the ``installServer`` method. `installed` of the instance.
May be overriden by subclasses to provide some better logic (e.g. the May be overridden by subclasses to provide some better logic (e.g. the
app developer may provide code to check if the given software is app developer may provide code to check if the given software is
pre-installed on the image which was provisioned on the VM) pre-installed on the image which was provisioned on the VM)
**beforeInstall** **beforeInstall**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``
* **Description:** * **Description:**
Reports the beginning of installation process, resets an error counter of Reports the beginning of installation process and calls the public event
the current deployment to zero and calls the public event handler handler ``onBeforeInstall``.
``onBeforeInstall``.
**onBeforeInstall** **onBeforeInstall**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``
* **Description:** Public handler of the `beforeInstall` event. Empty in * **Description:** Public handler of the `beforeInstall` event. Empty in
the base class, may be overriden in subclasses if some custom pre-install the base class, may be overridden in subclasses if some custom pre-install
logic needs to be executed. logic needs to be executed.
**installServer** **installServer**
* **Arguments:** ``Server`` * **Arguments:** ``server``, ``serverGroup``
* **Description:** does the actual software deployment on a given server by * **Description:** Does the actual software deployment on a given server by
calling an ``onInstallServer`` public event handler. If the installation calling an ``onInstallServer`` public event handler. If the installation
completes successfully sets the `installed_at_%serverId%` attribute of completes successfully sets the `installed` attribute of the server to
the component's attribute storage to indicate that the software component `true`, reports successful installation and returns `null`. If an
was installed on that particular machine. If an exception was encountered exception encountered during the invocation of ``onInstallServer``, the
during the invocation of ``onInstallServer`` the method will handle that method handles that exception, reports a warning and returns the server.
exception, report a warning and increment the error counter for the The return value of the method indicates to the ``install`` method how
particular deployment. many failures encountered in total during the installation and with what
servers.
**onInstallServer** **onInstallServer**
* **Arguments:** ``Server`` * **Arguments:** ``server``, ``serverGroup``
* **Description:** an event-handler method which is called by the * **Description:** an event-handler method which is called by the
``installServer`` method when the actual software deployment is needed. ``installServer`` method when the actual software deployment is needed.
Is empty in the base class. The implementations should override it with Is empty in the base class. The implementations should override it with
custom logic to deploy the actual software bits. custom logic to deploy the actual software bits.
**completeInstallation** **completeInstallation**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``, ``failedServers``
* **Description:** is executed after all the ``installServer`` methods were * **Description:** is executed after all the ``installServer`` methods were
called. Checks for the number of errors reported during the installation: called. Checks for the number of errors reported during the installation:
if it is greater than some pre-configurable threshold an exception is if it is greater than some pre-configurable threshold an exception is
@ -325,7 +310,7 @@ Installation workflow consists of the following methods:
completion of the installation workflow. completion of the installation workflow.
**onCompleteInstallation** **onCompleteInstallation**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``, ``failedServers``
* **Description:** an event-handler method which is called by the * **Description:** an event-handler method which is called by the
``completeInstallation`` method when the component installation is about ``completeInstallation`` method when the component installation is about
to be completed. to be completed.
@ -338,61 +323,61 @@ Configuration workflow consists of the following methods:
:: ::
+-------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------+
| CONFIGURATION | | CONFIGURATION |
| +-------------------------------------+ | | +-----------------+ |
| | | | | | | |
| | +------------------+ +-----------------+ | | | +---------------+ +-----------------+ |
| | +------------------+ | +-----------------+ | | | | +---------------+ | +-----------------+ | |
| +------------v--+ +--------------+ +------------------+ | | +-----------------+ | | +-----------------------+ | | +------------v--+ +---------------+ | | +--------------+ +-----------------+ | | +-----------------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | checkNeedsRe\ +---> preConfigure +---> checkServerNeeds\| +-+---> configureServer | +-+---> completeConfiguration | | | | checkCluster\ +---> checkServer\ | +-+---> preConfigure +---> configureServer | +-+---> completeConfiguration | |
| | configuration | | | | Reconfiguration +-+ | +-+ | | | | | IsConfigured | | IsConfigured +-+ | | | +-+ | | |
| +------------+--+ +------+-------+ +------------------+ +--------+--------+ +-----------+-----------+ | | +------------+--+ +---------------+ +------+-------+ +--------+--------+ +-----------+-----------+ |
| | | | | | | | | | | |
| | | | | | | | | | | |
| +----v---+ | | | | | +----------v----------+ | | | |
| | | | | | | | | | | | | |
| | getKey | | | | | | | getConfigurationKey | | | | |
| | | | | | | | | | | | | |
| +--------+ | | | | | +---------------------+ | | | |
| | | | | | | | | |
+-------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------+
| | | | | |
| | | | | |
v v v v v v
onPreConfigure onConfigureServer onCompleteConfiguration onPreConfigure onConfigureServer onCompleteConfiguration
**configure** **configure**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``serverGroup``
* **Description:** * **Description:**
Entry point of the configuration workflow. Entry point of the configuration workflow.
Calls a ``checkNeedsReconfiguration`` method. If the call does not return Calls a ``checkClusterIsConfigured`` method. If the call returns `true`,
`True` workflow exits without doing anything. Otherwise calls workflow exits without any further action. Otherwise for each server in
``preConfigure`` method and then iterates through all the servers of the ``serverGroup`` it calls ``checkServerIsConfigured`` method and gets
the passed ServerGroup. For each server it calls the list of servers that need reconfiguration. The ``preConfigure``
``checkServerNeedsReconfiguration`` method. If that call returns `True` method is called with that list. At the end calls the
then a ``configureServer`` is called for that server. At the end calls a ``completeConfiguration`` method.
``completeConfiguration`` method if at least one call of
``configureServer`` was made.
**checkNeedsReconfiguration** **checkClusterIsConfigured**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``serverGroup``
* **Description:** has to return `True` if the configuration (i.e. the * **Description:**
values of input properties) of the component has been changed since it Has to return `true` if the configuration (i.e. the values of input
was last deployed on the given Server Group. Default implementation calls properties) of the component has not been changed since it was last
a ``getKey`` method and compares the returned result with a value of deployed on the given server group. Default implementation calls the
`configuration_of_%serverGroupId%` attribute. If the results do not match ``getConfigurationKey`` method and compares the returned result with a
returns `True` otherwise `False`. value of `configuration` attribute of ``serverGroup``. If the results
match returns `true` otherwise `false`.
**getKey** **getConfigurationKey**
* **Arguments:** None * **Arguments:** None
* **Description:** should return some values describing the configuration * **Description:**
state of the component. This state is used to track the changes of the Should return some values describing the configuration state of the
configuration by the ``checkNeedsReconfiguration`` method. component. This state is used to track the changes of the configuration
by the ``checkClusterIsConfigured`` and ``checkServerIsConfigured``
methods.
Default implementation returns a synthetic value which gets updated on Default implementation returns a synthetic value which gets updated on
every environment redeployment. Thus the subsequent calls of the every environment redeployment. Thus the subsequent calls of the
@ -402,73 +387,79 @@ Configuration workflow consists of the following methods:
The inheritors may redefine this to include the actual values of the The inheritors may redefine this to include the actual values of the
configuration properties, so the configuration is reapplied only if the configuration properties, so the configuration is reapplied only if the
appropriate input properties were changed. appropriate input properties are changed.
**checkServerIsConfigured**
* **Arguments:** ``server``, ``serverGroup``
* **Description:**
It is called to check if the particular server of the server group has
to be reconfigured thus providing more precise control compared to
cluster-wide ``checkClusterIsConfigured``.
Default implementation calls the ``getConfigurationKey`` method and
compares the returned result with a value of `configuration` attribute
of the server. If the results match returns `true` otherwise `false`.
This method gets called only if the ``checkClusterIsConfigured`` method
returned `false` for the whole server group.
**preConfigure** **preConfigure**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``
* **Description:** * **Description:**
Reports the beginning of configuration process, resets an error counter Reports the beginning of configuration process and calls the public
of the current configuration to zero and calls the public event handler event handler ``onPreConfigure``. This method is called once per the
``onPreConfigure``. This method is called once per the server group and server group and only if the changes in configuration are detected.
only if the changes in configuration are detected.
**onPreConfigure** **onPreConfigure**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``
* **Description:** * **Description:**
a public event-handler which is called by the ``preConfigure`` method Public event-handler which is called by the ``preConfigure`` method
when the (re)configuration of the component is required. when the (re)configuration of the component is required.
Default implementation is empty. Inheritors my implement this method to Default implementation is empty. Inheritors may implement this method to
set various kinds of cluster-wide states or output properties which may set various kinds of cluster-wide states or output properties which may
be of use at later stages of the workflow. be of use at later stages of the workflow.
**checkServerNeedsReconfiguration**
* **Arguments:** ``Server``
* **Description:** is called to check if the particular server of the
server group has to be reconfigured thus providing more precise control
compared to cluster-wide ``checkNeedsReconfiguration``.
Default implementation calls a ``getKey`` method and compares the
returned result with a value of `configuration_of_%serverId%` attribute.
If the results do not match returns `True` otherwise `False`.
This method gets called only if the ``checkNeedsReconfiguration`` method
returned `True` for the whole server group.
**configureServer** **configureServer**
* **Arguments:** ``Server`` * **Arguments:** ``server``, ``serverGroup``
* **Description:** does the actual software configuration on a given server * **Description:**
by calling an ``onConfigureServer`` public event handler. Does the actual software configuration on a given server by calling the
If the configuration completes successfully calls the ``getKey`` method ``onConfigureServer`` public event handler. If the configuration
and sets the `configuration_of_%serverId%` attribute to resulting value completes successfully calls the ``getConfigurationKey`` method and sets
thus saving the configuration applied to a given server. the `configuration` attribute of the server to resulting value thus
saving the configuration applied to a given server. Returns `null` to
indicate successful configuration.
If an exception was encountered during the invocation of If an exception encountered during the invocation of
``onConfigureServer`` the method will handle that exception, report a ``onConfigureServer``, the method will handle that exception, report a
warning and increment the error counter for the particular deployment. warning and return the current server to signal its failure to the
``configure`` method.
**onConfigureServer** **onConfigureServer**
* **Arguments:** ``Server`` * **Arguments:** ``server``, ``serverGroup``
* **Description:** an event-handler method which is called by the * **Description:**
``configureServer`` method when the actual software configuration is An event-handler method which is called by the ``configureServer``
needed. Is empty in the base class. The implementations should override method when the actual software configuration is needed. It is empty in
it with custom logic to apply the actual software configuration on a the base class. The implementations should override it with custom logic
given server. to apply the actual software configuration on a given server.
**completeConfiguration** **completeConfiguration**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``, ``failedServers``
* **Description:** is executed after all the ``configureServer`` methods * **Description:**
were called. Checks for the number of errors reported during the It is executed after all the ``configureServer`` methods were called.
configuration: if it is greater than some pre-configurable threshold an Checks for the number of errors reported during the configuration: if it
exception is risen to interrupt the deployment workflow. Otherwise the is greater than set by some pre-configured threshold, an exception is
method calls an ``onCompleteConfiguration`` event handler and then risen to interrupt the deployment workflow. Otherwise the method calls
reports a successful completion of the configuration workflow. an ``onCompleteConfiguration`` event handler, calls the
``getConfigurationKey`` method and sets the `configuration` attribute of
the server group to resulting value and then reports successful
completion of the configuration workflow.
**onCompleteConfiguration** **onCompleteConfiguration**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``servers``, ``serverGroup``, ``failedServers``
* **Description:** an event-handler method which is called by the * **Description:**
``completeConfiguration`` method when the component configuration was The event-handler method which is called by the ``completeConfiguration``
finished at all the servers. method when the component configuration is finished at all the servers.
Default implementation is empty. Inheritors may implement this method to Default implementation is empty. Inheritors may implement this method to
add some final handling, reporting etc. add some final handling, reporting etc.
@ -516,7 +507,7 @@ Uninstallation workflow consists of the following methods:
**onBeforeUninstall** **onBeforeUninstall**
* **Arguments:** ``ServerGroup`` * **Arguments:** ``ServerGroup``
* **Description:** Public handler of the `beforeUninstall` event. Empty in * **Description:** Public handler of the `beforeUninstall` event. Empty in
the base class, may be overriden in subclasses if some custom pre the base class, may be overridden in subclasses if some custom pre
uninstall logic needs to be executed. uninstall logic needs to be executed.
**uninstallServer** **uninstallServer**