Question

cvpysdk

  • 2 November 2021
  • 15 replies
  • 191 views

Badge +2

Hello!

I'm using the cvpysdk in order to restore SQL Server databases, but unfortunately I can't find an option to restore out of place and change the name of the database.

Maybe someone here faced this issue and can help me with this?


15 replies

Userlevel 7
Badge +14

Hi @TheOzymandias 

I have checked cvpysdk documentation for SQL Server restores:

https://commvault.github.io/cvpysdk/cvpysdk/instances/sqlinstance.html#cvpysdk.instances.sqlinstance.SQLServerInstance.restore

You can perform an out of place restore to a different server and instance, but I agree, the restore commands here imply the database name remains the same - there is no function/method to change the database name as part of the restore.

Can you change the name of the database post restore?

What’s the use case for changing the database name as part of the restore?

Thanks,

Stuart

Userlevel 1
Badge +2

@TheOzymandias, Here is an example that can cover changing the database name, file path and file name to the same instance. Let me know if you have any questions.

 

# Python script to perform sql out of place restore (different instance, new file path, new file name)

# Change these variable according to your setup
COMMCELL_HOSTNAME = 'dummy_host.dummy.com'
COMMCELL_USER = 'admin'
COMMCELL_PASSWORD = 'dummy_password'
CLIENT_NAME = 'sql_client'
INSTANCE_NAME = 'sql_client\\sql_instance'

# DATABASES is a list of the names of source databases to be restored
DATABASES = ['jtrauy1']

# If DESTINATION_INSTANCE is None, then in place restore is done.
# Please set valid destination instance name to run out of place restore
DESTINATION_INSTANCE = None # Accepted values are None or <<destination_instance_name>>. # Destination instance name should be as listed in Commcell

# If RESTORE_PATH is None, then restore path will be inplace.
RESTORE_PATH = None

# RESTORE_PATH needs to be a list of the files belonging to each database being restored.
# This list has a specific format (including delimiters) to follow: ["|<<original_database_name>>|#12!<<restore_database_name>>|#12!<<logical_file_name>>|#12!<<restore_file_path_with_file_names>>|#12!<<original_file_path_with_file_names>>"]
#
# Example for 1 database with 11 files
#
# [
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy1|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1_zvex.mdf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1.mdf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy1_log|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1_log_zvex.ldf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1_log.ldf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy111|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy11_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy11.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy112|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy12_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy12.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy113|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy13_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy13.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy121|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy21_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy21.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy122|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy22_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy22.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy123|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy23_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy23.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy131|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy31_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy31.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy132|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy32_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy32.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy133|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy33_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy33.ndf'
# ]

# If TO_TIME value is None, then restore from latest backup is done.
# Set TO_TIME value in format YYYY-MM-DD HH:MM:SS to perform point in time restore.
TO_TIME = None # Accepted values are None/'YYYY-MM-DD HH:MM:SS'

from cvpysdk.commcell import Commcell
commcell = Commcell(COMMCELL_HOSTNAME, COMMCELL_USER, COMMCELL_PASSWORD)
client = commcell.clients.get(CLIENT_NAME)
agent = client.agents.get('sql server')
instance = agent.instances.get(INSTANCE_NAME)
job = instance.restore(DATABASES, restore_path=RESTORE_PATH, destination_instance=DESTINATION_INSTANCE, to_time=TO_TIME)
print(f"Restore Job ID:{job.job_id}")

-Chris

Badge +2

@TheOzymandias, Here is an example that can cover changing the database name, file path and file name to the same instance. Let me know if you have any questions.

 

# Python script to perform sql out of place restore (different instance, new file path, new file name)

# Change these variable according to your setup
COMMCELL_HOSTNAME = 'dummy_host.dummy.com'
COMMCELL_USER = 'admin'
COMMCELL_PASSWORD = 'dummy_password'
CLIENT_NAME = 'sql_client'
INSTANCE_NAME = 'sql_client\\sql_instance'

# DATABASES is a list of the names of source databases to be restored
DATABASES = ['jtrauy1']

# If DESTINATION_INSTANCE is None, then in place restore is done.
# Please set valid destination instance name to run out of place restore
DESTINATION_INSTANCE = None # Accepted values are None or <<destination_instance_name>>. # Destination instance name should be as listed in Commcell

# If RESTORE_PATH is None, then restore path will be inplace.
RESTORE_PATH = None

# RESTORE_PATH needs to be a list of the files belonging to each database being restored.
# This list has a specific format (including delimiters) to follow: ["|<<original_database_name>>|#12!<<restore_database_name>>|#12!<<logical_file_name>>|#12!<<restore_file_path_with_file_names>>|#12!<<original_file_path_with_file_names>>"]
#
# Example for 1 database with 11 files
#
# [
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy1|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1_zvex.mdf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1.mdf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy1_log|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1_log_zvex.ldf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\jtrauy1_log.ldf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy111|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy11_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy11.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy112|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy12_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy12.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy113|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy13_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy13.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy121|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy21_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy21.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy122|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy22_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy22.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy123|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy23_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy23.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy131|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy31_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy31.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy132|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy32_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy32.ndf',
# '|jtrauy1|#12!jtrauy1_renamed|#12!jtrauy133|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy33_zvex.ndf|#12!C:\\Program Files\\Microsoft SQL Server\\MSSQL13.SQLAUTO2016\\MSSQL\\DATA\\1jtrauy33.ndf'
# ]

# If TO_TIME value is None, then restore from latest backup is done.
# Set TO_TIME value in format YYYY-MM-DD HH:MM:SS to perform point in time restore.
TO_TIME = None # Accepted values are None/'YYYY-MM-DD HH:MM:SS'

from cvpysdk.commcell import Commcell
commcell = Commcell(COMMCELL_HOSTNAME, COMMCELL_USER, COMMCELL_PASSWORD)
client = commcell.clients.get(CLIENT_NAME)
agent = client.agents.get('sql server')
instance = agent.instances.get(INSTANCE_NAME)
job = instance.restore(DATABASES, restore_path=RESTORE_PATH, destination_instance=DESTINATION_INSTANCE, to_time=TO_TIME)
print(f"Restore Job ID:{job.job_id}")

-Chris

So how can I get those details?

Badge +2

Hi @TheOzymandias 

I have checked cvpysdk documentation for SQL Server restores:

https://commvault.github.io/cvpysdk/cvpysdk/instances/sqlinstance.html#cvpysdk.instances.sqlinstance.SQLServerInstance.restore

You can perform an out of place restore to a different server and instance, but I agree, the restore commands here imply the database name remains the same - there is no function/method to change the database name as part of the restore.

Can you change the name of the database post restore?

What’s the use case for changing the database name as part of the restore?

Thanks,

Stuart

For example if the costumer wants to restore a db from production to dev, but not in the same name.

Userlevel 1
Badge +2

So how can I get those details?

 

You’ll need a REST API call for the database details. See the example below (this API will return the database details and the SQL server instances that it can be restored to).

API: /SQL/RestoreOptions
POST
Body:
{
'restoreDbType': 0,
'sourceInstanceId': 7,
'selectedDatabases': [{
'databaseName': 'yqpwdh1'
}
]
}

• restoreDbType: is to be left at zero. This will return list of SQL instances it can safely be restored to based on the user defined databases passed in list and instance version check (SQL restores can be to same instance version or higher).
• sourceInstanceId: id of source instance
• selectedDatabases: list of databases to restore



Sample response:
{
"sqlDbdeviceItem": [{
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh11.ndf",
"logicalFileName": "yqpwdh111",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh12.ndf",
"logicalFileName": "yqpwdh112",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh13.ndf",
"logicalFileName": "yqpwdh113",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh21.ndf",
"logicalFileName": "yqpwdh121",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh22.ndf",
"logicalFileName": "yqpwdh122",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh23.ndf",
"logicalFileName": "yqpwdh123",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh31.ndf",
"logicalFileName": "yqpwdh131",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh32.ndf",
"logicalFileName": "yqpwdh132",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\1yqpwdh33.ndf",
"logicalFileName": "yqpwdh133",
"fileMaxSize": 10485760,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\yqpwdh1.mdf",
"logicalFileName": "yqpwdh1",
"fileMaxSize": 3211264,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}, {
"fileName": "C:\\\\Program Files\\\\Microsoft SQL Server\\\\MSSQL11.SQL2012\\\\MSSQL\\\\DATA\\\\yqpwdh1_log.ldf",
"logicalFileName": "yqpwdh1_log",
"fileMaxSize": 802816,
"id": 0,
"sqlDBInfo": {
"databaseName": "yqpwdh1",
"databaseId": 35
}

}
],
"sqlDestinationInstances": [{
"serverType": "DataBase Engine",
"genericEntity": {
"clientName": "sqlautocs-nf",
"instanceId": 15,
"clientId": 2,
"instanceName": "SQLAUTOCS-NF\\\\COMMVAULT",
"_type_": 0,
"osType": "Windows"
}

}, {
"serverType": "DataBase Engine",
"genericEntity": {
"clientName": "mcrae",
"instanceId": 6,
"clientId": 7,
"instanceName": "MCRAE\\\\MIXEDCASE",
"_type_": 0,
"osType": "Windows"
}

}, {
"serverType": "DataBase Engine",
"genericEntity": {
"clientName": "mcrae",
"instanceId": 7,
"clientId": 7,
"instanceName": "MCRAE\\\\SQL2012",
"_type_": 0,
"osType": "Windows"
}

}, {
"serverType": "DataBase Engine",
"genericEntity": {
"clientName": "sanchez64",
"instanceId": 8,
"clientId": 8,
"instanceName": "SANCHEZ64",
"_type_": 0,
"osType": "Windows"
}
}
],
"error": {
"errorMessage": "success",
"errorCode": 0
}

}

-Chris

Badge +2

Two more questions @CGarcia :

1. Can I perform a "restore to disk" operation for an SQL Server database(get the .bak file)

 

2. I know I can get the date and time of the last backup. Can I get some more dates of other backups( I want the costumer to see the backup history, but not from the commvault itself)

Userlevel 1
Badge +2

@TheOzymandias what version are you running on your commcell?

Badge +2

@TheOzymandias what version are you running on your commcell?

Version SP20(11.20)

Userlevel 1
Badge +2

Here are 2 examples for Restore to Disk:

Restore to disk of database by last backup
API: v2/sql/instances/{{instanceid}}/databases/{{databaseid}}/export
POST
Body:
{
"overwriteFiles": true,
"destinationEntity": {
"clientId": 6,
},
"destDiskPath": "C:\\temp"
}

Restore to disk of database by job
API: v2/sql/instances/{{instanceid}}/databases/{{databaseid}}/jobs/{{jobid}}/export
POST
Body:
{
"overwriteFiles": true,
"destinationEntity": {
"clientId": 6,
},
"destDiskPath": "C:\\temp"
}

For finding details of other jobs there are some options (see: https://api.commvault.com/#4b95ae15-02f6-82c0-29f3-6382ecba9aba). Here is an example of backup jobs for a specific client.

API: /Job?clientId={{clientId}}&jobFilter=Backup'
GET

-Chris

Badge +2

Here are 2 examples for Restore to Disk:

Restore to disk of database by last backup
API: v2/sql/instances/{{instanceid}}/databases/{{databaseid}}/export
POST
Body:
{
"overwriteFiles": true,
"destinationEntity": {
"clientId": 6,
},
"destDiskPath": "C:\\temp"
}

Restore to disk of database by job
API: v2/sql/instances/{{instanceid}}/databases/{{databaseid}}/jobs/{{jobid}}/export
POST
Body:
{
"overwriteFiles": true,
"destinationEntity": {
"clientId": 6,
},
"destDiskPath": "C:\\temp"
}

For finding details of other jobs there are some options (see: https://api.commvault.com/#4b95ae15-02f6-82c0-29f3-6382ecba9aba). Here is an example of backup jobs for a specific client.

API: /Job?clientId={{clientId}}&jobFilter=Backup'
GET

-Chris

Hi @CGarcia !

In order to get the instanceid and databaseid, i'm trying to send a get request:

GET /v2/sql/instance

I'm getting error 404 but don't know why... because other requests went well and the authentication was fine.

Couldn't upload the picture, but here's the error shortly:

cache-control: private

connection: keep-alive

content-length: 0

date: ...

Userlevel 7
Badge +23

@TheOzymandias , it might be wise to open a support case at this point (unless @CGarcia has ideas).

Userlevel 1
Badge +2

@TheOzymandias, my apologies, I never saw your additional question.

To get a list of databases with their respective instances you can use: /sql/databases

This will get you the entire list of protected databases but I believe this is what you’re looking for.

-Chris

Userlevel 7
Badge +14

Hi @TheOzymandias 

Thanks to @CGarcia detailed responses and guidance, do you have any other questions or can we mark this thread as answered?

Thanks,

Stuart

Badge +2

Well actually yes.

In the request /v2/sql/instances/{instanceid}/databases/{databaseid}/restore

You have some details to add in the body.

I noticed that the "logFilePath" parameter is not applicable. This request restores the mdf and ldf to the same path, as I mentioned in the "dataFilePath" parameter.

We need to restore the mdf to one path and the ldf to another.

And thanks for helping(:

Userlevel 7
Badge +14

Hi @TheOzymandias 

I’ve checked various sources and I don’t believe at this point we have any parameters available to specify a different dataFilePath and logFilePath in cvpysdk or from I have checked REST API.

Please would you raise a support case so that we can check this in more detail and work with you for some specific examples.

I’m guessing we’ll need to involve Development and may well need to submit a change request for an enhancement, but we can get into details on a support case.

If you would PM me the case number once raised, I will track internally and ensure the key points from this discussion are presented.

Thanks,

Stuart

Reply