/* * Copyright (c) Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1) Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2) Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace XenAPI { /// /// A long-running asynchronous task /// First published in XenServer 4.0. /// public partial class Task : XenObject { public Task() { } public Task(string uuid, string name_label, string name_description, List allowed_operations, Dictionary current_operations, DateTime created, DateTime finished, task_status_type status, XenRef resident_on, double progress, string type, string result, string[] error_info, Dictionary other_config, XenRef subtask_of, List> subtasks, string backtrace) { this.uuid = uuid; this.name_label = name_label; this.name_description = name_description; this.allowed_operations = allowed_operations; this.current_operations = current_operations; this.created = created; this.finished = finished; this.status = status; this.resident_on = resident_on; this.progress = progress; this.type = type; this.result = result; this.error_info = error_info; this.other_config = other_config; this.subtask_of = subtask_of; this.subtasks = subtasks; this.backtrace = backtrace; } /// /// Creates a new Task from a Proxy_Task. /// /// public Task(Proxy_Task proxy) { this.UpdateFromProxy(proxy); } public override void UpdateFrom(Task update) { uuid = update.uuid; name_label = update.name_label; name_description = update.name_description; allowed_operations = update.allowed_operations; current_operations = update.current_operations; created = update.created; finished = update.finished; status = update.status; resident_on = update.resident_on; progress = update.progress; type = update.type; result = update.result; error_info = update.error_info; other_config = update.other_config; subtask_of = update.subtask_of; subtasks = update.subtasks; backtrace = update.backtrace; } internal void UpdateFromProxy(Proxy_Task proxy) { uuid = proxy.uuid == null ? null : (string)proxy.uuid; name_label = proxy.name_label == null ? null : (string)proxy.name_label; name_description = proxy.name_description == null ? null : (string)proxy.name_description; allowed_operations = proxy.allowed_operations == null ? null : Helper.StringArrayToEnumList(proxy.allowed_operations); current_operations = proxy.current_operations == null ? null : Maps.convert_from_proxy_string_task_allowed_operations(proxy.current_operations); created = proxy.created; finished = proxy.finished; status = proxy.status == null ? (task_status_type) 0 : (task_status_type)Helper.EnumParseDefault(typeof(task_status_type), (string)proxy.status); resident_on = proxy.resident_on == null ? null : XenRef.Create(proxy.resident_on); progress = Convert.ToDouble(proxy.progress); type = proxy.type == null ? null : (string)proxy.type; result = proxy.result == null ? null : (string)proxy.result; error_info = proxy.error_info == null ? new string[] {} : (string [])proxy.error_info; other_config = proxy.other_config == null ? null : Maps.convert_from_proxy_string_string(proxy.other_config); subtask_of = proxy.subtask_of == null ? null : XenRef.Create(proxy.subtask_of); subtasks = proxy.subtasks == null ? null : XenRef.Create(proxy.subtasks); backtrace = proxy.backtrace == null ? null : (string)proxy.backtrace; } public Proxy_Task ToProxy() { Proxy_Task result_ = new Proxy_Task(); result_.uuid = uuid ?? ""; result_.name_label = name_label ?? ""; result_.name_description = name_description ?? ""; result_.allowed_operations = (allowed_operations != null) ? Helper.ObjectListToStringArray(allowed_operations) : new string[] {}; result_.current_operations = Maps.convert_to_proxy_string_task_allowed_operations(current_operations); result_.created = created; result_.finished = finished; result_.status = task_status_type_helper.ToString(status); result_.resident_on = resident_on ?? ""; result_.progress = progress; result_.type = type ?? ""; result_.result = result ?? ""; result_.error_info = error_info; result_.other_config = Maps.convert_to_proxy_string_string(other_config); result_.subtask_of = subtask_of ?? ""; result_.subtasks = (subtasks != null) ? Helper.RefListToStringArray(subtasks) : new string[] {}; result_.backtrace = backtrace ?? ""; return result_; } /// /// Creates a new Task from a Hashtable. /// /// public Task(Hashtable table) { uuid = Marshalling.ParseString(table, "uuid"); name_label = Marshalling.ParseString(table, "name_label"); name_description = Marshalling.ParseString(table, "name_description"); allowed_operations = Helper.StringArrayToEnumList(Marshalling.ParseStringArray(table, "allowed_operations")); current_operations = Maps.convert_from_proxy_string_task_allowed_operations(Marshalling.ParseHashTable(table, "current_operations")); created = Marshalling.ParseDateTime(table, "created"); finished = Marshalling.ParseDateTime(table, "finished"); status = (task_status_type)Helper.EnumParseDefault(typeof(task_status_type), Marshalling.ParseString(table, "status")); resident_on = Marshalling.ParseRef(table, "resident_on"); progress = Marshalling.ParseDouble(table, "progress"); type = Marshalling.ParseString(table, "type"); result = Marshalling.ParseString(table, "result"); error_info = Marshalling.ParseStringArray(table, "error_info"); other_config = Maps.convert_from_proxy_string_string(Marshalling.ParseHashTable(table, "other_config")); subtask_of = Marshalling.ParseRef(table, "subtask_of"); subtasks = Marshalling.ParseSetRef(table, "subtasks"); backtrace = Marshalling.ParseString(table, "backtrace"); } public bool DeepEquals(Task other, bool ignoreCurrentOperations) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; if (!ignoreCurrentOperations && !Helper.AreEqual2(this.current_operations, other.current_operations)) return false; return Helper.AreEqual2(this._uuid, other._uuid) && Helper.AreEqual2(this._name_label, other._name_label) && Helper.AreEqual2(this._name_description, other._name_description) && Helper.AreEqual2(this._allowed_operations, other._allowed_operations) && Helper.AreEqual2(this._created, other._created) && Helper.AreEqual2(this._finished, other._finished) && Helper.AreEqual2(this._status, other._status) && Helper.AreEqual2(this._resident_on, other._resident_on) && Helper.AreEqual2(this._progress, other._progress) && Helper.AreEqual2(this._type, other._type) && Helper.AreEqual2(this._result, other._result) && Helper.AreEqual2(this._error_info, other._error_info) && Helper.AreEqual2(this._other_config, other._other_config) && Helper.AreEqual2(this._subtask_of, other._subtask_of) && Helper.AreEqual2(this._subtasks, other._subtasks) && Helper.AreEqual2(this._backtrace, other._backtrace); } internal static List ProxyArrayToObjectList(Proxy_Task[] input) { var result = new List(); foreach (var item in input) result.Add(new Task(item)); return result; } public override string SaveChanges(Session session, string opaqueRef, Task server) { if (opaqueRef == null) { System.Diagnostics.Debug.Assert(false, "Cannot create instances of this type on the server"); return ""; } else { if (!Helper.AreEqual2(_other_config, server._other_config)) { Task.set_other_config(session, opaqueRef, _other_config); } return null; } } /// /// Get a record containing the current state of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static Task get_record(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_record(session.uuid, _task); else return new Task((Proxy_Task)session.proxy.task_get_record(session.uuid, _task ?? "").parse()); } /// /// Get a reference to the task instance with the specified UUID. /// First published in XenServer 4.0. /// /// The session /// UUID of object to return public static XenRef get_by_uuid(Session session, string _uuid) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_by_uuid(session.uuid, _uuid); else return XenRef.Create(session.proxy.task_get_by_uuid(session.uuid, _uuid ?? "").parse()); } /// /// Get all the task instances with the given label. /// First published in XenServer 4.0. /// /// The session /// label of object to return public static List> get_by_name_label(Session session, string _label) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_by_name_label(session.uuid, _label); else return XenRef.Create(session.proxy.task_get_by_name_label(session.uuid, _label ?? "").parse()); } /// /// Get the uuid field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static string get_uuid(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_uuid(session.uuid, _task); else return (string)session.proxy.task_get_uuid(session.uuid, _task ?? "").parse(); } /// /// Get the name/label field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static string get_name_label(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_name_label(session.uuid, _task); else return (string)session.proxy.task_get_name_label(session.uuid, _task ?? "").parse(); } /// /// Get the name/description field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static string get_name_description(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_name_description(session.uuid, _task); else return (string)session.proxy.task_get_name_description(session.uuid, _task ?? "").parse(); } /// /// Get the allowed_operations field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static List get_allowed_operations(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_allowed_operations(session.uuid, _task); else return Helper.StringArrayToEnumList(session.proxy.task_get_allowed_operations(session.uuid, _task ?? "").parse()); } /// /// Get the current_operations field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static Dictionary get_current_operations(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_current_operations(session.uuid, _task); else return Maps.convert_from_proxy_string_task_allowed_operations(session.proxy.task_get_current_operations(session.uuid, _task ?? "").parse()); } /// /// Get the created field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static DateTime get_created(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_created(session.uuid, _task); else return session.proxy.task_get_created(session.uuid, _task ?? "").parse(); } /// /// Get the finished field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static DateTime get_finished(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_finished(session.uuid, _task); else return session.proxy.task_get_finished(session.uuid, _task ?? "").parse(); } /// /// Get the status field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static task_status_type get_status(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_status(session.uuid, _task); else return (task_status_type)Helper.EnumParseDefault(typeof(task_status_type), (string)session.proxy.task_get_status(session.uuid, _task ?? "").parse()); } /// /// Get the resident_on field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static XenRef get_resident_on(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_resident_on(session.uuid, _task); else return XenRef.Create(session.proxy.task_get_resident_on(session.uuid, _task ?? "").parse()); } /// /// Get the progress field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static double get_progress(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_progress(session.uuid, _task); else return Convert.ToDouble(session.proxy.task_get_progress(session.uuid, _task ?? "").parse()); } /// /// Get the type field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static string get_type(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_type(session.uuid, _task); else return (string)session.proxy.task_get_type(session.uuid, _task ?? "").parse(); } /// /// Get the result field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static string get_result(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_result(session.uuid, _task); else return (string)session.proxy.task_get_result(session.uuid, _task ?? "").parse(); } /// /// Get the error_info field of the given task. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static string[] get_error_info(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_error_info(session.uuid, _task); else return (string [])session.proxy.task_get_error_info(session.uuid, _task ?? "").parse(); } /// /// Get the other_config field of the given task. /// First published in XenServer 4.1. /// /// The session /// The opaque_ref of the given task public static Dictionary get_other_config(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_other_config(session.uuid, _task); else return Maps.convert_from_proxy_string_string(session.proxy.task_get_other_config(session.uuid, _task ?? "").parse()); } /// /// Get the subtask_of field of the given task. /// First published in XenServer 5.0. /// /// The session /// The opaque_ref of the given task public static XenRef get_subtask_of(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_subtask_of(session.uuid, _task); else return XenRef.Create(session.proxy.task_get_subtask_of(session.uuid, _task ?? "").parse()); } /// /// Get the subtasks field of the given task. /// First published in XenServer 5.0. /// /// The session /// The opaque_ref of the given task public static List> get_subtasks(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_subtasks(session.uuid, _task); else return XenRef.Create(session.proxy.task_get_subtasks(session.uuid, _task ?? "").parse()); } /// /// Get the backtrace field of the given task. /// First published in XenServer 7.0. /// /// The session /// The opaque_ref of the given task public static string get_backtrace(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_backtrace(session.uuid, _task); else return (string)session.proxy.task_get_backtrace(session.uuid, _task ?? "").parse(); } /// /// Set the other_config field of the given task. /// First published in XenServer 4.1. /// /// The session /// The opaque_ref of the given task /// New value to set public static void set_other_config(Session session, string _task, Dictionary _other_config) { if (session.JsonRpcClient != null) session.JsonRpcClient.task_set_other_config(session.uuid, _task, _other_config); else session.proxy.task_set_other_config(session.uuid, _task ?? "", Maps.convert_to_proxy_string_string(_other_config)).parse(); } /// /// Add the given key-value pair to the other_config field of the given task. /// First published in XenServer 4.1. /// /// The session /// The opaque_ref of the given task /// Key to add /// Value to add public static void add_to_other_config(Session session, string _task, string _key, string _value) { if (session.JsonRpcClient != null) session.JsonRpcClient.task_add_to_other_config(session.uuid, _task, _key, _value); else session.proxy.task_add_to_other_config(session.uuid, _task ?? "", _key ?? "", _value ?? "").parse(); } /// /// Remove the given key and its corresponding value from the other_config field of the given task. If the key is not in that Map, then do nothing. /// First published in XenServer 4.1. /// /// The session /// The opaque_ref of the given task /// Key to remove public static void remove_from_other_config(Session session, string _task, string _key) { if (session.JsonRpcClient != null) session.JsonRpcClient.task_remove_from_other_config(session.uuid, _task, _key); else session.proxy.task_remove_from_other_config(session.uuid, _task ?? "", _key ?? "").parse(); } /// /// Create a new task object which must be manually destroyed. /// First published in XenServer 4.0. /// /// The session /// short label for the new task /// longer description for the new task public static XenRef create(Session session, string _label, string _description) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_create(session.uuid, _label, _description); else return XenRef.Create(session.proxy.task_create(session.uuid, _label ?? "", _description ?? "").parse()); } /// /// Destroy the task object /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static void destroy(Session session, string _task) { if (session.JsonRpcClient != null) session.JsonRpcClient.task_destroy(session.uuid, _task); else session.proxy.task_destroy(session.uuid, _task ?? "").parse(); } /// /// Request that a task be cancelled. Note that a task may fail to be cancelled and may complete or fail normally and note that, even when a task does cancel, it might take an arbitrary amount of time. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static void cancel(Session session, string _task) { if (session.JsonRpcClient != null) session.JsonRpcClient.task_cancel(session.uuid, _task); else session.proxy.task_cancel(session.uuid, _task ?? "").parse(); } /// /// Request that a task be cancelled. Note that a task may fail to be cancelled and may complete or fail normally and note that, even when a task does cancel, it might take an arbitrary amount of time. /// First published in XenServer 4.0. /// /// The session /// The opaque_ref of the given task public static XenRef async_cancel(Session session, string _task) { if (session.JsonRpcClient != null) return session.JsonRpcClient.async_task_cancel(session.uuid, _task); else return XenRef.Create(session.proxy.async_task_cancel(session.uuid, _task ?? "").parse()); } /// /// Set the task status /// First published in XenServer 7.2. /// /// The session /// The opaque_ref of the given task /// task status value to be set public static void set_status(Session session, string _task, task_status_type _value) { if (session.JsonRpcClient != null) session.JsonRpcClient.task_set_status(session.uuid, _task, _value); else session.proxy.task_set_status(session.uuid, _task ?? "", task_status_type_helper.ToString(_value)).parse(); } /// /// Return a list of all the tasks known to the system. /// First published in XenServer 4.0. /// /// The session public static List> get_all(Session session) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_all(session.uuid); else return XenRef.Create(session.proxy.task_get_all(session.uuid).parse()); } /// /// Get all the task Records at once, in a single XML RPC call /// First published in XenServer 4.0. /// /// The session public static Dictionary, Task> get_all_records(Session session) { if (session.JsonRpcClient != null) return session.JsonRpcClient.task_get_all_records(session.uuid); else return XenRef.Create(session.proxy.task_get_all_records(session.uuid).parse()); } /// /// Unique identifier/object reference /// public virtual string uuid { get { return _uuid; } set { if (!Helper.AreEqual(value, _uuid)) { _uuid = value; Changed = true; NotifyPropertyChanged("uuid"); } } } private string _uuid = ""; /// /// a human-readable name /// public virtual string name_label { get { return _name_label; } set { if (!Helper.AreEqual(value, _name_label)) { _name_label = value; Changed = true; NotifyPropertyChanged("name_label"); } } } private string _name_label = ""; /// /// a notes field containing human-readable description /// public virtual string name_description { get { return _name_description; } set { if (!Helper.AreEqual(value, _name_description)) { _name_description = value; Changed = true; NotifyPropertyChanged("name_description"); } } } private string _name_description = ""; /// /// list of the operations allowed in this state. This list is advisory only and the server state may have changed by the time this field is read by a client. /// public virtual List allowed_operations { get { return _allowed_operations; } set { if (!Helper.AreEqual(value, _allowed_operations)) { _allowed_operations = value; Changed = true; NotifyPropertyChanged("allowed_operations"); } } } private List _allowed_operations = new List() {}; /// /// links each of the running tasks using this object (by reference) to a current_operation enum which describes the nature of the task. /// public virtual Dictionary current_operations { get { return _current_operations; } set { if (!Helper.AreEqual(value, _current_operations)) { _current_operations = value; Changed = true; NotifyPropertyChanged("current_operations"); } } } private Dictionary _current_operations = new Dictionary() {}; /// /// Time task was created /// [JsonConverter(typeof(XenDateTimeConverter))] public virtual DateTime created { get { return _created; } set { if (!Helper.AreEqual(value, _created)) { _created = value; Changed = true; NotifyPropertyChanged("created"); } } } private DateTime _created; /// /// Time task finished (i.e. succeeded or failed). If task-status is pending, then the value of this field has no meaning /// [JsonConverter(typeof(XenDateTimeConverter))] public virtual DateTime finished { get { return _finished; } set { if (!Helper.AreEqual(value, _finished)) { _finished = value; Changed = true; NotifyPropertyChanged("finished"); } } } private DateTime _finished; /// /// current status of the task /// [JsonConverter(typeof(task_status_typeConverter))] public virtual task_status_type status { get { return _status; } set { if (!Helper.AreEqual(value, _status)) { _status = value; Changed = true; NotifyPropertyChanged("status"); } } } private task_status_type _status; /// /// the host on which the task is running /// [JsonConverter(typeof(XenRefConverter))] public virtual XenRef resident_on { get { return _resident_on; } set { if (!Helper.AreEqual(value, _resident_on)) { _resident_on = value; Changed = true; NotifyPropertyChanged("resident_on"); } } } private XenRef _resident_on = new XenRef(Helper.NullOpaqueRef); /// /// This field contains the estimated fraction of the task which is complete. This field should not be used to determine whether the task is complete - for this the status field of the task should be used. /// public virtual double progress { get { return _progress; } set { if (!Helper.AreEqual(value, _progress)) { _progress = value; Changed = true; NotifyPropertyChanged("progress"); } } } private double _progress; /// /// if the task has completed successfully, this field contains the type of the encoded result (i.e. name of the class whose reference is in the result field). Undefined otherwise. /// public virtual string type { get { return _type; } set { if (!Helper.AreEqual(value, _type)) { _type = value; Changed = true; NotifyPropertyChanged("type"); } } } private string _type = ""; /// /// if the task has completed successfully, this field contains the result value (either Void or an object reference). Undefined otherwise. /// public virtual string result { get { return _result; } set { if (!Helper.AreEqual(value, _result)) { _result = value; Changed = true; NotifyPropertyChanged("result"); } } } private string _result = ""; /// /// if the task has failed, this field contains the set of associated error strings. Undefined otherwise. /// public virtual string[] error_info { get { return _error_info; } set { if (!Helper.AreEqual(value, _error_info)) { _error_info = value; Changed = true; NotifyPropertyChanged("error_info"); } } } private string[] _error_info = {}; /// /// additional configuration /// First published in XenServer 4.1. /// public virtual Dictionary other_config { get { return _other_config; } set { if (!Helper.AreEqual(value, _other_config)) { _other_config = value; Changed = true; NotifyPropertyChanged("other_config"); } } } private Dictionary _other_config = new Dictionary() {}; /// /// Ref pointing to the task this is a substask of. /// First published in XenServer 5.0. /// [JsonConverter(typeof(XenRefConverter))] public virtual XenRef subtask_of { get { return _subtask_of; } set { if (!Helper.AreEqual(value, _subtask_of)) { _subtask_of = value; Changed = true; NotifyPropertyChanged("subtask_of"); } } } private XenRef _subtask_of = new XenRef(Helper.NullOpaqueRef); /// /// List pointing to all the substasks. /// First published in XenServer 5.0. /// [JsonConverter(typeof(XenRefListConverter))] public virtual List> subtasks { get { return _subtasks; } set { if (!Helper.AreEqual(value, _subtasks)) { _subtasks = value; Changed = true; NotifyPropertyChanged("subtasks"); } } } private List> _subtasks = new List>() {}; /// /// Function call trace for debugging. /// First published in XenServer 7.0. /// public virtual string backtrace { get { return _backtrace; } set { if (!Helper.AreEqual(value, _backtrace)) { _backtrace = value; Changed = true; NotifyPropertyChanged("backtrace"); } } } private string _backtrace = "()"; } }