This is a sample application that is written in C#. It queries entities in Mirage, centralizes endpoints, and migrates a CVD operating system.

//This is the C# sample code of Mirage API, which includes three parts.
//1. Query entities in Mirage, such as policy, volume, pending device, CVD, base layer and app layer
//2. Centralize endpoints.
//3. Migrate CVD Operating System.
//4. CVD assign base layer.
//5. CVD update app layer.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.Threading;
using vmware.mirage.mit.faults;
using vmware.mirage.mit.query;
using vmware.mirage.mit.types;

namespace SampleCode
{
    class MirageApiSample
    {
        private static MitServiceClient Client;

        private static int Main(string[] args)
        {
            if (args.Length < 4)
            {
                Console.WriteLine(
                                  "Usage: SampleCode <Web_Management_Server_IP> <Username> <Password> <migration_domain>");
                return -1;
            }
            Console.WriteLine("---------------- Login ----------------");
            Login(args[0], args[1], args[2]);

            Console.WriteLine("--------------VolumeQuery--------------");
            VolumeQuery("Default");

            Console.WriteLine("--------------PolicyQuery--------------");
            PolicyQuery("VMware Mirage default CVD policy");

            Console.WriteLine("----------------CvdQuery---------------");
            CvdQuery(10001, "MIRAGEDOMAIN");

            Console.WriteLine("-----------PendingDeviceQuery----------");
            PendingDeviceQuery(23);

            Console.WriteLine("----------------CeFlow-----------------");
            CeFlow();

            Console.WriteLine("------------OsMigrationFlow------------");
            OsMigrationFlow(args[1], args[2], args[3]);

            Console.WriteLine("----------ProvisioningFlow-------------");
            ProvisioningFlow(args[1], args[2], args[3]);

            Console.WriteLine("---------CvdAssignBaseLayerFlow---------");
            CvdAssignBaseLayerFlow();

            Console.WriteLine("--------CvdUpdateAppLayerFlow-----------");
            CvdUpdateAppLayerFlow();

            return 0;
        }

        //Login Mirage API server with address, username and password.
        public static void Login(string address, string username, string password)
        {
            // Trust all certificates. This is just for sample code. 
            ServicePointManager.ServerCertificateValidationCallback =
                ((sender, certificate, chain, sslPolicyErrors) => true);

            BasicHttpBinding binding = new BasicHttpBinding
            {
                AllowCookies = true,
                Security =
                {
                    Mode = BasicHttpSecurityMode.Transport
                }
            };

            //Connect to Mirage Web Management Server, default port is 7443
            EndpointAddress endpoint =
                new EndpointAddress(string.Format("https://{0}:7443/mirageapi/MitService.svc", address));
            Client = new MitServiceClient(binding, endpoint);
            Client.Login(username, password);
            Console.WriteLine("Login success!");
        }

        // Query pending devices whose device id is deviceId, only the first page returns.
        public static void PendingDeviceQuery(long deviceId)
        {
            QueryDefinition query = new QueryDefinition
            {
                Filter = new QueryFilterEquals
                {
                    Field = FilterField.DEVICE_ID,
                    Value = new Id
                    {
                        IdValue = deviceId
                    }
                },
                Page = 1 //Page index starts from 1, not 0 
            };
            QueryResult result = Client.PendingDevice_Query(query);
            if (result.Elements.Length == 0)
            {
                return;
            }
            foreach (DeviceDetails deviceDetails in result.Elements)
            {
                Console.WriteLine(
                                  "ID: {0}, name: {1}, user name: {2}, OS version: {3}, vendor name {4}, model name {5}, connected: {6}, last connected time: {7}, operation time: {8}",
                                  deviceDetails.Id.IdValue, deviceDetails.Name, deviceDetails.UserName,
                                  deviceDetails.Os, deviceDetails.VendorName,
                                  deviceDetails.ModelName, deviceDetails.Connected, deviceDetails.LastConnectedTime,
                                  deviceDetails.OperationTime);
            }
        }

        // Query volumes whose name is volumeName, only the first page returns.
        public static void VolumeQuery(string volumeName)
        {
            QueryDefinition query = new QueryDefinition
            {
                Filter = new QueryFilterBeginsWith
                {
                    Field = FilterField.VOLUME_NAME,
                    Value = volumeName
                },
                Page = 1
            };
            QueryResult result = Client.Volume_Query(query);
            if (result.Elements.Length == 0)
            {
                return;
            }
            foreach (VolumeDetails volumeDetails in result.Elements)
            {
                Console.WriteLine("ID: {0}, name: {1}, path: {2}", volumeDetails.Id.IdValue, volumeDetails.Name,
                                  volumeDetails.Path);
            }
        }

        // Query polices whose name is policyName, only the first page returns.
        public static void PolicyQuery(string policyName)
        {
            QueryDefinition query = new QueryDefinition
            {
                Filter = new QueryFilterContains
                {
                    Field = FilterField.POLICY_NAME,
                    Value = policyName
                },
                Page = 1
            };
            QueryResult result = Client.Policy_Query(query);
            if (result.Elements.Length == 0)
            {
                return;
            }
            foreach (PolicyDetails policyDetails in result.Elements)
            {
                Console.WriteLine("ID: {0}, version: {1}.{2}, name: {3}",
                                  policyDetails.ImageId.Id.IdValue, policyDetails.ImageId.Version.Major,
                                  policyDetails.ImageId.Version.Minor, policyDetails.Name);
            }
        }

        // Query Cvd with cvdId. It will throw FaultException<InvalidArgument> when the cvdId is not the Id type.
        public static void CvdQuery(long cvdId)
        {
            QueryFilterEquals filter = new QueryFilterEquals
            {
                Field = FilterField.CVD_ID,
                Value = cvdId //Invalid value type for CVD_ID, expected type: Id
            };
            QueryDefinition query = new QueryDefinition
            {
                Filter = filter,
                Page = 1
            };
            try
            {
                Client.Cvd_Query(query);
            }
            catch (FaultException<InvalidArgument> e)
            {
                InvalidArgument detail = e.Detail;
                if (detail.GetType() == typeof(InvalidArgument))
                {
                    Console.WriteLine("InvalidArgument fault, detail message: " + detail.Message);
                    //Expected output:
                    //InvalidArgument fault, detail message: Bad value for queryDefinition: "Filter value for CVD_ID must be of type Id 
                    //Parameter name: queryDefinition
                }
            }
        }

        // Query Cvd, whose Id isn't cvdId, and cvd name begins with cvdUsername. 
        public static void CvdQuery(long cvdId, string cvdUsername)
        {
            QueryFilterNotEquals filterNotEquals = new QueryFilterNotEquals
            {
                Field = FilterField.CVD_ID,
                Value = new Id
                {
                    IdValue = cvdId
                }
            };
            QueryFilterBeginsWith filterBeginsWith = new QueryFilterBeginsWith
            {
                Field = FilterField.CVD_USER_NAME,
                Value = cvdUsername
            };
            QueryDefinition query = new QueryDefinition
            {
                Filter = new QueryFilterAnd
                {
                    Filters = new QueryFilter[] { filterNotEquals, filterBeginsWith }
                },
                Page = 1
            };
            QueryResult result = Client.Cvd_Query(query);
            if (result.Elements.Length == 0)
            {
                return;
            }
            foreach (CvdDetails cvdDetails in result.Elements)
            {
                Console.WriteLine("ID: {0}, device ID: {1}, policy ID: {2}, machine version: {3}.{4}",
                                  cvdDetails.Id.IdValue, cvdDetails.DeviceId.IdValue, cvdDetails.PolicyId.IdValue,
                                  cvdDetails.MachineVersion.Major, cvdDetails.MachineVersion.Minor);
            }
        }

        // Centralization endpoint flow.
        public static void CeFlow()
        {
            QueryResult result = Client.PendingDevice_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            DeviceDetails pendingDevice = (DeviceDetails)result.Elements[0];

            result = Client.Volume_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            VolumeDetails volume = (VolumeDetails)result.Elements[0];

            result = Client.Policy_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            PolicyDetails policy = (PolicyDetails)result.Elements[0];

            Console.WriteLine("Creating new Cvd...");
            Id[] ids = { pendingDevice.Id };
            BatchResult batchResult = Client.PendingDevice_CreateNewCvd(ids, policy.ImageId, volume.Id);
            OperationResult opResult = batchResult.results[0];
            if (opResult.Success == false)
            {
                Console.WriteLine("failed to create cvd, error: {0}", opResult.Fault);
                return;
            }

            // Check the centralization endpoint flow complete.
            while (true)
            {
                result = Client.Cvd_Query(new QueryDefinition
                {
                    Filter = new QueryFilterEquals
                    {
                        Field = FilterField.CVD_ID,
                        Value = new Id
                        {
                            IdValue = (long)opResult.Result
                        }
                    },
                    Page = 1
                });
                if (result.Elements.Length == 0)
                {
                    return;
                }
                CvdDetails cvdDetails = (CvdDetails)result.Elements[0];
                if (cvdDetails.MachineVersion.Major > 1 || cvdDetails.MachineVersion.Minor > 0)
                {
                    Console.WriteLine("ID: {0}, device ID: {1}, policy ID: {2}, machine version: {3}.{4}",
                                      cvdDetails.Id.IdValue, cvdDetails.DeviceId.IdValue, cvdDetails.PolicyId.IdValue,
                                      cvdDetails.MachineVersion.Major, cvdDetails.MachineVersion.Minor);
                    break;
                }
                Thread.Sleep(TimeSpan.FromMinutes(2));
            }
        }

        //Pending device provisioning flow
        public static void ProvisioningFlow(string username, string password, string domain)
        {
            QueryResult result = Client.PendingDevice_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            DeviceDetails pendingDevice = (DeviceDetails)result.Elements[0];

            result = Client.Volume_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            VolumeDetails volume = (VolumeDetails)result.Elements[0];

            result = Client.Policy_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            PolicyDetails policy = (PolicyDetails)result.Elements[0];

            result = Client.BaseLayer_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            LayerDetails baseLayer = (LayerDetails)result.Elements[0];

            result = Client.AppLayer_Query(new QueryDefinition { Filter = null, Page = 1 });
            if (result.Elements.Length == 0)
            {
                return;
            }
            LayerDetails appLayer = (LayerDetails)result.Elements[0];

            Console.WriteLine("Provisioning new Cvd...");

            Id[] ids = { pendingDevice.Id };
            ImageId[] appLayers = { appLayer.ImageId };
            MachineIdentityInfo identityInfo = new MachineIdentityInfo
            {
                DomainMember = true,
                DomainOrWorkgroupName = domain,
                User = username,
                Password = password
            };
            BatchResult batchResult = Client.PendingDevice_Provision(ids, policy.ImageId, baseLayer.ImageId, appLayers,
                                                                     identityInfo, volume.Id, false);
            OperationResult opResult = batchResult.results[0];
            if (opResult.Success == false)
            {
                Console.WriteLine("failed to provision cvd, error: {0}", opResult.Fault);
                return;
            }

            //Wait for provision complete
            //Assignments include both base layer and app layer assignment.
            WaitForAssignmentsComplete("DeviceProvisioning", new Id{ IdValue = (long)opResult.Result });
        }

        // OS migration flow.
        public static void OsMigrationFlow(string username, string password, string domain)
        {
            // Suppose we have one win7 32bit base layer and one xp cvd
            QueryDefinition query = new QueryDefinition
            {
                Filter = null,
                Page = 1
            };
            QueryResult result = Client.Cvd_Query(query);
            if (result.Elements.Length == 0)
            {
                return;
            }
            CvdDetails cvd = (CvdDetails)result.Elements[0];
            result = Client.BaseLayer_Query(query);
            if (result.Elements.Length == 0)
            {
                return;
            }
            LayerDetails baseLayer = (LayerDetails)result.Elements[0];

            ImageId[] appLayerImageIds = GetAppLayerImageIds();

            MigrationTarget target = new MigrationTarget
            {
                CvdId = cvd.Id,
                IdentityInfo = new MachineIdentityInfo
                {
                    DomainMember = true,
                    DomainOrWorkgroupName = domain,
                    User = username,
                    Password = password
                }
            };

            OperationResult operationResult =
                Client.OsMigration_BeginDownloadOnly(new[] { target }, baseLayer.ImageId, appLayerImageIds, true).results[0];
            if (!operationResult.Success)
            {
                return;
            }

            WaitForOsMigrationDownloadInProgress();
            WaitForOsMigrationDownloadCompleted();

            operationResult = Client.OsMigration_ApplyDownloadOnlyMigration(new[] { cvd.Id }).results[0];
            if (!operationResult.Success)
            {
                return;
            }
            Console.WriteLine("Applying migration...");
            //Wait for migration complete
            WaitForAssignmentsComplete("Migration", cvd.Id);
        }

        //Cvd assign base layer flow
        public static void CvdAssignBaseLayerFlow()
        {
            const string baselayerDownloadOnlyTaskName = "BaseImageDownloadOnly";
            const string applyLayerTaskName = "ApplyLayers";
            QueryResult result = Client.Cvd_Query(new QueryDefinition
            {
                Filter = null,
                Page = 1
            });

            if (result.Elements.Length == 0)
            {
                return;
            }
            CvdDetails cvd = (CvdDetails)result.Elements[0];
            result = Client.BaseLayer_Query(new QueryDefinition
            {
                Filter = null,
                Page = 1
            });

            if (result.Elements.Length == 0)
            {
                return;
            }
            LayerDetails baseLayer = (LayerDetails)result.Elements[0];

            
            //Download only assign base layer
            Console.WriteLine("Base layer download...");
            BatchResult batchResult = Client.Cvd_AssignBaseLayerDownloadOnly(new[]{cvd.Id}, baseLayer.ImageId, true);
            OperationResult opResult = batchResult.results[0];
            if (opResult.Success == false)
            {
                Console.WriteLine("failed to assign base layer for cvd, error: {0}", opResult.Fault);
                return;
            }

            WaitForAssignmentsComplete(baselayerDownloadOnlyTaskName, cvd.Id);

            //Query Assignment and apply 
            result = AssignmentQueryWithTaskAndCvdId(baselayerDownloadOnlyTaskName, cvd.Id);
            if (result.Elements.Length == 0)
            {
                return;
            }
            AssignmentDetails assignmentDetails = (AssignmentDetails) result.Elements[0];

            Console.WriteLine("Apply base layer assignment...");
            batchResult = Client.Assignment_ApplyDownloadOnly(new[]{assignmentDetails.Id}, true);
            opResult = batchResult.results[0];
            if (opResult.Success == false)
            {
                Console.WriteLine("failed to apply layers for cvd, error: {0}", opResult.Fault);
                return;
            }
            //Wait for assignment complete
            //Apply assignment will create a new assignment with task name "ApplyLayers"
            WaitForAssignmentsComplete(applyLayerTaskName, cvd.Id);
        }

        //Cvd update app layer flow
        public static void CvdUpdateAppLayerFlow()
        {
            const string applayerDownloadOnlyTaskName = "AppLayerDownloadOnly";
            const string applyLayerTaskName = "ApplyLayers";
            QueryResult result = Client.Cvd_Query(new QueryDefinition
            {
                Filter = null,
                Page = 1
            });

            if (result.Elements.Length == 0)
            {
                return;
            }
            CvdDetails cvd = (CvdDetails)result.Elements[0];
            result = Client.AppLayer_Query(new QueryDefinition
            {
                Filter = null,
                Page = 1
            });

            if (result.Elements.Length == 0)
            {
                return;
            }
            LayerDetails appLayer = (LayerDetails)result.Elements[0];

            //Download only update app layer
            Console.WriteLine("App layer download...");
            BatchResult batchResult = Client.Cvd_UpdateAppLayerDownloadOnly(new[] { cvd.Id }, new []{ appLayer.ImageId }, null, true);
            OperationResult opResult = batchResult.results[0];
            if (opResult.Success == false)
            {
                Console.WriteLine("failed to update app layer for cvd, error: {0}", opResult.Fault);
                return;
            }

            WaitForAssignmentsComplete(applayerDownloadOnlyTaskName, cvd.Id);

            //Query assignment and apply
            result = AssignmentQueryWithTaskAndCvdId(applayerDownloadOnlyTaskName, cvd.Id);
            if (result.Elements.Length == 0)
            {
                return;
            }
            AssignmentDetails assignmentDetails = (AssignmentDetails)result.Elements[0];

            Console.WriteLine("Apply app layer assignment...");
            batchResult = Client.Assignment_ApplyDownloadOnly(new[] { assignmentDetails.Id }, true);
            opResult = batchResult.results[0];
            if (opResult.Success == false)
            {
                Console.WriteLine("failed to apply layers for cvd, error: {0}", opResult.Fault);
                return;
            }
            //Wait for assignment complete
            //Apply assignment will create a new assignment with task name "ApplyLayers"
            WaitForAssignmentsComplete(applyLayerTaskName, cvd.Id);
        }

        // Check the Cvd completes to download base layer and app layers for migration.
        private static void WaitForOsMigrationDownloadCompleted()
        {
            while (true)
            {
                QueryDefinition query = new QueryDefinition
                {
                    Filter = new QueryFilterEquals
                    {
                        Field = FilterField.DOWNLOAD_ONLY_MIGRATION_STATUS,
                        Value = "Complete"
                    },
                    Page = 1
                };
                QueryResult result = Client.OsMigrationCvd_QueryDownloadOnly(query);
                if (result.Elements.Length != 0)
                {
                    Console.WriteLine("Migration download success!");
                    break;
                }
                Thread.Sleep(TimeSpan.FromMinutes(2));
            }
        }

        // Check the Cvd is downloading base layer or app layers for migration.
        private static void WaitForOsMigrationDownloadInProgress()
        {
            while (true)
            {
                QueryDefinition query = new QueryDefinition
                {
                    Filter = new QueryFilterEquals
                    {
                        Field = FilterField.DOWNLOAD_ONLY_MIGRATION_STATUS,
                        Value = "Downloading"
                    },
                    Page = 1
                };
                QueryResult result = Client.OsMigrationCvd_QueryDownloadOnly(query);
                if (result.Elements.Length != 0)
                {
                    Console.WriteLine("Migration downloading...");
                    break;
                }
                Thread.Sleep(TimeSpan.FromMinutes(2));
            }
        }

        //Wait for assignment complete
        private static void WaitForAssignmentsComplete(string taskName, Id cvdId)
        {
            while (true)
            {
                QueryResult result = AssignmentQueryWithTaskAndCvdId(taskName, cvdId);
                if (result.Elements != null && result.Elements.Length > 0)
                {
                    AssignmentDetails[] assignments = result.Elements.Select(e => (AssignmentDetails)e).ToArray();
                    if (IsAssignmentComplete(assignments))
                    {
                        break;
                    }
                }

                Thread.Sleep(TimeSpan.FromMinutes(2));
            }
        }

        //Query assignment
        private static QueryResult AssignmentQueryWithTaskAndCvdId(string taskName, Id cvdId)
        {
            QueryFilter taskNameFilter = new QueryFilterEquals
            {
                Field = FilterField.ASSIGNMENT_TASK_NAME,
                Value = taskName
            };
            QueryFilter cvdIdFilter = new QueryFilterEquals
            {
                Field = FilterField.ASSIGNMENT_CVD_ID,
                Value = cvdId
            };
            QueryFilterAnd filter = new QueryFilterAnd { Filters = new[] { taskNameFilter, cvdIdFilter } };

            return Client.Assignment_Query(new QueryDefinition { Filter = filter, Page = 1 });
        }

        //Check if all assignments complete
        private static bool IsAssignmentComplete(AssignmentDetails[] assignments)
        {
            if (assignments == null || assignments.Length == 0)
            {
                return false;
            }
            HashSet<string> statusFailed = new HashSet<string>(new[] { "Cancelled", "Rejected", "Blocked" });
            const string statusDone = "Done";

            bool assignmentsDone = true;
            foreach (AssignmentDetails assignment in assignments)
            {
                if (statusFailed.Contains(assignment.Status))
                {
                    Console.WriteLine("Assignment failed, operation failed!");
                    return true;
                }
                assignmentsDone &= assignment.Status.Equals(statusDone);
            }
            if (assignmentsDone)
            {
                Console.WriteLine("Assignment done, operation succeed!");
            }
            return assignmentsDone;
        }

        // Get App layers.
        private static ImageId[] GetAppLayerImageIds()
        {
            QueryResult result = Client.AppLayer_Query(new QueryDefinition { Filter = null, Page = 1 });
            ImageId[] appLayerImageIds;
            if (result.Elements.Length != 0)
            {
                LayerDetails[] appLayers = Array.ConvertAll(result.Elements, a => (LayerDetails)a);
                appLayerImageIds = appLayers.Select(a => a.ImageId).ToArray();
            }
            else
            {
                appLayerImageIds = null;
            }
            return appLayerImageIds;
        }
    }
}