]> xenbits.xensource.com Git - xcp/xen-api.git/commitdiff
Add lifecycle information to datamodel
authorRob Hoes <rob.hoes@citrix.com>
Tue, 25 May 2010 13:26:27 +0000 (14:26 +0100)
committerRob Hoes <rob.hoes@citrix.com>
Tue, 25 May 2010 13:26:27 +0000 (14:26 +0100)
Signed-off-by: Rob Hoes <rob.hoes@citrix.com>
ocaml/idl/datamodel.ml
ocaml/idl/datamodel_types.ml
ocaml/idl/datamodel_utils.ml

index 1e45298317b64e4659eb8855f1547556c93e0b6f..6617e1223c9d27611f2c19893eb58753e049dbd7 100644 (file)
@@ -185,41 +185,53 @@ let rio_release =
        }
 
 let call ~name ?(doc="") ?(in_oss_since=Some "3.0.3") ~in_product_since ?internal_deprecated_since
-    ?result ?(flags=[`Session;`Async])
-    ?(effect=true) ?(tag=Custom) ?(errs=[]) ?(custom_marshaller=false) ?(db_only=false)
-    ?(no_current_operations=false) ?(secret=false) ?(hide_from_docs=false)
-    ?(pool_internal=false)
-    ~allowed_roles
-    ?(map_keys_roles=[])
-    ?(params=[]) ?versioned_params () = 
-  (* if you specify versioned_params then these get put in the params field of the message record;
-     otherwise params go in with no default values and param_release=call_release...
-  *)
-  let call_release = {internal=get_product_releases in_product_since; 
-                     opensource=get_oss_releases in_oss_since;
-                     internal_deprecated_since = internal_deprecated_since;
-                    } in
-  { 
-    msg_name = name;
-    msg_params =
-      (match versioned_params with
-        None ->
-          List.map (fun (ptype, pname, pdoc) -> {param_type=ptype; param_name=pname; param_doc=pdoc; param_release=call_release; param_default=None}) params
-       | Some ps -> ps);
-    msg_result = result; msg_doc = doc;
-    msg_session = List.mem `Session flags; msg_async = List.mem `Async flags;
-    msg_db_only = db_only;
-    msg_release = call_release;
-    msg_has_effect = effect; msg_tag = tag; msg_obj_name="";
-    msg_force_custom = None;
-    msg_errors = List.map (Hashtbl.find errors) errs; msg_secret = secret;
-    msg_custom_marshaller = custom_marshaller;
-    msg_no_current_operations = no_current_operations;
-    msg_hide_from_docs = hide_from_docs;
-    msg_pool_internal = pool_internal;
-    msg_allowed_roles = allowed_roles;
-    msg_map_keys_roles = map_keys_roles
-  }
+       ?result ?(flags=[`Session;`Async])
+       ?(effect=true) ?(tag=Custom) ?(errs=[]) ?(custom_marshaller=false) ?(db_only=false)
+       ?(no_current_operations=false) ?(secret=false) ?(hide_from_docs=false)
+       ?(pool_internal=false)
+       ~allowed_roles
+       ?(map_keys_roles=[])
+       ?(params=[]) ?versioned_params ?lifecycle () =
+       (* if you specify versioned_params then these get put in the params field of the message record;
+        * otherwise params go in with no default values and param_release=call_release...
+        *)
+       let call_release = {internal=get_product_releases in_product_since; 
+               opensource=get_oss_releases in_oss_since;
+               internal_deprecated_since = internal_deprecated_since;
+       } in
+       let lifecycle = match lifecycle with
+               | None ->
+                       let publish = [Published, in_product_since, doc] in
+                       let deprecated = match internal_deprecated_since with
+                               | None -> []
+                               | Some rel -> [Deprecated, rel, ""]
+                       in
+                       publish @ deprecated
+               | Some l -> l
+       in
+       { 
+               msg_name = name;
+               msg_params =
+                       (match versioned_params with
+                       | None ->
+                               List.map (fun (ptype, pname, pdoc) -> {param_type=ptype; param_name=pname;
+                                       param_doc=pdoc; param_release=call_release; param_default=None}) params
+                       | Some ps -> ps);
+               msg_result = result; msg_doc = doc;
+               msg_session = List.mem `Session flags; msg_async = List.mem `Async flags;
+               msg_db_only = db_only;
+               msg_release = call_release;
+               msg_lifecycle = lifecycle;
+               msg_has_effect = effect; msg_tag = tag; msg_obj_name="";
+               msg_force_custom = None;
+               msg_errors = List.map (Hashtbl.find errors) errs; msg_secret = secret;
+               msg_custom_marshaller = custom_marshaller;
+               msg_no_current_operations = no_current_operations;
+               msg_hide_from_docs = hide_from_docs;
+               msg_pool_internal = pool_internal;
+               msg_allowed_roles = allowed_roles;
+               msg_map_keys_roles = map_keys_roles
+       }
 
 let assert_operation_valid enum cls self = call 
   ~in_oss_since:None
@@ -2610,36 +2622,50 @@ let vbd_assert_attachable = call
 
 (** Make an object field record *)
 let field ?(in_oss_since = Some "3.0.3") ?(in_product_since = rel_rio) ?(internal_only = false)
-    ?internal_deprecated_since ?(ignore_foreign_key = false) ?(writer_roles=None) ?(reader_roles=None)
-    ?(qualifier = RW) ?(ty = String) ?(effect = false) ?(default_value = None) ?(persist = true)
-    ?(map_keys_roles=[]) (* list of (key_name,(writer_roles)) for a map field *)
-    name desc =
-  
+       ?internal_deprecated_since ?(ignore_foreign_key = false) ?(writer_roles=None) ?(reader_roles=None)
+       ?(qualifier = RW) ?(ty = String) ?(effect = false) ?(default_value = None) ?(persist = true)
+       ?(map_keys_roles=[]) (* list of (key_name,(writer_roles)) for a map field *)
+       ?lifecycle name desc =
+       
+       let lifecycle = match lifecycle with
+       | None ->
+               let publish = [Published, in_product_since, desc] in
+               let deprecated = match internal_deprecated_since with
+                       | None -> []
+                       | Some rel -> [Deprecated, rel, ""]
+               in
+               publish @ deprecated
+       | Some l -> l
+       in
+       Field {
+               release = {
+                       internal=get_product_releases in_product_since; 
+                       opensource=(get_oss_releases in_oss_since);
+                       internal_deprecated_since=internal_deprecated_since;
+               };
+               lifecycle=lifecycle;
+               qualifier=qualifier; ty=ty; internal_only = internal_only; default_value = default_value;
+               field_name=name; 
+               full_name=[ name ];
+               field_description=desc;
+               field_persist=persist;
+               field_has_effect = effect;
+               field_ignore_foreign_key = ignore_foreign_key;
+               field_setter_roles = writer_roles;
+               field_getter_roles = reader_roles;
+               field_map_keys_roles = map_keys_roles;
+       }
 
-  Field { release={internal=get_product_releases in_product_since; 
-                  opensource=(get_oss_releases in_oss_since);
-                  internal_deprecated_since=internal_deprecated_since;};
-         qualifier=qualifier; ty=ty; internal_only = internal_only; default_value = default_value;
-         field_name=name; 
-         full_name=[ name ];
-         field_description=desc;
-         field_persist=persist;
-         field_has_effect = effect;
-         field_ignore_foreign_key = ignore_foreign_key;
-         field_setter_roles = writer_roles;
-         field_getter_roles = reader_roles;
-         field_map_keys_roles = map_keys_roles;
-         }
-
-let uid ?(in_oss_since=Some "3.0.3") ?(reader_roles=None) refname =
+let uid ?(in_oss_since=Some "3.0.3") ?(reader_roles=None) ?lifecycle refname =
        field
                ~in_oss_since
+               ?lifecycle
                ~qualifier:DynamicRO
                ~ty:(String)
                ~writer_roles:_R_POOL_ADMIN (* only the system should be able to create/modify uuids *)
                ~reader_roles
                "uuid"
-               "unique identifier/object reference"
+               "Unique identifier/object reference"
 
 let allowed_and_current_operations ?(writer_roles=None) ?(reader_roles=None) operations_type =
   [ 
@@ -2660,28 +2686,39 @@ let namespace ?(get_field_writer_roles=fun x->x) ?(get_field_reader_roles=fun x-
 
 let default_field_reader_roles = _R_ALL (* by default, all can read fields *)
 let default_field_writer_roles = _R_POOL_ADMIN (* by default, only root can write to them *)
+
 (** Create an object and map the object name into the messages *)
-let create_obj ~in_oss_since ~in_product_since ~internal_deprecated_since ~gen_constructor_destructor ~gen_events ~persist ~name ~descr ~doccomments ~contents ~messages ~in_db
-  ?(contents_default_reader_roles=default_field_reader_roles) ?(contents_default_writer_roles=None)
-  ?(implicit_messages_allowed_roles=_R_ALL) (* used in implicit obj msgs (get_all, etc) *)
-  ?force_custom_actions:(force_custom_actions=None) (* None,Some(RW),Some(StaticRO) *)
-  ~messages_default_allowed_roles (* used in constructor, destructor and explicit obj msgs *)
-  () =
-    let contents_default_writer_roles = if contents_default_writer_roles=None then messages_default_allowed_roles else contents_default_writer_roles in
-    let get_field_reader_roles = function None->contents_default_reader_roles|r->r in
-    let get_field_writer_roles = function None->contents_default_writer_roles|r->r in
-    let get_msg_allowed_roles = function None->messages_default_allowed_roles|r->r in
-    let contents = List.map (function 
-      | Namespace(n,cs)->namespace ~get_field_writer_roles ~get_field_reader_roles ~name:n ~contents:cs ~idempotent:true ()
-      | Field f->Field{f with field_setter_roles=get_field_writer_roles f.field_setter_roles;
-          field_getter_roles=get_field_reader_roles f.field_getter_roles}
-      ) contents in
-    let msgs = List.map (fun m -> {m with msg_obj_name=name;msg_allowed_roles=get_msg_allowed_roles m.msg_allowed_roles}) messages in
-    { name = name; description = descr; messages = msgs; contents = contents;
-      doccomments = doccomments; gen_constructor_destructor = gen_constructor_destructor; force_custom_actions = force_custom_actions;
-      persist = persist; gen_events = gen_events; obj_release = {internal=get_product_releases in_product_since; opensource=get_oss_releases in_oss_since; internal_deprecated_since = internal_deprecated_since};
-      in_database=in_db; obj_allowed_roles = messages_default_allowed_roles; obj_implicit_msg_allowed_roles = implicit_messages_allowed_roles;
-    }
+let create_obj ?lifecycle ~in_oss_since ~in_product_since ~internal_deprecated_since ~gen_constructor_destructor ~gen_events ~persist ~name ~descr ~doccomments ~contents ~messages ~in_db
+       ?(contents_default_reader_roles=default_field_reader_roles) ?(contents_default_writer_roles=None)
+       ?(implicit_messages_allowed_roles=_R_ALL) (* used in implicit obj msgs (get_all, etc) *)
+       ?force_custom_actions:(force_custom_actions=None) (* None,Some(RW),Some(StaticRO) *)
+       ~messages_default_allowed_roles (* used in constructor, destructor and explicit obj msgs *)
+       () =
+       let contents_default_writer_roles = if contents_default_writer_roles=None then messages_default_allowed_roles else contents_default_writer_roles in
+       let get_field_reader_roles = function None->contents_default_reader_roles|r->r in
+       let get_field_writer_roles = function None->contents_default_writer_roles|r->r in
+       let get_msg_allowed_roles = function None->messages_default_allowed_roles|r->r in
+       let contents = List.map (function 
+               | Namespace(n,cs)->namespace ~get_field_writer_roles ~get_field_reader_roles ~name:n ~contents:cs ~idempotent:true ()
+               | Field f->Field{f with field_setter_roles=get_field_writer_roles f.field_setter_roles;
+                       field_getter_roles=get_field_reader_roles f.field_getter_roles}
+               ) contents in
+       let lifecycle = match lifecycle with
+               | None ->
+                       let publish = [Published, in_product_since, descr] in
+                       let deprecated = match internal_deprecated_since with
+                               | None -> []
+                               | Some rel -> [Deprecated, rel, ""]
+                       in
+                       publish @ deprecated
+               | Some l -> l
+       in
+       let msgs = List.map (fun m -> {m with msg_obj_name=name;msg_allowed_roles=get_msg_allowed_roles m.msg_allowed_roles}) messages in
+       { name = name; description = descr; obj_lifecycle = lifecycle; messages = msgs; contents = contents;
+               doccomments = doccomments; gen_constructor_destructor = gen_constructor_destructor; force_custom_actions = force_custom_actions;
+               persist = persist; gen_events = gen_events; obj_release = {internal=get_product_releases in_product_since; opensource=get_oss_releases in_oss_since; internal_deprecated_since = internal_deprecated_since};
+               in_database=in_db; obj_allowed_roles = messages_default_allowed_roles; obj_implicit_msg_allowed_roles = implicit_messages_allowed_roles;
+       }
 
 (** Additional messages for srs *)
 let dev_config_param =
@@ -5682,6 +5719,7 @@ let event =
     () in
   (* !!! This should call create_obj ~in_db:true like everything else... !!! *)
   {
+    obj_lifecycle=[];
     name = _event;
     gen_events = false;
     description = "Asynchronous event registration and handling";
index 634be87ca7432d1f3ae07cbdc40ec751892f978e..6dff96cae6679ba1a773e6a210e96c1a5b18315e 100644 (file)
@@ -87,15 +87,12 @@ type api_value =
        
 (** Each database field has a qualifier associated with it: *)
 type qualifier =
-       | RW
-               (** Read-write database field whose initial value is specified at the
-               time of object construction. *)
-       | StaticRO
-               (** Read-only database field whose final value is specified at the time
-               of object construction. *)
-       | DynamicRO
-               (** Read-only database field whose value is computed dynamically and
-               not specified at the time of object construction. *)
+       | RW        (** Read-write database field whose initial value is specified at the
+                     * time of object construction. *)
+       | StaticRO  (** Read-only database field whose final value is specified at the time
+                     * of object construction. *)
+       | DynamicRO (** Read-only database field whose value is computed dynamically and
+                     * not specified at the time of object construction. *)
        with rpc
        
 (** Release keeps track of which versions of opensource/internal products fields and messages are included in *)
@@ -105,6 +102,16 @@ type release = {
   internal_deprecated_since: string option; (* first release we said it was deprecated *)
 } with rpc
 
+type lifecycle_change =
+       | Published
+       | Extended
+       | Changed
+       | Deprecated
+       | Removed
+
+and lifecycle_transition = lifecycle_change * string * string
+with rpc
+
 (** Messages are tagged with one of these indicating whether the message was
     specified explicitly in the datamodel, or is one of the automatically
     generated ones. If automatically generated, the tag tells you where it came
@@ -136,6 +143,7 @@ and message = {
     msg_pool_internal: bool; (* only allow on "pool-login" sessions *)
     msg_db_only: bool; (* this is a db_* only message; not exposed through api *)
     msg_release: release;
+    msg_lifecycle: lifecycle_transition list;
     msg_has_effect: bool; (* if true it appears in the custom operations *)
     msg_force_custom: qualifier option; (* unlike msg_has_effect, msg_force_custom=Some(RO|RW) always forces msg into custom operations, see gen_empty_custom.ml *)
     msg_no_current_operations: bool; (* if true it doesnt appear in the current operations *)
@@ -149,6 +157,7 @@ and message = {
 
 and field = {
     release: release;
+    lifecycle: lifecycle_transition list;
     field_persist: bool;
     default_value: api_value option;
     internal_only: bool;
@@ -192,20 +201,22 @@ type persist_option = PersistNothing | PersistEverything with rpc
    PersistNothing - no creates/writes to this table persisted *)
 
 (** An object (or entity) is represented by one of these: *)
-type obj = { name : string;
-            description : string;
-            contents : content list;
-            messages : message list;
-            doccomments : (string * string) list;
-            gen_constructor_destructor: bool;
-            force_custom_actions: qualifier option; (* None,Some(RW),Some(StaticRO) *)
-            obj_allowed_roles: string list option; (* for construct, destruct and explicit obj msgs*)
-            obj_implicit_msg_allowed_roles: string list option; (* for all other implicit obj msgs*)
-            gen_events: bool;
-            persist: persist_option;
-            obj_release: release;
-            in_database: bool (* If the object is in the database *)
-          } with rpc
+type obj = {
+       name : string;
+       description : string;
+       obj_lifecycle: lifecycle_transition list;
+       contents : content list;
+       messages : message list;
+       doccomments : (string * string) list;
+       gen_constructor_destructor: bool;
+       force_custom_actions: qualifier option; (* None,Some(RW),Some(StaticRO) *)
+       obj_allowed_roles: string list option; (* for construct, destruct and explicit obj msgs*)
+       obj_implicit_msg_allowed_roles: string list option; (* for all other implicit obj msgs*)
+       gen_events: bool;
+       persist: persist_option;
+       obj_release: release;
+       in_database: bool (* If the object is in the database *)
+} with rpc
 
 (* val rpc_of_obj : obj -> Rpc.t *)
 (* let s = Jsonrpc.to_string (rpc_of_obj o) *)
index b56f40a90a8dd41291a6a63d8fe3fdc766043f24..c41a2f7b464d2086137d7edcaf66af8af8eb16a6 100644 (file)
@@ -210,6 +210,7 @@ let new_messages_of_field x order fld =
                 msg_session = true;
                 msg_secret = false;
                 msg_release = fld.release;
+                msg_lifecycle = [];
                 msg_has_effect = fld.field_has_effect;
                 msg_force_custom = x.force_custom_actions;
                 msg_no_current_operations = false;
@@ -320,7 +321,7 @@ let messages_of_obj (x: obj) document_order : message list =
                 msg_async=false; msg_custom_marshaller = false; msg_db_only = false;
                 msg_no_current_operations = false;
                 msg_hide_from_docs = false; msg_pool_internal = false;
-                msg_session=false; msg_release=x.obj_release; msg_has_effect=false; msg_tag=Custom;
+                msg_session=false; msg_release=x.obj_release; msg_lifecycle=[]; msg_has_effect=false; msg_tag=Custom;
                 msg_force_custom = x.force_custom_actions;
                 msg_allowed_roles = None;
                 msg_map_keys_roles = [];