Being the inquisitive IT architect that I am, after reading the developerWorks article Create and customize virtual application patterns, I had a question: "How difficult would it be to create a pattern type?" So I attempted to build a pattern type for a standalone server, a somewhat simple project but one that easily demonstrates the concepts that underlie the pattern type.
This article is a guideline to that process; the steps involved distilled from a more complete series from my blog. Each section is a synopsis of the entire instruction. To dive into the details, you need to choose the links and either read the accompanying PDF of the entire discussion or read it in my blog. The PDFs are copies of the actual blog entries and are only updated periodically; the links to the actual blog entries are likely the most current version of the information and where you can find new installments to this series.
Oh, one further note: Each segment builds on the work in the previous segments, so common to most of the series, I examine the application-model and physical-model changes and how to test to make sure your changes work.
Definitions, concepts, the scenario, and the setup
Part 1 starts by describing the difference between pattern type and pattern: A pattern type provides all components, links, scalability rules, etc., to build a pattern. A pattern type requires more effort to create than it does to create a pattern based on a pattern type.
Then outlines the scenario:
- The pattern type contains only one server.
- The server has one parameter.
- The deployment process logs a message when the "deployment" starts the installation.
- The deployment process logs a message at another point of the deployment.
Three important concepts are introduced:
- A pattern type is generally made up of one plug-in consisting of the pattern type definition and one or more plug-ins consisting of functionality provided by this pattern type — the number of plug-ins is an architecture choice.
- You can decompose a plug-in in two main parts:
- Application model: Defines the different components and links to design a virtual application pattern.
- Physical model: Defines the different virtual machines and scripts that have to be launched on the target cloud.
- Two mechanisms are provided to map the application model to the physical model: A Java™-based code mechanism and a template-based one (preferred and recommended).
Finally, the setup steps to participate in this exercise are described:
- Create a workspace.
- Import the pattern type and plug-ins.
- Modify the pattern type name.
- Edit the pattern type JSON description.
- Create a new Java project for the plug-in.
- Create a plug-in directory.
- Copy the META-INF file, the build.plugin.xml, and the build.properties to the plug-in directory.
- Update the config.json file of your plug-in.
I also discuss and provide code for:
- The application model: Defined in the plugin/appmodel/metadata.json. You'll see how to design and test it.
- The physical model: Composed of a VM template file defining the virtual element that should be deployed and the role regarding the application model.
A final test is demonstrated and you're ready for part 2.
Create the Slave-Master pattern type
The next task is to create a Master-Slave pattern type; it differs from the Part 1 exercise since it consists of a link between both servers from the Master to the Slave and retrieves some information from the Slave (such as the IP address) to configure the Master.
Steps in Part 2 include:
- Examining the application model and see the changes I make to it from the application model's JSON file in Part 1. A link type element that specifies source and target has been added.
- Examining the physical model changes, learning to update the OSGI directory, and restructuring the parts based on the Master being dependent on the Slave.
- Discovering how to test it and what the proper results are.
Add static scalability to a pattern type
Part 3 shows how to add a static scalability to the Master-Slave pattern type. By static scalability, I mean define the number of instances during the pattern design.
First, attach a policy component to the Slave component, then define attributes for this policy, and finally adapt the Slave VM templates to import the gathered information from the application model. (This functionality is important because it also exists for IBM Workload Deployer and the IBM PureSystems expert integrated systems.)
Add a monitoring collector to a pattern type
Of course, to realize dynamic scalability, a scalability that will react to a monitoring feature, you have to be able to collect information from the server. The goal of this instruction is to be able to monitor the number of files in a given directory of a server and have a graph show it.
The steps include:
- Defining the format of the data to be collected in a metadata file. Definitions occur during creation of the file.
- Creating the collector script that collect the information on the server. There are different ways to collect information from a server, such as HTTP, WCA, and more; I chose scripting because it is the easiest to understand. You can also implement your own Java class by implementing the
ICollectorinterface. Since all collectors have to follow this interface, the response of the collector will have to follow a given format. - Creating scripts that upload the metadata file and the collector script on the server. I adapted the install.py file for this role. There are other ways to perform this function too.
- Registering the collector. To register the collector, use the command
maestro.monitorAgent.register(). You do that in the configure.py file. - Provide configuration to the user interface to show a graph representation of the collected data. You have to create a monitoring_ui.json file to show the graph. Place that file next to the config.json file.
Scale in and out based on the monitoring collector
You added a simple collector counting the number of files in a directory; next, learn how to leverage this collector to add in-and-out scaling rules based on the metrics provided by this collector.
To implement this scenario you have to modify some files to:
- Capture the scaling rules arguments while designing the pattern:
- The files directory to monitor.
- The min./max. threshold in terms of number of files.
- The min./max. number of VMs you would like to spin off.
- The time period reaction.
- Reflect these values in the topology.
- Change the scripts to create the directory to monitor and pass this parameter to the collector.
The metadata file of the application model has to be modified to capture the different parameters of the scaling rule and define the scaling policy. The VM file must be adapted in order to inject the scaling policy attributes in the topology.
As for scripts, in the previous section I hard-coded the directory to monitor in the scripts. I did it in the install scripts but now, since it is a role parameters, it must be placed in a role scripts, either in the configure.py or start.py file. Obviously it is a configuration of the role, so put it in the configuration scripts.
Add associations to operations
When you define a role in a pattern type, you can associate to this role a number of operations you want to launch once the pattern is deployed. In this example, I add a "Send string to log" operation to a role.
To implement an operation, you have to add an extra file called operation.json next to the metadata.json file in the appmodel directory. This file specifies which script has to be launched and that the script has to be placed under the part role directory.
In the operation.json file for each role, you can define a number of operations; each operation has an id, label, description, category, script, and a list of attributes. The category is used to put together a number of operations in the UI. The script is a Python script and must be placed in the role script directory of the part. The attributes are shown in the user interface.
Implement a very simple script. This script simply retrieves the stringToLog attribute value and posts it in the log file. You can
retrieve an attribute value using the following syntax, maestro.operation['parms'][{attributeName}];, in which attributeName is the name of the attribute you want to retrieve. The script must be placed in the role script directory.
Scale in and out based on operating systems metrics
In the previous segment on scaling, I explained how to scale in and out using your own monitoring collector (by counting files in a directory). You can also reuse some embedded OS metrics in a scaling policy. The reuse of an existing metric requires changes in only two files — the application model (to collect the arguments of the scaling policy) and the topology file (to define the rules and implement this policy).
In the application model file, you have to define the scaling policy and capture all
arguments for this policy. This is very similar to what we did when we defined the policy
for our own monitoring collector. Instead of defining a number of files and a directory to
monitor attributes, define a cpuUsage attribute that is a
percentage. Define a policy type element that is applied to the server role. There are two groups in this policy: One for a static scaling policy and another for a CPU-based policy.
For the CPU-based policy, define three attributes: cpuUsage,
scaleInstanceRange1, and triggerTime1. You can choose the names you want; it's important that the names match an attribute id in the attributes list defined after that. The order of the attribute reference in the group defines the order appearance in the pattern editor.
Next, define each attribute; for example for cpuUsage,
specify that it is a range, it should be displayed as a percentage with a default
minimum of 1 and maximum of 100.
In the topology files, you have to inject the attribute captured in the application model to define the scaling rule. This is done in the scaling JSON attribute of the VM file. You can use a Velocimacro scenario to insert elements in the topology.
Extend an existing pattern type
A customer asked me the following question:
I have my own logging event system and I would like that all log files information of the WebSphere® Enterprise Application environment are copied to my logging event system. I don't want to recreate the full WebApp pattern type just to add a new functionality. So, how can I leverage the existing WebApp pattern type and add in it just the functionality I need?
The answer is simple: Extend the WebApp pattern type by adding a plug-in that does what you want. And you're in luck: Extending a pattern type is easy. All you have to remember is that a pattern type is composed of a pattern type definition and a number of attached plug-ins. The pattern type definition specifies its version, name, and description. Each plug-in attached to it specifies its relationship with the pattern type definition with a few lines in the individual config.json file.
All you have to do is to create a new plug-in that is linked to the target pattern type (in this case, WebApp). Add new components to the metadata.json file.
Add the capability to tweak a virtual application instance
Operations are important: They provide the ability to take actions on a deployed pattern or virtual application; actions like setting parameters and manipulating situations based on these parameters. Do that by launching a script that is specified in an operation.json file created in the application model. Refer to how to add an operation to a pattern type.
The operations model lets you launch scripts with parameters on a running pattern, but there is another way to do this: Tweak. The difference is, a tweaked parameter is persisted in the storehouse and thus can be reused at any time during the running pattern life cycle.
Tweak provides the same functionality but with persisted parameters in the deployed pattern. You can use the tweak parameter to regenerate a crashed server and set it up exactly as the previous version. An example is the WAR/EAR file in the WebApp pattern; when you set it up, the path to the file is persisted in the deployed pattern.
Tweaked parameters can be linked to component attributes.
In the application model, you have to create tweak.json and operations files. Define your tweaked parameters in the tweak.json file.
So, you might ask, "Why do I need an operations file if I'm tweaking?". You need
an operations file (with the "id":
"configuration",) for the user interface to show the "tweak."
Persistence is done in the parameters.json located in the deployed pattern in the storehouse.
Nothing special has to be done in the topology files (VM) unless you want to retrieve a
value using the maestro.parms function.
Attach storage to a virtual machine on SmartCloud Application Services
I was wondering how to add storage to a virtual machine generated from a pattern type developed on the SmartCloud Application Workload Service: in fact, it is simple. All you have to do is update your topology template to request storage and then reference this storage in the vm-templates array element.
Take a simple VM file, add a storage request by adding a storage-templates array in the JSON file, add a reference to the storage request by adding a storage array element in the vm-templates element, then build your plug-in and deploy it.
Once the pattern is deployed, connect and verify that the storage is mounted with the correct size.
Oh, a quick note: The SmartCloud Application Workload Service specifies its storage sizes in gigabytes (GBs); SmartCloud Enterprise allows you to request in both GB and terabytes (TB).
I hope this abstract on creating and adapting a pattern type from the SmartCloud Application Services has provided a strong start for you to construct a reusable pattern type, the building block for creating virtual patterns. Remember, details for each segment are just a physical click away.
Learn
-
Keep in touch with updates to this series at the author's blog.
- View the steps to create a simple
pattern type with SmartCloud Application Workload Services on YouTube.
-
Learn more about cloud computing technologies at cloud at developerWorks.
-
IBM has encapsulated the most-expert best practices for cloud application deployment and
systems configuration in the IBM PureSystems family of expert integrated systems; get
started at PureSystems at developerWorks.
- Follow developerWorks on
Twitter.
- Watch developerWorks
demos ranging from product installation and setup demos for
beginners, to advanced functionality for experienced developers.
Get products and technologies
-
Access IBM SmartCloud Enterprise.
-
Access more information on IBM PureSystems expert integrated systems.
-
Evaluate IBM
products in the way that suits you best: Download a product trial, try
a product online, use a product in a cloud environment, or spend a few hours
in the
SOA Sandbox learning how to implement Service Oriented Architecture efficiently.
Discuss
- Get involved in the developerWorks
community. Connect with other developerWorks users while exploring the
developer-driven blogs, forums, groups, and wikis.

In recent years, Dominique Vernier focused on Java technologies and cloud architecture. He also has been working in information technology for quite a while where he earned a broad knowledge in such technologies and products as messaging, database, SOA, EAI, client/server, C/C++, and existing frameworks. Dominique also has extensive knowledge in industry areas such as telecom, CRM, logistics, and insurance. He is the author/co-author of four patents having to do with state engines and resource management. At present, Dominique is in charge of the IBM SmartCloud Enterprise solutions on the IBM GTS Global Team.




