Beispiel #1
0
        public static void Run(string hostName, Action action)
        {
            GlobalLockToken token           = new GlobalLockToken("MACH_SHUT_3E94", TimeSpan.FromDays(1), TimeSpan.FromMinutes(10));
            CriticalSection criticalSection = new CriticalSection(new DistributedLockManager(GlobalSettings.WcfHosts["Lock"]));

            criticalSection.RunConcurrent(token, action, _batchSize);
        }
Beispiel #2
0
        /// <summary>
        /// ReSyncs the VM Inventory.
        /// </summary>
        /// <param name="credential">The VSphere credentials to use during synchronization.</param>
        public static void SyncInventory(UserCredential credential)
        {
            UserManager.CurrentUser = credential;

            TraceFactory.Logger.Debug("Acquiring Lock.");
            var token = new GlobalLockToken("VirtualMachineInventorySynchronization", TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(5));

            // Create an explicit CriticalSection here because this call is coming from the UI where ExecutionServices is not initialized.
            CriticalSection criticalSection = new CriticalSection(new DistributedLockManager(GlobalSettings.WcfHosts["Lock"]));

            criticalSection.Run(token, UpdateInventory);
        }
Beispiel #3
0
        /// <summary>
        /// Reserves a block of users.  This MUST be called before being able to get user credentials.
        /// </summary>
        /// <param name="sessionId">The session id.</param>
        /// <param name="accountQuantity">The account quantity which is separated by account pool.</param>
        /// <returns>A <see cref="DomainAccountReservationSet"/> containing information on the reserved accounts.</returns>
        /// <exception cref="System.ArgumentNullException">accountQuantity</exception>
        /// <exception cref="System.InvalidOperationException">Domain accounts have already been reserved for this Session Id</exception>
        public static DomainAccountReservationSet Reserve(string sessionId, DomainAccountQuantityDictionary accountQuantity)
        {
            if (accountQuantity == null)
            {
                throw new ArgumentNullException("accountQuantity");
            }

            DomainAccountReservationSet reservedBlock = new DomainAccountReservationSet(sessionId);

            Action action = new Action(() =>
            {
                try
                {
                    using (AssetInventoryContext context = DbConnect.AssetInventoryContext())
                    {
                        if (context.DomainAccountReservations.Any(e => e.SessionId.Equals(sessionId, StringComparison.OrdinalIgnoreCase)))
                        {
                            //This could be a subsequent call to reserve.  Clear all reservations before proceeding.
                            Release(sessionId);
                        }

                        foreach (var poolType in accountQuantity.Keys)
                        {
                            int userCount          = accountQuantity[poolType];
                            DomainAccountPool pool = SelectPool(context, poolType);
                            int startIndex         = ReserveBlock(context, sessionId, pool, userCount);

                            TraceFactory.Logger.Debug($"New pool reserved: StartIndex: {startIndex}, UserCount: {userCount}, PoolName: {pool.DomainAccountKey}");

                            reservedBlock.Add(poolType, pool, startIndex, userCount);
                        }
                    }
                }
                catch (InsufficientDomainAccountsException)
                {
                    ReleaseSessionReservations(sessionId);
                    throw;
                }
            });

            var token = new GlobalLockToken("DomainAccountReservation", TimeSpan.FromMinutes(11), TimeSpan.FromMinutes(2));

            ExecutionServices.CriticalSection.Run(token, action);

            return(reservedBlock);
        }
Beispiel #4
0
        /// <summary>
        /// Gets a replacement VM if one is not responding.
        /// </summary>
        /// <param name="replacedVMName">The name of the replaced VM.</param>
        /// <returns></returns>
        public static VirtualMachine GetReplacement(string replacedVMName)
        {
            VirtualMachine replacement = null;

            using (AssetInventoryContext context = DbConnect.AssetInventoryContext())
            {
                //Get the SessionId that tried to power-on the failed machine
                FrameworkClient replacedVirtualMachine = Select(context, replacedVMName);

                LockToken lockToken = new GlobalLockToken("VirtualMachineReservation", new TimeSpan(0, 1, 0), new TimeSpan(0, 2, 0));
                ExecutionServices.CriticalSection.Run(lockToken, () =>
                {
                    //Get the next available machine
                    replacement = VirtualMachine.SelectReplacement(replacedVirtualMachine.PlatformUsage, replacedVirtualMachine.HoldId);

                    if (replacement != null)
                    {
                        Reserve
                        (
                            context,
                            replacement.Name,
                            replacedVirtualMachine.PlatformUsage,
                            DateTime.Now,
                            replacedVirtualMachine.SessionId,
                            GlobalSettings.Environment
                        );
                        context.SaveChanges();
                    }
                    else
                    {
                        throw new VMInventoryException("Insufficient VMs available.");
                    }
                });
            }

            return(replacement);
        }
Beispiel #5
0
        /// <summary>
        /// Reserves the requested VMs.
        /// </summary>
        /// <param name="sessionId">The session id.</param>
        /// <param name="credential">The user requesting the reservation.</param>
        /// <param name="requestedVMs">The requested VMs.</param>
        /// <param name="requiredVMQuantity">The required VM quantity.</param>
        /// <returns></returns>
        public static bool Reserve(string sessionId, UserCredential credential, RequestedVMDictionary requestedVMs, VMQuantityDictionary requiredVMQuantity)
        {
            if (requiredVMQuantity == null)
            {
                throw new ArgumentNullException("requiredVMQuantity");
            }

            if (requestedVMs == null)
            {
                throw new ArgumentNullException("requestedVMs");
            }

            DateTime currentTime = DateTime.Now;

            TraceFactory.Logger.Debug(requiredVMQuantity.ToString());

            LockToken lockToken = new GlobalLockToken("VirtualMachineReservation", new TimeSpan(0, 1, 0), new TimeSpan(0, 2, 0));

            ExecutionServices.CriticalSection.Run(lockToken, () =>
            {
                // Need to work with a master list of VMs.  If the requested set is empty, then the master list
                // will come from the database.  Otherwise it will come from the requested set.
                List <VirtualMachine> masterMachineList = GetMasterList(credential, requestedVMs);

                // Copy the required VMs (by Platform) to their own dictionary as items will be removed.
                Dictionary <string, int> remainingPlatforms = requiredVMQuantity.ToDictionary(entry => entry.Key, entry => entry.Value);

                using (AssetInventoryContext context = DbConnect.AssetInventoryContext())
                {
                    // Iterate over each item in the required VM dictionary and process
                    while (remainingPlatforms.Count > 0)
                    {
                        // Get the target platform and required count for each entry
                        string targetPlatformId = remainingPlatforms.ElementAt(0).Key;
                        int targetPlatformCount = remainingPlatforms.ElementAt(0).Value;
                        TraceFactory.Logger.Debug("Target Platform {0} and machine count {1}".FormatWith(targetPlatformId, targetPlatformCount));

                        List <VirtualMachineSelection> machineSelections = GetMachineSelections(targetPlatformId, masterMachineList, remainingPlatforms);


                        // Now try to reserve the VMs.  If the required VMs are more than the available, then
                        // this is an error.  Otherwise work down the list for the number of VMs required.  Since
                        // they are now ordered the VMs selected will be the least unique and those will more
                        // special associations will be further down the list.
                        TraceFactory.Logger.Debug("Machine Platform: {0} - {1} Requested, {2} Available".FormatWith(targetPlatformId, targetPlatformCount, machineSelections.Count));

                        if (machineSelections.Count >= targetPlatformCount)
                        {
                            for (int i = 0; i < targetPlatformCount; i++)
                            {
                                Reserve
                                (
                                    context,
                                    machineSelections[i].Machine.Name,
                                    targetPlatformId,
                                    currentTime,
                                    sessionId,
                                    GlobalSettings.Environment
                                );

                                //Once the machine is reserved, remove it from the master list.
                                masterMachineList.Remove(machineSelections[i].Machine);
                                TraceFactory.Logger.Debug("Host {0} reserved".FormatWith(machineSelections[i].Machine.Name));
                            }
                        }
                        else
                        {
                            throw new VMInventoryException("Only {0} {1} machines available of {2} requested."
                                                           .FormatWith(machineSelections.Count, targetPlatformId, targetPlatformCount));
                        }

                        // Remove the platform that was just processed
                        remainingPlatforms.Remove(targetPlatformId);
                    }

                    // Save all the final changes.  Do this at the end so that if there
                    // is a problem, there is nothing to roll back.
                    context.SaveChanges();
                } //AssetInventoryContext
            }); //reservation.Run

            return(true);
        }
Beispiel #6
0
        public static void Run(string hostName, Action action)
        {
            GlobalLockToken token = new GlobalLockToken("MACHINE_START_B58B", TimeSpan.FromDays(1), TimeSpan.FromMinutes(10));

            ExecutionServices.CriticalSection.RunConcurrent(token, action, _batchSize);
        }