Type modeling
From ControlTier
This document describes the Type Modeling system used in ControlTier. The Type system in use is similar in many ways to some Object Oriented programming languages (such as Java), and borrows concepts from them. It is also built on top of the Resource Description Format (RDF), and so its behavior also depends on some underlying concepts used by RDF. Understanding RDF is not required to understand the Type system, but some concepts may come up.
Contents |
Description
ControlTier uses a class based Type system to allow you to create a data model to represent the various components of your Business Service.
Each Object in your model is a member of a particular class, called a Type. Each Type has a set of #Properties and #Commands, that govern how Objects can be used and what they can do. You can modify some of these features, such as add Constraints to Properties or override Commands, but you cannot add new Properties to the Types or change all behaviors.
Every Type in the system also belongs to a meta-class called an "Order". Think of an Order as a secondary classification of the Types. The Order of a Type determines which Properties are defined for the Type, and some of its behavior. (See #Orders)
You can create subclasses of the Types, and each Subtype initially duplicates the behavior and property constraints of the Supertype, but can be altered to extend or restrict those features. (See #Subtypes)
When using the Type Modeling system to refine your model, it is the best practice to create Subtypes and override commands and constraints, rather than modifying any of the Types that come installed with ControlTier. This is so that in the future when you may upgrade your ControlTier server, those builtin Types which have been upgraded will not affect your existing Object model.
The Type System
Types and Objects in the ControlTier system have some features that may be recognizable to you if you have done Object Oriented Programming (OOP): Commands (i.e. methods), inheritance, properties (similar to members), instantiation, constraints (similar to type safety). However this system is limited in many places and is not meant to be a full featured "programming" model.
It is designed as a way to model a dataset as a collection of related Resources and their Properties, and it is built on RDF, and the RDFS schema system. The RDFS Schema allows our Typing system to have inheritance, and on top of that have been added the OOP constructs.
In this system we have some nomenclature which should be defined:
- Type
- A member of the hierarchical classification system
- Class
- Synonymous with Type, but not typically used except in reference to OOP
- Object
- An instance of a Type
- Resource
- Typically synonymous with Object, it is also the name of the Base Type
Basics of Modeling
The modeling system of ControlTier is complex, and it needs to be in order to accurately represent complex systems and also to be functionally useful.
However, at the basic level there are only three important concepts in the modeling system:
- Resources
- Relationships
- Properties
- Resources
- Every resource that we want to represent in the system is called a Resource.
- Relationships
- Every Resource can have multiple other Resources as "parents" (also known as the property, "referrers"). Some Resources can have multiple other Resources as "children" (also known as the property, "resources").
- Properties
- Every Resource can have literal values attached to it which are identified by a name
These basics allow you to model things in your environment, as well as relationships between them and some of the pertinent data about them. In addition to these concepts, the only other important concept to add is that of Types.
- Type
- A class of Resources, which confers on its members the ability to have certain Properties, Relationships, and other specific traits.
You can see that for example, there is a need to differentiate between the concept of a Node and a software Service, and that Resources of each of those Types will have different needs: different Properties will be necessary, as well as the ability to have only certain other Types of Resources as children.
Types
Each Type has the following features:
- A Supertype, from which all other features are initially inherited
- An Order Type, which may be inherited, or may be equivalent to the Type itself
- Each Order Type may add features to itself and its subtypes
- A unique name
- A description
- A set of configuration values, which determine some of its behaviors
- A set of Object Properties, which define data that Objects can hold
- Each Property has a name and a type, which is either a String-type (literal string values), or Instance-type (Object values)
- All Types have the 'referrers' Instance-type Property
- A set of Constraints on the Properties, which may be empty or may default to certain values
Each Type may have the following features:
- A set of Commands, and associated command-handler files and directory structure
- These files are packaged as a Java JAR file when creating a Module
- A set of Subtypes
Core Types
ControlTier comes with a set of Core Types, which provide a framework for modeling a Business Service. It also comes with a number of additional Types which extend the Core Types to provide specific uses or solve specific problems, such as managing an installation of the JBoss or Tomcat servers.
This screenshot lays out all of the Core Types that are included in the ControlTier system (except "Tomcat" which is not a Core Type):
As you can see, the Type system is hierarchical. And almost each different icon you see for the Core Types represents a different one of the #Orders.
Resource is the top-most Type in the system, and it has very few features of its own. The other Core Types each add unique features (Commands, Properties, or behaviors) that are available to all of their subtypes:
- Assembly - This type adds a "resources" property, allowing it to have Resource objects as Child Dependendencies.
- Managed-Entity - This type adds Commands, allowing it to be packaged as a Module and deployed to a host. (See #Modules)
- Deployment - This Type adds properties for configuring deployed Objects, facilitating software or file deployments.
- Node - This Type represents computer hosts in the system that are registered with ControlTier, and allows modeling their relationships with the other Objects.
- Package - This Type represents a discrete computer file or archive.
- Managed-Entity - This type adds Commands, allowing it to be packaged as a Module and deployed to a host. (See #Modules)
- Setting - This type adds properties allowing a simple value to be set
- Statistic - Not commonly used, this Type adds properties to hold some measurement value
Orders
Orders are the secondary classification system of Types (some refer to these as meta types). You will usually not need to worry about Orders, but it is useful to recognize why certain Core Types are different from each other.
The Types which are also Orders are highlighted in the below screenshot:
New Subtypes will gain the Order of their Supertype, meaning they gain all of the features that that Order provides.
Properties
Properties of Types come in two types:
- string
- instance
String-type properties allow objects to have a literal string value. Below is the "deployment-basedir" property of the Deployment type:
Instance-type properties allow Objects to add other Objects as dependencies. There are only two commonly used Instance-type properties: 'resources', and 'referrers'.
See Attributes for the equivalent to user-defined properties for a Type.
Property View
Each Object that is defined in the ControlTier system has a Property View file. The file is called "resource.properties" and is generated by the server when an Object is stored or updated in the model. This file is distributed to CTL clients, and contains all of the information about the Object and its Properties.
The file is in the Java "Properties" format, which simply means it is a set of key,value pairs. Here when we refer to a Java Property, we simply mean the key name used in the file, as opposed to a Type Property used in the model.
For each Type Property, there is at least one Java Property stored in the resource.properties file.
For example, the "deployment-basedir" Property of the Deployment type is stored as the "resource.deployment-basedir" Java Property:
resource.deployment-basedir=/usr/opts/myservice
In addition to containing entries for the Object itself, this file may contain entries for Child or Parent Dependencies, or both.
Constraints
For each Property, a Type can define Constraints on the property. For String-type properties, this can either restrict which values are allowed, or provide a default set of values. For Instance-type properties, this can restrict the Types of Objects that are allowed to be set on the property, whether there can be only one or more than one Object of that Type set, and they can be used to set a collection of defaults for new Objects.
Attributes
Each String-type property can also have an Attribute name assigned to it. This provides a customizable way of referring to Property values inside scripts or command options. The Property value is added to the Java Properties (See #Property View) using the attribute name as well, in the form resource.attribute.ATTRIBUTE.
This is useful when you have Child or Parent Dependencies of an Object and want to refer to a particular property value that is imported by them, or when you have Setting dependencies.
Type configurations
Each Type has a set of configuration values:
Each Type has two Object Creation Settings:
- Creation role: either "concrete", or "abstract". If "abstract", then the Type is not allowed to have Objects created for it.
- Unique Object Names: true/false. If
True, then all Objects of this Type must have a unique name.
To change the Object Creation Settings, choose the "Edit Type" link (Pencil icon) on the Type View page. Under the Advanced Options you can see options to change these values:
The Types also have a set of Command Module Settings:
- Logger Name: a string, unused.
- Transforms Directory: A path, used by the Documents feature. (optional)
- Failure Notifications: true/false. If True, then command failure notifications are sent to the Notification Email.
- Notification Email: An email address where failure notifications are sent.
- Dependencies View: Either Children, Parents, or both.
- View Degrees away: An integer from 1-4
To change the Command Module Settings, click the Pencil icon next to the list of Command Module Settings in the Type View.
You will see this form:
The Dependencies View and View Degrees determine what Objects' data are included in the #Property View.
Commands
Sub-types of the Managed-Entity Base Type gain the ability to have Commands.
Types inherit all of their Supertype's Commands. They can also redefine, or override any inherited command. This allows Subtypes to implement hooks, or just add or modify the actions performed by the Supertype's commands.
Every Command is of a certain type:
- Shell command - use a shell interpreter, such as bash, or cmd.exe, to execute a script
- Ant command - use the Ant XML-based language to implement a script
- BSF command (Bean Scripting Framework) - use a variety of languages, such as Python, Groovy, Ruby, etc. to execute a script
- Workflow command - Execute a sequence of other Commands, and handle errors
- Dispatch command - Execute a Command on a set of Objects
Commands are defined in either a type.xml file, or in the Graphical type editor. When the Type's Module is generated, those commands are converted into "handler" files. Each handler is actually an Ant handler script. When the Command is executed on the commandline or in Jobcenter, then the Ant handler is executed.
Commands are also either defined as "Static" or "Instance" commands. A Static Command can be executed in a Static Context, without requiring that an Object of the Type exists.
Modules
The definition of a Type exists in the ControlTier server's data model, yet in order to make the Commands and Resources of the Type usable, they must all be stored into an archive file and distributed to the various ControlTier Clients that need to use it.
A Module is a Java Jar Archive that is created to contain the Type definition and its related file resources, including the Command handler files, any included scripts or templates, and various metadata files which describe the Type itself.
You can create a Module for a Type, either by using the Graphical type editor, or the ProjectBuilder utility.
To create the Type Module using Workbench, navigate to the Type, and click the "Package Commands" button on the right side of the page:
The icon used on this button differs depending on whether the Type has been recently modified or not. When there are changes that have been made to the Type that have not yet been stored in a Module, then the button has an exclamation mark to indicate that the Module is out of date:
When you click this button, the ControlTier server creates the Module file and names it Type-head.jar. This file is then stored in the WebDAV Repository under the path /PROJECT/publish/modules, where "PROJECT" is the name of your Project. This is the location that ControlTier Clients will use to find the latest version of the Module when they need to download it.
To create a Module using the ControlTier Client, CTL, you can use the ProjectBuilder Type's build-type command. This Command requires that you have a type.xml file defining the Type, and it will prompt you to locate the file and to input a location to store the Module .jar file. If you include the -upload option, the command will additionally upload the Module .jar file to the ControlTier Server and install it there. Adding the -deploy option will also deploy the Module in your local CTL installation, after which you can execute its commands.
Create Types
You can create and develop new Types using two methods:
- the Workbench GUI
- Use the web interface to modify your Types and create Modules
- Source based development
- Use a text editor to edit files, and the ProjectBuilder Type's commands via the command-line CTL tool to build the source into a usable Module.
Using the GUI is a simple way to get started, but prolonged or complex development is best done using established software development practices, such as checking in your code to a SCM repository (such as CVS or Subversion), and as such the source-based method is preferable.
You can start out using the GUI and if you want to switch to using Source based development, you can follow the instructions here: Converting Workbench modules for use with ProjectBuilder
Pick a Supertype
However you decide to develop, the first question you should ask is "What Supertype should I use?"
ControlTier's Core Types, and all of the other Builtin Types offer a variety of solutions and features. You should examine them to determine what best suits your needs.
In the examples below we have decided to use Service as the Supertype. This is a good point to start from if you are implementing a Type to control some custom software service that does not already have a Type to control it.
Using Workbench
Workbench provides a full user interface for developing all facets of a Type.
To create a Type, first navigate to the Type you want as the Supertype.
Click the "Create Subtype" button the right side of the page:
Fill in the Name, Description, and optionally change the Object Creation Settings under the Advanced Settings section, then Click the "Save Type" button:
After your Type is created, it has not yet been "staged" as a Module. Once you have made some changes to your Type, you can use the "Package Commands" button to generate the Module archive.
Using Source
Source based development makes use of a utility Type called ProjectBuilder.
Recall that the Builder Base Type is meant for "executing software builds and creating Packages". The ProjectBuilder Type is made to do exactly that for XML files called "type.xml", which are built into Modules. ProjectBuilder also has some commands that can help get you started with development.
First, execute the create-type command on the commandline, using CTL:
$ ctl -p demo -m ProjectBuilder -c create-type
This command will prompt you for several pieces of information, including the Name, Description, Supertype, and directory to store the source code in.
Name of type:
WidgetService
Description of type:
Controls the WidgetServer program
Choose a supertype: ([Managed-Entity], Package, Builder, Deployment, Service)
Service
Directory where module files will be created: [/Users/greg/ctier3/ctl/src]
[hit enter to accept the default location of $CTL_BASE/src]
Creating module definition files in directory: /Users/greg/ctier3/ctl/src ... Creating directory structure... Created dir: /Users/greg/ctier3/ctl/src/modules/WidgetService Created dir: /Users/greg/ctier3/ctl/src/modules/WidgetService/bin Created dir: /Users/greg/ctier3/ctl/src/modules/WidgetService/commands Created dir: /Users/greg/ctier3/ctl/src/modules/WidgetService/objects Created dir: /Users/greg/ctier3/ctl/src/modules/WidgetService/templates Initializing type module from template dir: /Users/greg/ctier3/ctl/modules/ProjectBuilder/templates/boilerplate ... Copying 2 files to /Users/greg/ctier3/ctl/src/modules/WidgetService Define commands and attributes in this file: /Users/greg/ctier3/ctl/src/modules/WidgetService/type.xml
You can see that the command created some directories, based at the path "$CTL_BASE/src/WidgetService", and a file called "type.xml" there.
type.xml is the main source code for your Type. You can edit it with your preferred text editor, and it is recommended that for important code you check the entire "$CTL_BASE/src" directory into a Source Code Management repository like Subversion.
Once you have developed your Type to a point that you want to test, you can use the ProjectBuilder build-type command:
$ ctl -p demo -m ProjectBuilder -c build-type -- -type WidgetService Base directory where module source files reside [/Users/greg/ctier3/ctl/src]
[hit enter for default, or type the path to your src dir]
Target directory where build files are generated [/Users/greg/ctier3/target]
[hit enter for default, or type a path to store the build artifacts in]
Building type using the buildmodule.xml via classloader converting type.xml for module: WidgetService generating handlers... packaging module: WidgetService Copying 1 file to /Users/greg/ctier3/ctl/src/modules/WidgetService Copying 1 file to /Users/greg/ctier3/ctl/src/modules/WidgetService Deleting: /Users/greg/ctier3/ctl/src/modules/WidgetService/module.properties.temp Building jar: /Users/greg/ctier3/target/modules/WidgetService-1.jar
This has generated the WidgetService-1.jar file. This is the Module archive that contains all of the files needed to define your Type in the Type Model, as well as execute the Commands that you may have defined.
At this point you could manually upload the Module to Workbench to install it in the server, but it is easier to just add the -upload option to the build-type command. Further, by adding the -deploy option you will also deploy the Module to your local CTL installation, allowing you to use the Commands in the Module right away.
Enter the same input values you provided earlier when you run this command:
$ ctl -p demo -m ProjectBuilder -c build-type -- -type WidgetService -upload -deploy
You will see this additional output:
... Uploading built module to server ... processing files in directory: /Users/greg/ctier3/target/modules scanning for files matching pattern: (WidgetService)-([0-9]+)\.jar Uploading jar: /Users/greg/ctier3/target/modules/WidgetService-1.jar to server: 'localhost' ... Installing new build of "WidgetService" module from server ... Getting: http://localhost:8080/jackrabbit/repository/controltier/projects/demo/publish/modules/WidgetService-head.jar To: /Users/greg/ctier3/ctl/var/tmp/downloads/demo/WidgetService-head.jar Created dir: /Users/greg/ctier3/ctl/projects/demo/modules/WidgetService Expanding: /Users/greg/ctier3/ctl/var/tmp/downloads/demo/WidgetService-head.jar into /Users/greg/ctier3/ctl/projects/demo/modules/WidgetService Attempting to get Service-head.jar ... Getting: http://localhost:8080/jackrabbit/repository/controltier/projects/demo/publish/modules/Service-head.jar To: /Users/greg/ctier3/ctl/var/tmp/downloads/demo/Service-head.jar Not modified - so not downloaded Service up to date Attempting to get Deployment-head.jar ... Getting: http://localhost:8080/jackrabbit/repository/controltier/projects/demo/publish/modules/Deployment-head.jar To: /Users/greg/ctier3/ctl/var/tmp/downloads/demo/Deployment-head.jar Not modified - so not downloaded Deployment up to date
You can see that the module was uploaded to the Server, and that it was subsequently downloaded and then deployed.
If you now look at the Workbench GUI, you will find that the WidgetService Type is shown in the Type hierarchy as a Subtype of Service.
| ||||||||||||||












