Managing service code structure

The Source Code of a service follows Service Composition Language (SCL) V3 version. Use the correct syntax when importing or editing a service.

The Service Composition Language structure is as follows:

{
 "service": {
 "specVersion": "v3",
 "catalog_metadata": {
 "name": "",
 "description": "",
 "image": "serviceicon_1.svg",
 "category": "CloudServices",
 "bullets": [
  {
      "title": "Cloud Provider",
      "description": "IBM Bluemix Platform"
    }
  ],
  "providerDisplayName": "IBM",
  "longDescription": "",
  "documentationUrl": "",
  "supportUrl": "",
  "bindable": false,
  "updatable": ""
  "systemTags": true            
  },
  "tags": [],
  "datatypes" :     [
    {
       "id" : "",
       "label": "",
       "description": "",
       "datatype": "",
       "default": "",
       "immutable": false
    },
  "actions": [
    {
       "type": "provision",
       "name": "Provision",
       "description": "Default action for deployment of service",
       "input_parameters": [],
       "flow": {
	     "conditions": [],
	     "templates": [],
	     "resthooks": [],
	     "notifications": [],
	     "sequence": {}
	},
	"output_parameters": []
	  }
	],
	"plans": [
	 {
	   "name": "Standard",
	   "description": "To deploy a Standard plan",
	   "actions": [],
	   "plan_parameters": []
	        "free": It can be true or false. False indicates that it is not free.,
		"metadata": {
                   "currency": "USD",
                   "prices" :{
                     ...		     .
          }
       },

For information about the individual sections in the Service Composition Language V3 structure, see the following sections:

For Service Composition Language samples, see Service samples External link icon.

catalog_metadata

"catalog_metadata": {
   "name": "The name of the service",		
   "description": "A short description of the service",    
   "image": "The name of the icon file. For example: serviceicon_1.svg",
   "category": "The category to which the service is assigned. For example: My Category",
   "bullets": [{
        "title": "The name of the first feature",
        "description": "A description for the first feature"
    },
  ]
  "providerDisplayName": "The display name of the provider",
  "longDescription": "A long of description of the service",  
  "documentationUrl": "The documentation URL",
  "supportUrl": "The support URL",
  "bindable": true or false,
  "updatable": "This is not supported in this release."
  "systemTags": true or fals. If systemTags flag is set to true, then system generated tags are automatically added to the tags section of the service instance.
    },
}

The information in the catalog_metadata section is the information that you provided in the Overview tab when you create the service. This information is overwritten if you import a service file in the Edit Source Code tab.

The image attribute value is the file name of the icon associated to the service. The file name must be serviceicon_<n>.svg where <n> is a number from 1 to 10. If you specify another file name, the image attribute value is changed by default to serviceicon_1.svg.

The bullets attribute contains the list of features that you add in the Overview tab.

You can add additional fields in catalog_metadata to provide additional details about the service in the IBM Cloud Pak for AIOps Catalog.

tags

"tags": [
      {
        "name": "The tag name",
        "label": "The display name of the tag",
        "type": "The type of tag.",
        "immutable": Specify if the parameter is immutable. The value must be true or false,
        "hidden": Specify if the parameter is hidden. The value must be true or false,
        "required": Specify if the parameter is required. The value must be true or false,
        "secured": Specify if the parameter is secured. The value must be true or false,
        "description": "The description of the tag",
        "default": "The default value of the tag",
        "customtype": "The custom type of the tag.",
	"permission": "Specify whether the permission. For example, Read-Write",
	}

If you select Specify Options, then the following additional values are displayed:

"options": [
          {
            "label": "The label of the value",
            "value": "The value",
            "default": Specify if it is a default value. The value must be true or false.
          }
	  {
	  ...
	  ...
	  }
        ]

datatypes

 "datatypes" :     [
        {
           "id" : "is an identifier for your datatype instance.",
           "label": "label",
           "description": "Description",
           "datatype": "The Datatype to which it is mapped.",
           "default": "The default DataObject",
           "immutable": "If the definition has `"immutable": false`, then the deployment page shows a drop-down list of all the DataObjects that are available for the DataType."
        },
]

An example for a datatype wherein the default dataobject is defined.

 "datatypes" :     [
        {
           "id" : "bastionhost1",
           "label": "Bastion Host Configuration",
           "description": "Select Bastion Host Configuration",
           "datatype": "bastionhost",
           "default": "DefaultNoBastionHostRequired",
           "immutable": false
        },
        {
          "id" : "httpproxy",
          "label": "Bastion Host Configuration",
          "description": "Select HTTP Proxy Configuration",
          "datatype": "httpproxy",
          "default": "DefaultNoProxyRequired",
          "immutable": true
        },
    ],

If you have only one DataObject associated to a Datatype, then you can directly use it in the interpolation without datatype mapping here. For interpolation syntax, see Using shared parameters in service interpolations.

actions

"actions": [
    {
      "type": "provision",
      "name": "Provision",

      input_parameter [{
	...
	...
	}]
	flow {
	...
	...
	}
	"output_parameters": []
    }
  ],
  "actions": [
    {
        "type": "bind",
        "name": "Bind",        
	input_parameter [{
	...
	...
	}]
	flow {
	...
	...
	}
	"output_parameters": []
    }
  ],

input_parameter

"input_parameter": [{
		"name": "The name of the input parameter. For example: ssh_key",
		"label": "The label to be displayed in the user interface for this parameter",
		"description": "A short description of the parameter. For example, used to access your server",
		"customtype": "The type of the parameter. For example: String" ,
		"type": "The variable type of customtype. For example: text",
		"immutable": "Specify if the parameter is read-only or not. The value is true for read-only user permissions and is false for read-write user permission.",
		"hidden": "Specify if the parameter is not displayed in the user interface. The value must be true or false",
		"required": "Specify if the parameter is required. The value must be true or false",
		"secured": "Specify if the parameter value is shown as ********. The value can be true for `string` or `password` `customtype` attribute and false for all other attributes.",
		"default": "Default value of the parameter.
		"plans": "


	},
	...
]

If you select Specify Options, then the following additional values are displayed:

"options": [
          {
	    "Default": "Is it a default value of the parameter",
	    "value": "The value",
            "label": "The label of the value",           
          }
	  {
	  ...
	  ...
	  }
        ]

flow

conditions

"conditions": [
          {
            "decision": {
              "title": "The unique title of the decision.",
              "options": [
                {
                  "case": "0",
                  "sequence": {
		  ...},
		  "case": "1",
		  "sequence":{
		  ...},
                }
              ],
              "id": "The generated id for this component. For example: decisionbbb53a59",
              "description": "The description of the component",
              "mapped_parameter": "The parameter to which this component is mapped. This is a mandatory parameter"
            }
          }
        ],

templates

"templates": [{
	"template_name": {
	"title": "The title of the template. For example: 1 Virtual Server with SSH Key",
	"id": "The id of the template component. For example:1virtual6ae83564",
	"template_name": "The name of the template",
	"version:"The version of the template",
	"template_provider: "The provider of the template. For example, IBM",
	"template_content_type": "The content type of the template. For example: prebuilt",
	"instance_name": "The name of the instance associated to this template when deployed",
	"cloud_connection_name": "The name of the cloud connection to be used to deploy the template",
	"content_runtime": "The runtime content",
	"template_params": [
	{
	   "default": "The actual value of the parameter. For read",
	   "description": "A description for this template parameter",
	   "hidden": "Specify if the parameter is not displayed in the user interface. The value must be true or false",
	   "immutable": "Specify if the parameter is read only. The value must be true or false",
           "label": "The label to be displayed in the user interface for this parameter",
	   "name": "The name of the template parameter",						
	   "required": "Specify if the parameter is required. The value must be true or false",
	   "secured": "Specify if the parameter value is shown as asterisk (*). The value must be true or false",
	   "type": "The type of parameter. For example: text",
	},
        {
	  ...
	}
      ]
   }
 ]

The type attribute can have text or list value. If the type value is list, in the default attribute specify the list of the values that can be assigned to the parameter in the format ["<First value>","<Second value>",...,"<Last value>"]. For example, ["IBM Cloud","Amazon EC2"].

If you want to set a template parameter to the value of a input parameter, specify the default attribute value by using the following convention:

"default": "${input_parameters.<service_parameter_name>}

For example, you have the following input parameters:

"input_parameters": [{
   "name": "datacenter",
   "label": "datacenter",
   "description": "Target vSphere datacenter for VM creation",
   "type": "list",
   "default": ["vSphere datacenter 1","vSphere datacenter 2"],
   "hidden": "false",
   "immutable": "false",
   "required": "true",
   "secured": "false",
   "validation": "",
   "dependent": "",
   "dependent_attribute": "",
   "return_type": "text"
},

You can define the following template parameter to set its value to the related input parameter value that you select when ordering the service:

"template_params": [
		{
		"name": "datacenter",
		"label": "datacenter",
		"description": "Target vSphere datacenter for VM creation",
		"type": "text",
		"default": "${input_parameters.datacenter},
		"hidden": "true",
		"immutable": "false",
		"required": "true",
		"secured": "false",
		"validation": "",
		},

In the previous example, note that the hidden attribute value in the template parameter must be set to true to allow the template parameter value to be replaced with the input parameter value when ordering the service.

If you are using a Business Process Manager template, then the following parameters are added to the template:

"async_req": true  //flag to determine whether it is a long running template.
"long_running_delay": "<time in minutes>", //Delay after every poll. Value must be in minutes.
"long_running_timeout": "<time in hour>" //Total time for which polling must be run. The value must be in hours.

Example of a Business Process Manager template:

"templates": [
  {
    "SampleLongRunningProcess": {
      "title": "SampleLongRunningProcess_9de34f",
      "template_name": "SampleLongRunningProcess_25.00746596-7ced-4f98-b382-294e2f702e95_2063.5af7b495-770a-4408-a15b-76ab6f3e890e",
      "version": "1.0"
      "id": "samplel0139690a6",
      "template_type": "BPM",
      "template_content_type": "BPM",
      "template_provider": "BPM",
      "instance_name": "",
      "cloud_connection_name": "BPM Connection",
      "template_data_objects": {},
      "async_req": true,
      "long_running_delay": "5",      
      "long_running_timeout": "24",
      "template_params": {
          "input1": ""
      },
      ...
      ]

Here, in 24 hours, poll happens at a frequency of 5 minutes and in total 288 times. if the Timeout is 24 and delay is 5, then poll happens 24*60/5 = 288 times.

resthooks

"resthooks": [{
	"resthook": {
	"title": "The title of the resthook",
	"id": "The unique id of the resthook",
	"header": {
		"accept": "
		"Content-Type: "application/json",
		The header of the resthook in JSON string format"
		},
	 	"url": "The URL of the external REST server",
        	"method": "The method to poll the external REST server",
        	"payload" : "The request payload if you specified a POST method"
		"timeout": 120,
	}
	"on_destroy":
                {
                "headers": {
                  "accept": "application/json",
                  "Content-Type": "application/json"
                },
                "auth": {
                  "type": "basic",
                  "username": "administrator@vsphere.local",
                  "password": "^(RGFuYzFuZyE=)"
                },
                "url": "https://example.com/create",
                "method": "POST",
                "payload": {
                  "id": "1"
                }
		"timeout": 120,
            }
      }
    ],
      ...
]

The service REST hooks are used to poll an external REST server.

Note: The timeout attribute suggests the maximum time of an URL connection. The default value for timeout is 120 seconds. As the timeout attribute is not available by default in Rest Hooks, you must add the timeout attribute and configure it as per your requirement. The resthook time out occurs either when the network timeout occurs or when the timeout value is reached.

notifications

"notifications": [{
	emailnotification":{
		"title": "The title of the email notification component",
            	"type": "The type of the service notification. For example: email",
		"id": "The identifier of the email notification component",
      		"sender": "The sender address",
		"receiverList": "The list of receiver email addresses",
		"subject": "The subject of the email",
		"body": "The notification body",

      },
      ...
]      

Before using service notifications, you must configure a connection to the SMTP server. For more information, see Configuring a connection for notifications.

sequence

It defines the sequence of activities to deploy the service instance.

For example:

"sequence": {
            "0": "ibmchartf76699ee",
            "1": "emailnot43bfbb6f"
          }

error sequence

It defines the sequence of activities to deploy a error sequence defined in the Error flow section of the Composition tab.

For example:

"error_sequence":{
        "0": servicen247273d"
	}

plans

You can have multiple plans with or without pricing.

Example plan without pricing details:

"plans": [{
      "name": "The name of the plan. For example, Amsterdam",
      "description": "The description of the plan. For example, to deploy in Amsterdam",
      "actions": [],
      "plan_parameters" [{   
            "name": "vm_cpu",
            "label": "Server CPU",
            "customtype": "string",
            "type": "string",
            "immutable": true,
            "hidden": true,
            "required": true,
            "secured": false,
            "description": "Virtual Machine CPU",
            "default": "1"
          }
	]
            "free": true 		
          },
      };
     ]

Where

  • plan_parameters[] - If your service has some input parameters in the provision action that you want to override at the time of deployment, use plan_parameters.
  • free - Signifies whether pricing is associated to the plan or not. If it is associated, then the value is set to false.

For an example of a plan with pricing, see Sample pricing.