示例#1
0
        /*
         *  In the Changed event, RoleEnvironment.CurrentRoleInstance.Role.Instances returns the target role instances,
         *  not the original role instances. If you need to know about the original instances,
         *  you can save this information when the Changing event fires and access it from the Changed event
         *  (since these events are always fired in sequence).
         */
        private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
        {
            targetNumOfInstances = RoleEnvironment.CurrentRoleInstance.Role.Instances.Count;
            Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > RoleEnvironmentChanged Eventhandler logging target instance count of {1} <br>", DateTime.Now.ToString(), targetNumOfInstances);
            Logfile.Get(logfile).Update();

            // The change is a downscale! Delete Mcr flag entry from db
            if (originalNumOfInstances > targetNumOfInstances)
            {
                using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                {
                    try
                    {
                        // The highest role instance id was determined in the changing event
                        ImagingProcessorWorkerInstance entry = null;
                        var queryResults = db.ImagingProcessorWorkerInstances.Where(en => en.RoleInstanceId == highestRoleInstanceId);
                        if (queryResults.Count() > 0)
                        {
                            entry = queryResults.First();
                        }

                        if (lowestRoleInstanceId) // The role instance with the lowest id deletes the db entry in case of downscale.
                        {
                            Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Delete database entry with key {1} <br>", DateTime.Now.ToString(), highestRoleInstanceId);
                            Logfile.Get(logfile).Update();

                            // Delete entry from DB
                            db.ImagingProcessorWorkerInstances.Remove(entry);
                            db.SaveChanges();
                        }
                    }
                    catch (Exception ex)
                    {
                        Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Failed to delete McrInstalled flag DB entry. <br>", DateTime.Now.ToString());
                        Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Exception: {1} <br>", DateTime.Now.ToString(), ex.Message);
                        Logfile.Get(logfile).Update();
                        throw;
                    }
                }
            }
        }
示例#2
0
        private async Task RunAsync(CancellationToken cancellationToken)
        {
            // 1. Check if this is after restart and "MCR is installed" already
            //
            bool   mcrAlreadyInstalled = false;
            string line = "";

            try
            {
                using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                {
                    ImagingProcessorWorkerInstance entry = null;
                    var queryResults = db.ImagingProcessorWorkerInstances.Where(e => e.RoleInstanceId == RoleEnvironment.CurrentRoleInstance.Id);
                    if (queryResults.Count() > 0)
                    {
                        entry = queryResults.First(); // Es gibt natürlich nur ein DB Eintrag mit dem Schlüssel RoleInstanceId
                    }
                    if (entry == null)                // First start of this Instance -> Create and add new DB entry
                    {
                        //
                        entry = new ImagingProcessorWorkerInstance();
                        entry.RoleInstanceId = RoleEnvironment.CurrentRoleInstance.Id;
                        entry.McrInstalled   = false;
                        entry.Timestamp      = DateTime.UtcNow;
                        db.ImagingProcessorWorkerInstances.Add(entry);
                        db.SaveChanges();
                        // mcrAlreadyInstalled is still false
                    }
                    else
                    {
                        if (entry.McrInstalled == true)
                        {
                            mcrAlreadyInstalled = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Failed to use McrInstalled flag. <br>", DateTime.Now.ToString());
                Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Exception: {1} <br>", DateTime.Now.ToString(), ex.Message);
                Logfile.Get(logfile).Update();
                mcrAlreadyInstalled = false;
            }

            // *************DEBUG*****************
            mcrAlreadyInstalled = true; // DEBUG


            // 2. Poll the MCR Installation Log if mcrAlreadyInstalled == false
            //
            Stopwatch stopWatch = new Stopwatch();
            bool      timeout   = false;

            stopWatch.Start();
            while (!mcrAlreadyInstalled && true)
            {
                try
                {
                    // Timeout
                    if (stopWatch.Elapsed > TimeSpan.FromMinutes(30))
                    {
                        timeout = true;
                        break;
                    }

                    // Sleep
                    await Task.Delay(TimeSpan.FromMinutes(5));

                    if (!File.Exists(mcrlog))
                    {
                        continue;
                    }

                    line = File.ReadLines(mcrlog).Last();
                    if (!line.Contains("End - Successful"))
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    // Probably file reading errors because the MCR installer uses the file
                    continue;
                }
            }


            //
            // MCR is installed now -->Set the flag in DB and Reboot
            if (!mcrAlreadyInstalled && timeout == false)
            {
                try
                {
                    using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                    {
                        // Update DB entry and set the McrInstalled Flag to true
                        var entry = db.ImagingProcessorWorkerInstances.Where(e => e.RoleInstanceId == RoleEnvironment.CurrentRoleInstance.Id).First(); // // Es gibt natürlich nur ein DB Eintrag mit dem Schlüssel RoleInstanceId
                        db.Entry(entry).Entity.McrInstalled = true;
                        db.Entry(entry).Entity.Timestamp    = DateTime.UtcNow;
                        db.Entry(entry).State = EntityState.Modified;
                        db.SaveChanges();

                        // Restart Worker Role
                        // Update: Der User nach dem Startup Task darf wohl kein shuttdown ausführen --> benutze schtasks
                        //string stat = ExecuteCommandSync("shutdown /R /F");

                        // Mit schtasks
                        DateTime executionTime = DateTime.Now.Add(new TimeSpan(0, 1, 0));
                        string   date          = string.Format("{0}/{1}/{2}", executionTime.Month.ToString("d2"), executionTime.Day.ToString("d2"), executionTime.Year);
                        string   time          = string.Format("{0}:{1}", executionTime.Hour.ToString("d2"), executionTime.Minute.ToString("d2"));
                        string   cmd           = string.Format("schtasks /CREATE /TN RebootRoleInstance /SC ONCE /SD {0} /ST {1} /RL HIGHEST /RU scheduser /RP Qwer123 /TR \"shutdown /R /F\" /F", date, time);
                        string   stat          = ExecuteCommandSync(cmd);
                        Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > {1} <br>", DateTime.Now.ToString(), stat);
                        Logfile.Get(logfile).Update();
                    }
                }
                catch (Exception ex)
                {
                    Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Failed writing to update McrInstalled flag and reboot. <br>", DateTime.Now.ToString());
                    Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Exception: {1} <br>", DateTime.Now.ToString(), ex.Message);
                    Logfile.Get(logfile).Update();
                }
            }
            // Timeout --> Write to log and do Not start Event Processor
            if (!mcrAlreadyInstalled && timeout == true)
            {
                Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Timeout occured during MCR Installation Polling. <br>", DateTime.Now.ToString());
                Logfile.Get(logfile).Update();
            }
            // Reboot and MCR is already installed --> Start Event Processor
            if (mcrAlreadyInstalled)
            {
                //
                // Create EventProcessorHost

                /*the iotHubD2cEndpoint in the example is the name of the device-to - cloud endpoint on your IoT hub.
                 * Technically, and IoT hub could have multiple endpoints that are compatible with Event Hubs.
                 * At this time the only Event Hubs - compatible endpoint is called "messages/events", so it is a fixed string. */
                string iotHubD2cEndpoint = "messages/events";
                string eventHubName      = CloudConfigurationManager.GetSetting("iotHubName"); //"IsmIoTHub";
                string consumerGroupName = EventHubConsumerGroup.DefaultGroupName;
                // Alternativ geht auch CurrentRoleInstance.Id (ist auch unique)
                //string eventProcessorHostName = Guid.NewGuid().ToString();

                string eventProcessorHostName = RoleEnvironment.CurrentRoleInstance.Id;
                // leaseContainerName-Parameter wie im scaled out event processing beispiel:
                // here it's using eventhub as lease name. but it can be specified as any you want.
                // if the host is having same lease name, it will be shared between hosts.
                // by default it is using eventhub name as lease name.
                eventProcessorHost = new EventProcessorHost(eventProcessorHostName,
                                                            iotHubD2cEndpoint,                                     // eigentlich steht hier der EventHub Name aber siehe Kommentar, bei IoTHubs ist hier der fixe string "messages/events" notwendig
                                                            consumerGroupName,
                                                                                                                   //iotHubConnectionString,
                                                            CloudConfigurationManager.GetSetting("ismiothub"),     //System.Configuration.ConfigurationSettings.AppSettings.Get("ismiothub"),
                                                                                                                   //EventProcessor.StorageConnectionString,
                                                            CloudConfigurationManager.GetSetting("ismiotstorage"), //System.Configuration.ConfigurationSettings.AppSettings.Get("ismiotstorage"),
                                                            eventHubName.ToLowerInvariant());

                factory = new EventProcessorFactory(logfile);
                await eventProcessorHost.RegisterEventProcessorFactoryAsync(factory);

                // Register EventProcessorHost
                Logfile.Get(logfile).fTextout("{0} > Registering EventProcessor... <br>", DateTime.Now.ToString());
                Logfile.Get(logfile).Update();

                // Ansatz ohne Factory. Hatte jedoch den Nachteil, dass man keine Referenz auf das EventProcessor Objekt
                // hat und somit z.B. keine Eventhandler registrieren konnte. Parameter an Konstruktor gigen ja auch nicht,
                // weil dieser niemals sichtbar aufgerufen wird bei dem Ansatz
                //eventProcessorHost.RegisterEventProcessorAsync<EventProcessor>().Wait();
            }

            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(TimeSpan.FromHours(1), cancellationToken);
            }
        }