Skip to main content

We've Moved!

Product Documentation has moved to docs.hitachivantara.com
Hitachi Vantara Knowledge

Creating and submitting service requests - use cases

Learn how to use the Ops Center Automator REST API to create and update services.

To access the sample code files referenced in the following use cases and get information on how to set up your environment to run the sample code, go to https://community.hds.com/docs/DOC-1007318.

Create and submit service request (run immediately)

Overview

Search for the Allocate Volumes for Generic Application service and then create a service request to allocate volumes to specified host and submit it.

Name Description
Use case title Create and submit a service request
Description Find the Allocate Volumes for Generic Application service by filtering services by name, then create a service request to allocate volumes to the specified host and submit it
Files sample_code.py, uri_creator.py

These files are located in the following sample code download folder: UC_CREATE_REQUEST

REST APIs to call
  1. GET https://host:port/Automation/v1/objects/Services?HQL::filter=name='Allocate Volumes for Generic Application'
    • Find the Allocate Volumes for Generic Application service by filtering services by name
    • Specify the query string HQL::filter=name='Allocate Volumes for Generic Application' to get only services with the specified name
    • For details about the query string and resource attributes such as name, see the API command set topics.
  2. GET https://host:port/Automation/v1/objects/Services/instanceID/actions/submit
    • Acquire the service property list to fill property values such as target host and volume settings before submitting a service request
  3. POST https://host:port/Automation/v1/objects/Services/instanceID/actions/submit/invoke
    • Submit a service request with a filled property list
Sample code

In the following sample code, the URIs are created by uri_creator.py. See URI Creation and Utility Functions for details.

Variables - The following variables are used in the sample code:

Name Description
USER Username of API user account
PASS Password of API user account
SERVICE_NAME Service name for which you want to create a service request
TARGET_HOST Target host to which volumes are allocated
HDVM_NAME Device Manager name to which the target host is registered
  1. Find a service by filtering services by name.
    """
    Find a service by specified name from all services
    """
    uri = uri_creator.create_get_service_by_name_uri(SERVICE_NAME)
    r = requests.get(uri, headers=headers, auth=(USER, PASS))
    data = r.json()['data']
    if len(data) > 0:
        service  = data[0]
    else:
        print("There is no service having specified name: \"" + SERVICE_NAME + "\"")
        exit(1)
    
    instanceID = service['instanceID']
  2. Acquire the service property list to fill property values such as target host and volume settings before submitting a service request.
    """
    Acquiring property list of the service in order to fill property values such as target host and volume settings before submitting service request
    """
    uri = uri_creator.create_prepare_submit_service_uri(instanceID)
    submitForm = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
    # Update host settings
    hostSetting = find(submitForm['parameters'], 'keyName', "provisioning.hostSetting.targetHosts.value")
    hostSettingValue = { 
        "values": {
            "deviceManagerName": HDVM_NAME, 
            "hosts" : [ 
                { "name": TARGET_HOST } 
            ] 
        } 
    }
    hostSetting['value'] = json.dumps(hostSettingValue)
    
    # Update volume settings
    volumeSetting = find(submitForm['parameters'], 'keyName', "provisioning.volumeSetting.volumeSettings.value")
    volumeSettingValue = json.loads(volumeSetting['value'])
    usageOS = find(volumeSettingValue['values'], "usage", "OS")
    usageOS.update({
        'ldevLabel' : 'OS',
        'capacity' : '10GB'
    })
    usageApp = find(volumeSettingValue['values'], "usage", "App")
    usageApp.update({
        'ldevLabel' : 'App',
        'capacity' : '10GB'
    })
    usageData = find(volumeSettingValue['values'], "usage", "Data")
    usageData.update({
        'ldevLabel' : 'Data',
        'capacity' : '10GB'
    })
    volumeSetting['value'] = json.dumps(volumeSettingValue)
    
    
    # Update task settings
    taskSettings = findByProperty(submitForm['parameters'], 'scheduleType')
    taskSettings.update({
        'name' : 'Task from API'
    })
  3. Submit a service request with a filled property list.
    """
    Submit service request with filled property list
    """
    uri = uri_creator.create_submit_service_uri(instanceID)
    ret = do_action("post", uri, submitForm, USER, PASS).json()
URI creation and utility functions

Get result information of the task such as LUN path information.

"""
This class creates URI for REST API
"""
class UriCreator():
	def __init__(self, host, port="22015", product="Automation", protocol="http", version="v1"):
		self.host = host
		self.port = port
		self.product = product
		self.protocol = protocol
		self.version = version
		self.encode = "utf-8"
	def create_url_base(self):
		uri = self.protocol + "://" + self.host + ":" + self.port + "/" + self.product + "/" + self.version + "/"
		return uri

	def create_get_service_by_name_uri(self, name):
		uri = self.create_url_base() + "/objects/Services?HQL::filter=name='"+name+"'"
		return uri
	
	def create_prepare_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit"
		return uri
	
	def create_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit/invoke"
		return uri

Utility functions in sample code

"""
Print json object information in human readable format
"""
def prettyPrint(jsonObj):
    print(json.dumps(jsonObj, sort_keys=True, indent=4))

"""
Find element of which property and value equals to specified ones from array
"""
def find(array, property, value):
    for elem in array:
        if property in elem.keys() and elem[property] == value:
            return elem
    return
 
"""
Find element of which property name equals to specified one from array
"""
def findByProperty(array, property):
    for elem in array:
        if property in elem.keys():
            return elem
    return    

"""
execute the HTTP request(POST or PUT)
@param method_type HTTP request method(POST or PUT)
@param uri URI to execute HTTP method?
@param body the information of resource
"""
def do_action(method_type,uri,body, user, passwd):
    try:
        if(method_type == "put"):
            r = requests.put(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        elif(method_type == "post"):
            r = requests.post(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        if r.status_code == http.client.OK:
            return r
        else:
            raise(Exception('ERROR HTTP Status = ' + str(r.status_code)))
            return None
    except requests.exceptions.ConnectionError as e:
        print(e.message)
        print("URI : " + uri)
        sys.exit("failed to connect to REST API server. Please check URI parameters.")
    except requests.HTTPError as e:
        print(e.message)
        sys.exit("HTTP error.")
    except Exception as e:
        print(e.message)
        sys.exit("failed to request.")

Create and submit service request (schedule)

Overview

Search for the Allocate Volumes for Generic Application service, then create a service request to allocate volumes to specified host. This service is run at the specified date and time.

Name Description
Use case title Create and submit a service request with a schedule.
Description Find the Allocate Volumes for Generic Application service by filtering services by name, then create a service request to allocate volumes to specified host and submit it with a the specified date/time for running the service.
Files sample_code.py, uri_creator.py

These files are located in the following sample code download folder: UC_CREATE_REQUEST_SCHEDULE.

REST APIs to call
  1. GET https://host:port/Automation/v1/objects/Services?HQL::filter=name='Allocate Volumes for Generic Application'
    • Find the Allocate Volumes for Generic Application service by filtering services by name
    • Specify the query string HQL::filter=name='Allocate Volumes for Generic Application' to get only services with the specified name
    • For details about the query string and resource attributes such as name, see the API command set topics.
  2. GET https://host:port/Automation/v1/objects/Services/instanceID/actions/submit
    • Acquire the service property list to fill property values such as target host and volume settings before submitting service request
    • Also, specify a date/time schedule that specifies when to run the service
  3. POST https://host:port/Automation/v1/objects/Services/instanceID/actions/submit/invoke
    • Submit a service request with a filled property list

In the following sample code, the URIs are created by uri_creator.py. See URI Creation and Utility Functions for details.

Sample code

Variables - The following variables are used in the sample code:

Name Description
USER Username of API user account
PASS Password of API user account
SERVICE_NAME Service name for which you want to create a service request
TARGET_HOST Target host to which volumes are allocated
SCHEDULE_TIME Date/time when the service will run
  1. Find a service by filtering services by name.
    """
    Find a service by filtering services by name
    """
    uri = uri_creator.create_get_service_by_name_uri(SERVICE_NAME)
    r = requests.get(uri, headers=headers, auth=(USER, PASS))
    data = r.json()['data']
    if len(data) > 0:
        #Possibly there are more than one services having same name belonging different service group
        service  = data[0]
    else:
        print("There is no service having specified name: \"" + SERVICE_NAME + "\"")
        exit(1)
    instanceID = service['instanceID']
  2. Acquire the service property list to fill property values such as target host and volume settings before submitting a service request.
    """
    Acquiring property list of the service in order to fill property values such as target host and volume settings before submitting service request
    """
    uri = uri_creator.create_prepare_submit_service_uri(instanceID)
    submitForm = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
    # Update host settings
    hostSetting = find(submitForm['parameters'], 'keyName', "provisioning.hostSetting.targetHosts.value")
    hostSettingValue = { 
        "values": {
            "deviceManagerName": HDVM_NAME, 
            "hosts" : [ 
                { "name": TARGET_HOST } 
            ] 
        } 
    }
    hostSetting['value'] = json.dumps(hostSettingValue)
    
    # Update volume settings
    volumeSetting = find(submitForm['parameters'], 'keyName', "provisioning.volumeSetting.volumeSettings.value")
    volumeSettingValue = json.loads(volumeSetting['value'])
    usageOS = find(volumeSettingValue['values'], "usage", "OS")
    usageOS.update({
        'ldevLabel' : 'OS',
        'capacity' : '10GB'
    })
    usageApp = find(volumeSettingValue['values'], "usage", "App")
    usageApp.update({
        'ldevLabel' : 'App',
        'capacity' : '10GB'
    })
    usageData = find(volumeSettingValue['values'], "usage", "Data")
    usageData.update({
        'ldevLabel' : 'Data',
        'capacity' : '10GB'
    })
    volumeSetting['value'] = json.dumps(volumeSettingValue)
    
    # Update task settings
    taskSettings = findByProperty(submitForm['parameters'], 'scheduleType')
    taskSettings.update({
        'name' : 'Task from API',
        'scheduleType' : 'schedule',
        'scheduledStartTime' : SCHEDULE_TIME
    })
  3. Submit a service request.
    """
    Send service request
    """
    uri = uri_creator.create_submit_service_uri(instanceID)
    ret = do_action("post", uri, submitForm, USER, PASS).json()
URI creation and utility functions

URI creation

"""
This class creates URI for REST API
"""
class UriCreator():
	def __init__(self, host, port="22015", product="Automation", protocol="http", version="v1"):
		self.host = host
		self.port = port
		self.product = product
		self.protocol = protocol
		self.version = version
		self.encode = "utf-8"
	def create_url_base(self):
		uri = self.protocol + "://" + self.host + ":" + self.port + "/" + self.product + "/" + self.version + "/"
		return uri

	def create_get_service_by_name_uri(self, name):
		uri = self.create_url_base() + "/objects/Services?HQL::filter=name='"+name+"'"
		return uri
	
	def create_prepare_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit"
		return uri
	
	def create_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit/invoke"
		return uri

Utility functions in sample code

"""
Print json object information in human readable format
"""
def prettyPrint(jsonObj):
    print(json.dumps(jsonObj, sort_keys=True, indent=4))

"""
Find element of which property and value equals to specified ones from array
"""
def find(array, property, value):
    for elem in array:
        if property in elem.keys() and elem[property] == value:
            return elem
    return
 
"""
Find element of which property name equals to specified one from array
"""
def findByProperty(array, property):
    for elem in array:
        if property in elem.keys():
            return elem
    return    

"""
execute the HTTP request(POST or PUT)
@param method_type HTTP request method(POST or PUT)
@param uri URI to execute HTTP method?
@param body the information of resource
"""
def do_action(method_type,uri,body, user, passwd):
    try:
        if(method_type == "put"):
            r = requests.put(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        elif(method_type == "post"):
            r = requests.post(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        if r.status_code == http.client.OK:
            return r
        else:
            raise(Exception('ERROR HTTP Status = ' + str(r.status_code)))
            return None
    except requests.exceptions.ConnectionError as e:
        print(e.message)
        print("URI : " + uri)
        sys.exit("failed to connect to REST API server. Please check URI parameters.")
    except requests.HTTPError as e:
        print(e.message)
        sys.exit("HTTP error.")
    except Exception as e:
        print(e.message)
        sys.exit("failed to request.")

Create and submit service request after input validation

Overview

Find the Allocate Volumes for Generic Application service by filtering services by name, then create a service request to allocate volumes to the specified host and submit if the user's input is valid.

Name Description
Use case title Create and submit a service request after input validation
Description Find the Allocate Volumes for Generic Application service by filtering services by name, then create a service request to allocate volumes to specified host and submit it if user input is valid
Files sample_code.py, uri_creator.py

These files are located in the following sample code download folder: UC_CREATE_REQUEST_AFTER_INPUT_VALIDATION

REST APIs to call
  1. GET https://host:port/Automation/v1/objects/Services?HQL::filter=name='Allocate Volumes for Generic Application'
    • Find the Allocate Volumes for Generic Application service by filtering services by name
    • Specify the query string HQL::filter=name='Allocate Volumes for Generic Application' to get only services with the specified name
    • For details about the query string and resource attributes such as name, see the API command set topics.
  2. GET https://host:port/Automation/v1/objects/Services/instanceID/actions/submit
    • Acquire the service property list to fill property values such as target host and volume settings before submitting service request
  3. GET https://host:port/Automation/v1/objects/PropertyDefinitions/?serviceID=instanceID
    • Acquire the property definition to validate the user input such as volume label and volume capacity
    • Specify the query string serviceID=instanceID to get only property definitions related to the service
  4. POST https://host:port/Automation/v1/objects/Services/instanceID/actions/submit/invoke
    • Submit a service request with a filled property list

In the following sample code, the URIs are created by uri_creator.py. See URI Creation and Utility Functions for details.

Sample code

Variables - The following variables are used in the sample code:

Name Description
USER Username of API user account
PASS Password of API user account
SERVICE_NAME Service name for which you want to create a service request
TARGET_HOST Target host to which volumes are allocated
HDVM_NAME Device Manager name to which target host is registered
  1. Find a service by filtering services by name.
    """
    Find a service by filtering services by name
    """
    uri = uri_creator.create_get_service_by_name_uri(SERVICE_NAME)
    r = requests.get(uri, headers=headers, auth=(USER, PASS))
    data = r.json()['data']
    if len(data) > 0:
        #Possibly there are more than one services having same name belonging different service group
        service  = data[0]
    else:
        print("There is no service having specified name: \"" + SERVICE_NAME + "\"")
        exit(1)
    instanceID = service['instanceID']
  2. Acquire the service property list to fill property values such as target host and volume settings before submitting a service request.
    """
    Acquiring property list of the service in order to fill property values such as target host and volume settings before submitting service request
    """
    uri = uri_creator.create_prepare_submit_service_uri(instanceID)
    submitForm = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
    # Update host settings
    hostSetting = find(submitForm['parameters'], 'keyName', "provisioning.hostSetting.targetHosts.value")
    hostSettingValue = { 
        "values": {
            "deviceManagerName": HDVM_NAME, 
            "hosts" : [ 
                { "name": TARGET_HOST } 
            ] 
        } 
    }
    hostSetting['value'] = json.dumps(hostSettingValue)
    
    # Update volume settings
    volumeSetting = find(submitForm['parameters'], 'keyName', "provisioning.volumeSetting.volumeSettings.value")
    volumeSettingValue = json.loads(volumeSetting['value'])
    usageOS = find(volumeSettingValue['values'], "usage", "OS")
    usageOS.update({
        'ldevLabel' : 'OS',
        'capacity' : '10GB'
    })
    usageApp = find(volumeSettingValue['values'], "usage", "App")
    usageApp.update({
        'ldevLabel' : 'App',
        'capacity' : '10GB'
    })
    usageData = find(volumeSettingValue['values'], "usage", "Data")
    usageData.update({
        'ldevLabel' : 'Data',
        'capacity' : '10GB'
    })
    volumeSetting['value'] = json.dumps(volumeSettingValue)
    
    
    # Update task settings
    taskSettings = findByProperty(submitForm['parameters'], 'scheduleType')
    taskSettings.update({
        'name' : 'Task from API'
  3. Acquire the property definition to validate whether the user input is valid.
    """
    Get Property Definition to check if input is valid
    """
    uri = uri_creator.create_get_property_definitions_uri(instanceID)
    r = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
    volumeSettingDefinition = find(r['data'], 'keyName', 'provisioning.volumeSetting.volumeSettings.definition')
    volumeSettingDefinitionValue = json.loads(volumeSettingDefinition['defaultValue'])
    volumeLabelDefinition = volumeSettingDefinitionValue['items']['properties']['ldevLabel']
    volumeCapacityDefinition = volumeSettingDefinitionValue['items']['properties']['capacity']
    
    """
    Check if volume label is valid
    """
    def checkVolumeLabel(value):
        if volumeLabelDefinition['minLength'] > len(value):
            return False
        if volumeLabelDefinition['maxLength'] < len(value):
            return False
        if re.match(volumeLabelDefinition['pattern'], value) == None:
            return False
        return True
    
    if checkVolumeLabel(usageApp['ldevLabel']) == False:
        print("Label for Usage App is invalid")
    if checkVolumeLabel(usageOS['ldevLabel']) == False:
        print("Label for Usage OS is invalid")
    if checkVolumeLabel(usageData['ldevLabel']) == False:
        print("Label for Usage Data is invalid")
    
    """
    Get capacity in MB
    """
    def getCapacityInMB(value):
        obj = re.match("^([1-9]+[.]?[0-9]*)(MB|GB|TB)$", value)
        num = float(obj.group(1))
        if obj.group(2) == "MB":
            num = num * 1
        if obj.group(2) == "GB":
            num = num * 1024
        if obj.group(2) == "TB":
            num = num * 1024 * 1024
        return num
    
    """
    Check if volume capacity is valid
    """
    def checkVolumeCapacity(value):
        capacityInMB = getCapacityInMB(value)
        if getCapacityInMB(volumeCapacityDefinition['minValue']) > capacityInMB:
            return False
        if getCapacityInMB(volumeCapacityDefinition['maxValue']) < capacityInMB:
            return False
        return True
    
    if checkVolumeCapacity(usageApp['capacity']) == False:
        print("Capacity for Usage App is invalid")
    if checkVolumeCapacity(usageOS['capacity']) == False:
        print("Capacity for Usage OS is invalid")
    if checkVolumeCapacity(usageData['capacity']) == False:
        print("Capacity for Usage Data is invalid")
  4. Submit a service request.
    """
    Send service request
    """
    uri = uri_creator.create_submit_service_uri(instanceID)
    ret = do_action("post", uri, submitForm, USER, PASS).json()
URI creation and utilities

URI creation

"""
This class creates URI for REST API
"""
class UriCreator():
	def __init__(self, host, port="22015", product="Automation", protocol="http", version="v1"):
		self.host = host
		self.port = port
		self.product = product
		self.protocol = protocol
		self.version = version
		self.encode = "utf-8"
	def create_url_base(self):
		uri = self.protocol + "://" + self.host + ":" + self.port + "/" + self.product + "/" + self.version + "/"
		return uri

	def create_get_service_by_name_uri(self, name):
		uri = self.create_url_base() + "/objects/Services?HQL::filter=name='"+name+"'"
		return uri
	
	def create_prepare_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit"
		return uri
	
	def create_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit/invoke"
		return uri
 
	def create_get_property_definitions_uri(self, serviceID):
		uri = self.create_url_base() + "/objects/PropertyDefinitions?serviceID=" + str(serviceID)
		return uri

Utility functions in sample code

"""
Print json object information in human readable format
"""
def prettyPrint(jsonObj):
    print(json.dumps(jsonObj, sort_keys=True, indent=4))

"""
Find element of which property and value equals to specified ones from array
"""
def find(array, property, value):
    for elem in array:
        if property in elem.keys() and elem[property] == value:
            return elem
    return
 
"""
Find element of which property name equals to specified one from array
"""
def findByProperty(array, property):
    for elem in array:
        if property in elem.keys():
            return elem
    return    

"""
execute the HTTP request(POST or PUT)
@param method_type HTTP request method(POST or PUT)
@param uri URI to execute HTTP method?
@param body the information of resource
"""
def do_action(method_type,uri,body, user, passwd):
    try:
        if(method_type == "put"):
            r = requests.put(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        elif(method_type == "post"):
            r = requests.post(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        if r.status_code == http.client.OK:
            return r
        else:
            raise(Exception('ERROR HTTP Status = ' + str(r.status_code)))
            return None
    except requests.exceptions.ConnectionError as e:
        print(e.message)
        print("URI : " + uri)
        sys.exit("failed to connect to REST API server. Please check URI parameters.")
    except requests.HTTPError as e:
        print(e.message)
        sys.exit("HTTP error.")
    except Exception as e:
        print(e.message)
        sys.exit("failed to request.")

Create and submit service request, then get the result after the task is completed

Overview

Create a service request for Allocate Volumes for Generic Application to allocate volumes to a host, and get the LUN Path Information regarding allocated volumes after the task has completed or failed.

Name Description
Use case title Create and submit a service request, then get result after the task is completed
Description Create a service request of Allocate Volumes for Generic Application to allocate volumes to a host, and get LUN Path Information for the allocated volumes after the task is finished.
Files sample_code.py, uri_creator.py

These files are located in the following sample code download folder: UC_CREATE_REQUEST_AND_GET_RESULT

REST APIs to call
  1. GET https://host:port/Automation/v1/objects/Services?HQL::filter=name='Allocate Volumes for Generic Application
    • Find the Allocate Volumes for Generic Application service by filtering services by name
    • Specify the query string HQL::filter=name='Allocate Volumes for Generic Application' to get only services with the specified name
    • For details about the query string and resource attributes such as name, see the API command set topics.
  2. GET https://host:port/Automation/v1/objects/Services/instanceID/actions/submit
    • Acquire the service property list to fill in property values such as target host and volume settings before submitting the service request
  3. POST https://host:port/Automation/v1/objects/Services/instanceID/actions/submit/invoke
    • Submit service request with filled property list
  4. GET https://host:port/Automation/v1/objects/Tasks/instanceID
    • Get task information to verify that the task is done
  5. GET https://host:port/Automation/v1/objects/PropertyValues?taskID=instanceID
    • Get result information (property values) of the task including LUN Path Information, then find the LUN Path Information by using the keyName of the LUN Path Information, which ends with provisioning.taskResultRawData.lunPaths

In the following sample code, the URIs are created by uri_creator.py. See URI Creation and Utility Functions for details.

Sample code

Variables - The following variables are used in the sample code:

Name Description
USER Username of API user account
PASS Password of API user account
SERVICE_NAME Service name for which you want to create a service request
TARGET_HOST Target host to which volumes are allocated
HDVM_NAME Device Manager name to which the target host is registered
LOOP_TIME Time interval to verify the task is completed
  1. Find a service by filtering services by name.
    """
    Find a service by filtering services by name
    """
    uri = uri_creator.create_get_service_by_name_uri(SERVICE_NAME)
    r = requests.get(uri, headers=headers, auth=(USER, PASS))
    data = r.json()['data']
    
    if len(data) > 0:
        #Possibly there are more than one services having same name belonging different service group
        service  = data[0]
    else:
        print("There is no service having specified name: \"" + SERVICE_NAME + "\"")
        exit(1)
    instanceID = service['instanceID']
  2. Acquire the service property list to create a service request, then fill property values such as target host and volume settings as needed.
    """
    Acquiring property list of the service in order to fill property values such as target host and volume settings before submitting service request
    """
    uri = uri_creator.create_prepare_submit_service_uri(instanceID)
    submitForm = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
    # Update host settings
    hostSetting = find(submitForm['parameters'], 'keyName', "provisioning.hostSetting.targetHosts.value")
    hostSettingValue = { 
        "values": {
            "deviceManagerName": HDVM_NAME, 
            "hosts" : [ 
                { "name": TARGET_HOST } 
            ] 
        } 
    }
    hostSetting['value'] = json.dumps(hostSettingValue)
    # Update volume settings
    volumeSetting = find(submitForm['parameters'], 'keyName', "provisioning.volumeSetting.volumeSettings.value")
    volumeSettingValue = json.loads(volumeSetting['value'])
    usageOS = find(volumeSettingValue['values'], "usage", "OS")
    usageOS.update({
        'ldevLabel' : 'OS',
        'capacity' : '10GB'
    })
    usageApp = find(volumeSettingValue['values'], "usage", "App")
    usageApp.update({
        'ldevLabel' : 'App',
        'capacity' : '10GB'
    })
    usageData = find(volumeSettingValue['values'], "usage", "Data")
    usageData.update({
        'ldevLabel' : 'Data',
        'capacity' : '10GB'
    })
    volumeSetting['value'] = json.dumps(volumeSettingValue)
    # Update task settings
    taskSettings = findByProperty(submitForm['parameters'], 'scheduleType')
    taskSettings.update({
        'name' : 'Task from API'
    })
  3. Submit the service request.
    """
    Submit service request
    """
    uri = uri_creator.create_submit_service_uri(instanceID)
    ret = do_action("post", uri, submitForm, USER, PASS).json()
  4. Wait for the task to finish.
    """
    Wait for task is done
    """
    def wait_for_task_done(uri):
     status = ""
     while(status != "completed" and status != "failed"):
      time.sleep(LOOP_TIME)
      r = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
      status = r["status"]
     return status
    
    uri = ret["affectedResource"][1]
    taskStatus = wait_for_task_done(uri)
    
    if taskStatus != "completed":
     sys.exit(1)
  5. Get result information from the task such as LUN path information.
    """
    Get result (LUN Path information)
    """
    taskId = extract_taskId_from_getUri(uri)
    uri = uri_creator.create_get_propertyValues_for_task_uri(taskId)
    r = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
    
    def propertyValueEndsWith(elem):
        return elem["keyName"].endswith("provisioning.taskResultRawData.lunPaths")
    
    elem = findElem(r["data"], propertyValueEndsWith)
    lunPaths = json.loads(elem["value"])["values"]
    for lunPath in lunPaths:
        print("---------------------------")
        print("Storage\t"+str(lunPath["storageSystemName"]))
        print("LDEV#\t"+str(lunPath["volLdevId"]))
        print("LUN\t"+str(lunPath["volLuNumber"]))
        print("Port\t"+str(lunPath["portName"]))
        print("WWN\t"+str(lunPath["hostPortName"]))
    print("---------------------------")

URI creation

"""
This class creates URI for REST API
"""
class UriCreator():
	def __init__(self, host, port="22015", product="Automation", protocol="http", version="v1"):
		self.host = host
		self.port = port
		self.product = product
		self.protocol = protocol
		self.version = version
		self.encode = "utf-8"

	def create_url_base(self):
		uri = self.protocol + "://" + self.host + ":" + self.port + "/" + self.product + "/" + self.version + "/"
		return uri

	def create_get_service_by_name_uri(self, name):
		uri = self.create_url_base() + "/objects/Services?HQL::filter=name='"+name+"'"
		return uri
	
	def create_prepare_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit"
		return uri
	
	def create_submit_service_uri(self, id):
		uri = self.create_url_base() + "/objects/Services/" + str(id) + "/actions/submit/invoke"
		return uri
	
	def create_get_propertyValues_for_task_uri(self, taskID):
		uri = self.create_url_base() + "/objects/PropertyValues?taskID=" + str(taskID)
		return uri

Utility functions in sample code

URI Creation and utility functions
"""
Print json object information in human readable format
"""
def prettyPrint(jsonObj):
    print(json.dumps(jsonObj, sort_keys=True, indent=4))

"""
Find element of which property and value equals to specified ones from array
"""
def find(array, property, value):
    for elem in array:
        if property in elem.keys() and elem[property] == value:
            return elem
    return

"""
Find element of which property name equals to specified one from array
"""
def findByProperty(array, property):
    for elem in array:
        if property in elem.keys():
            return elem
    return   

"""
Find elem satisfying specified condition from array
"""
def findElem(array, func):
    for elem in array:
        if func(elem):
            return elem
    return None

"""
execute the HTTP request(POST or PUT)
@param method_type HTTP request method(POST or PUT)
@param uri URI to execute HTTP method?
@param body the information of resource
"""
def do_action(method_type,uri,body, user, passwd):
    try:
        if(method_type == "put"):
            r = requests.put(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        elif(method_type == "post"):
            r = requests.post(uri, headers=headers, data=json.dumps(body), auth=(user, passwd))
        if r.status_code == http.client.OK:
            return r
        else:
            raise(Exception('ERROR HTTP Status = ' + str(r.status_code)))
            return None
    except requests.exceptions.ConnectionError as e:
        print(e.message)
        print("URI : " + uri)
        sys.exit("failed to connect to REST API server. Please check URI parameters.")
    except requests.HTTPError as e:
        print(e.message)
        sys.exit("HTTP error.")
    except Exception as e:
        print(e.message)
        sys.exit("failed to request.")

"""
Wait for task done (completed/failed)
"""
def wait_for_task_done(uri):
    print("Waiting task")
    status = ""
    while(status != "completed" and status != "failed"):
        print(".", end="")
        time.sleep(LOOP_TIME)
        r = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
        status = r["status"]
    print("")
    print("Task is finished: " + status)
    return status

"""
Extract instanceID of Task from URI 'http://......./Tasks/{instanceID}'
"""
def extract_taskId_from_getUri(uri):
    m = re.search(r"[.]*\/([\d]+)$", uri)
    return m.group(1)

Get result by task ID after task completed

Overview

Get LUN Path Information after the task for the Allocate Volumes for Generic Application service is done by using the given task ID.

Name Description
Use case title Get result by task ID after the task completes
Description Get LUN Path Information after the Allocate Volumes for Generic Application service task is done by using the specified task ID.
Files sample_code.py, uri_creator.py

These files are located in the following sample code download folder: UC_GET_RESULT_BY_TASK_ID

REST APIs to call
GET https://host:port/Automation/v1/objects/PropertyValues?taskID=instanceID
  • Get result information (property values) for the task including LUN Path Information, then find LUN Path Information from the result by using the LUN Path Information keyname, which ends with provisioning.taskResultRawData.lunPaths

In the following sample code, the URIs are created by uri_creator.py. See URI Creation and Utility Functions for details.

Sample code

Variables - The following variables are used in the sample code:

Name Description
USER Username of API user account
PASS Password of API user account
TASK_ID The task ID to use for viewing property values

Get task result information such as LUN path information

"""
Get result (LUN Path information)
"""
uri = uri_creator.create_get_propertyValues_for_task_uri(TASK_ID)
r = requests.get(uri, headers=headers, auth=(USER, PASS)).json()
 
if r['count'] == 0:
    print("There is no task having specified ID: " + str(TASK_ID))
    sys.exit(1)
    
def propertyValueEndsWith(elem):
    return elem["keyName"].endswith("provisioning.taskResultRawData.lunPaths")
elem = findElem(r["data"], propertyValueEndsWith)

lunPaths = json.loads(elem["value"])["values"]
for lunPath in lunPaths:
    print("---------------------------")
    print("Storage\t"+str(lunPath["storageSystemName"]))
    print("LDEV#\t"+str(lunPath["volLdevId"]))
    print("LUN\t"+str(lunPath["volLuNumber"]))
    print("Port\t"+str(lunPath["portName"]))
    print("WWN\t"+str(lunPath["hostPortName"]))
print("---------------------------")
URI creation and utility functions

URI creation

"""
This class creates URI for REST API
"""
class UriCreator():
	def __init__(self, host, port="22015", product="Automation", protocol="http", version="v1"):
		self.host = host
		self.port = port
		self.product = product
		self.protocol = protocol
		self.version = version
		self.encode = "utf-8"

	def create_url_base(self):
		uri = self.protocol + "://" + self.host + ":" + self.port + "/" + self.product + "/" + self.version + "/"
		return uri
	
	def create_get_propertyValues_for_task_uri(self, taskID):
		uri = self.create_url_base() + "/objects/PropertyValues?taskID=" + str(taskID)
		return uri

Utility functions in sample code

"""
Print json object information in human readable format
"""
def prettyPrint(jsonObj):
    print(json.dumps(jsonObj, sort_keys=True, indent=4))


"""
Find element of which property and value equals to specified ones from array
"""
def find(array, property, value):
    for elem in array:
        if property in elem.keys() and elem[property] == value:
            return elem
    return

"""
Find elem satisfying specified condition from array
"""
def findElem(array, func):
    for elem in array:
        if func(elem):
            return elem
    return None