Pattern-type (Part 3): Adding Static scalability to a pattern-type with SmartCloud Application Services

In our ongoing journey on the pattern-type elaboration on the SmartCloud Application Services, I explained how to create a simple pattern-type, how to create a master-slave pattern-type, now I will show how to add a static scalability in the master-slave pattern-type. Of Course, this functionality also existing on the PureApplications and IWD.

But first I would like to stress the difference between pattern-type and pattern. A pattern-type provides all components, links, scalability rules… to build a pattern. The best example is the pattern-type for Web-Application (see demo) which provides Enterprise Application, Database components and scalability rules to design your own pattern which you will be able to deploy multiple time. So in this article we show how to create a pattern-type which requires more effort than create a pattern based on a pattern-type. ISV and/or company with home made application which not fit one of the existing pattern-type would be interested in this as pattern-type allows to put all the infrastructure intelligence in the pattern-type in order to deliver the best pattern for your customer.

Don’t forget also that next to virtual application pattern with their pattern-type you have to capability to create virutal system pattern, which allows you to deploy topology with your own images and scripts.

Here by static scalability, I mean define the number of instances during the pattern design.

We will attach a policy component to the slave component, define attributes for this policy and finally adapt the slave vm-templates to import the gathered information from the application model.

AppModel:

We have to add the policy in the application model, this is done adding a component of type policy in the list of components.

    {
        "id": "ScalingPolicy",
        "label": "Slave Server scaling policy",
        "type": "policy",
        "applicableTo": [
            "Slave"
        ],
        "description": "Slave Server scaling policy",
        "groups": [
            {
                "category": "Scaling Type",
                "id": "None",
                "label": "Static",
                "defaultValue": true,
                "attributes": [
                    "intialInstanceNumber"
                ],
                "description": "Description for the Slave scaling policy"
            }
        ],
        "attributes": [
            {
                "id": "intialInstanceNumber",
                "label": "Number of Instances",
                "type": "number",
                "min": 1,
                "required": true,
                "sampleValue": 1,
                "invalidMessage": "This value is required, its valid value greater or equal to 1",
                "description": "Specifies the number of cluster members that are hosting the web application. The default value is 1. Acceptable values range from 1-n."
            }
        ]
    }

The “type” is set to “policy” because we are implementing a policy components.

The “applicableTo” is an array where the id of the component on which the policy will apply is listed. Here our policy apply to the “Slave” component only.

“groups” is a way to group attributes, group with the same id are mutually exclusive. The group selection will be done based on the value selected in the dropdown box generated by this group, here as there is only one element in the group the dropdown box will only have one possibility ‘Static’. The “attributes” array in the group references the attributes that have to be shown when the group is selected.

Then we have the list of attributes, here we have only one attribute “initialInstanceNumber” with its specification.

Physical model:

Now, we have adapt the “Slave.vm” template to retrieve the “initialInstanceNumber” value and set it as min/max values in the “scaling” element of the template.

"scaling":{
                    "min": 1,
                    "max": 1,
            },

This becomes:

{
    "vm-templates": [
        {
#set( $spattrs = $provider.getPolicyAttributes($component, "ScalingPolicy") )
            "scaling":{
#if_value( $spattrs, "intialInstanceNumber", '"min": $value,')
#if_value( $spattrs, "intialInstanceNumber", '"max": $value')
            },
            "name": "${prefix}-MasterSlave",
            "roles": [
                {
                    "parms": {
                        "Attr1": "$attributes.Sattr1"
                    },
                    "type": "Slave",
                    "name": "Slave"
                }
            ],

            "packages":["Slave"]
        }
    ]
}

You can see we use here velocity-macro to modify the template at deployment time.

The first line retrieves the policy attributes by calling the method getPolicyAttributes from the provider for the current component (“Slave”) and for the named policy “ScalingPolicy”. The attributes are stored in the $spattrs variable.

The next lines will insert the text “min:” and “max:” with the value of the “initialInstanceNumber” attribute of the policy.

PS: the “parms” references an attribute ‘Sattr1’ defined in the previous articles. If this attribute is not defined in your appmodel/metadata.json you can either add it in your related component or remove the parms element from the vm file.

Final Test:

Using the pattern described at the beginning of this article where the slave is set with a Static Policy and an initial number of instance set to 2, we get the following deployment which shows one master and two slaves instances.

If we look at the master server logs, we can see that the configuration happens twice, once for each slave servers:

Conclusion:

Adding static scalability on a pattern-type can be done in few steps in your plug-in.