Sample scenario: Get ILM schema

In our last post we saw how to use the enumeration endpoint to search for particular objects.  In this post we take that knowledge to get ILM’s schema.  Since ILM’s schema is dynamic and customizable, you must enumerate the ILM objects related to schema.  There is no static XSD to reference.  The three objects of note:

  • ObjectTypeDescription: This object instance defines an ILM object.  Examples include Person and Group.
  • AttributeTypeDescription.  This object instance defines an ILM attribute. Examples include DisplayName, AccountName, and ExplicitMember.
  • BindingDescription.  This object instance binds an attribute to an object.  Examples include binding DisplayName to Person, binding DisplayName to Group, AccountName to Person, and ExplicitMember to Group.

Please note that the code posted below is slightly changed from the code posted on MSDN Code Gallery.  The key difference is we output the schema to a file instead of printing it to the console.  I realized that reading the console was less than ideal given the large number of ILM objects and attributes.  I uploaded my copy of the output on the MSDN Code Gallery downloads page since I know copying code from blogs can be cumbersome.  This is the schema in ILM “2” RC, and to be honest, I use it as a reference during the week.

The following code should look familiar from last post since it merely uses the enumeration client and combines the output in a useful way.

static void Topic14EnumerateSchema()

        {

            WSEnumerationClient enumerationClient = new WSEnumerationClient();

            enumerationClient.ClientCredentials = GetCredentials();

            Dictionary<String, ResourceManagementObject> AttributeDescriptions = new Dictionary<string, ResourceManagementObject>();

            Dictionary<String, ResourceManagementObject> ObjectDescriptions = new Dictionary<string, ResourceManagementObject>();

            Dictionary<String, List<ResourceManagementObject>> Bindings = new Dictionary<string, List<ResourceManagementObject>>();

 

            // need to get these three ILM objects:

            // ObjectTypeDescription -- defines ILM objects

            // AttributeTypeDescription -- defines ILM attributes

            // BindingDescription -- maps attributes to objects

 

            enumerationClient.Enumerate("/AttributeTypeDescription");

            while (enumerationClient.IsContextValid)

            {

                foreach (ResourceManagementObject obj in enumerationClient.Pull())

                {

                    AttributeDescriptions[obj.ObjectId] = obj;

                }

            }

            enumerationClient.Enumerate("/ObjectTypeDescription");

            while (enumerationClient.IsContextValid)

            {

                foreach (ResourceManagementObject obj in enumerationClient.Pull())

                {

                    ObjectDescriptions[obj.ObjectId] = obj;

                }

            }

            enumerationClient.Enumerate("/BindingDescription");

            while (enumerationClient.IsContextValid)

            {

                foreach (ResourceManagementObject obj in enumerationClient.Pull())

                {

                    String boundObject = obj["BoundObjectType"].AttributeSingleValue.ToString();

                    if (Bindings.ContainsKey(boundObject) == false)

                    {

                        Bindings[boundObject] = new List<ResourceManagementObject>();

                    }

                    Bindings[boundObject].Add(obj);

                }

            }

            using (System.IO.StreamWriter fs = new System.IO.StreamWriter("schema.txt"))

            {

                foreach (ResourceManagementObject objectDescription in ObjectDescriptions.Values)

                {

                    Console.WriteLine(objectDescription["DisplayName"].AttributeSingleValue);

                    fs.WriteLine(objectDescription["DisplayName"].AttributeSingleValue);

                    foreach (ResourceManagementObject binding in Bindings[objectDescription.ObjectId])

                    {

                        ResourceManagementObject attribute = AttributeDescriptions[binding["BoundAttributeType"].AttributeSingleValue.ToString()];

                        if (null == attribute)

                            continue;

                        Console.WriteLine("\t" + attribute["DisplayName"]);

                        fs.WriteLine("\t" + String.Join(",", new string[] { attribute["DisplayName"].AttributeSingleValue.ToString(), attribute["Name"].AttributeSingleValue.ToString(), attribute["DataType"].AttributeSingleValue.ToString() }));

                    }

                }

                fs.Close();

            }

 

            Console.WriteLine("Topic 14 Complete");

        }

Let’ s go over the code:

  1. The first two foreach statements should be pretty clear: we enumerate over every ObjectTypeDescription and AttributeTypeDescription, and we place the objects into their respective dictionaries.
  2. The third foreach statement enumerates all BindingDescription instances and builds an internal mapping of objects to attributes.
  3. We then go over each found object and write it to a line in the file.
  4. Then for each attribute bound to the object we write its DisplayName, Name, and DataType to a line and indent by one tab.
  5. When using ResourceManagementAttribute objects in the sample client code, be sure to use an attribute’s Name and not DisplayName.  If you notice, all of the values we pass as index values are names and not display names.

That’s it!  You now know how to combine data from ILM enumerations into something that’s useful for you and your customers.

Final note about the sample client: internally we treat all data as strings so the data type doesn’t have a direct impact on you explorations.  However, please note that the server enforces data types on all values sent.  These failures result in invalid representation faults.