コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void OnScheduleError(object sender, Schedule.ExceptionEventArgs e)
        {
            // Esecuzione di ogni singolo task schedulato
            ChannelRefInfo instance = (ChannelRefInfo)sender;

            PublisherException ex = null;

            if (e.Error.GetType() == typeof(PublisherException))
            {
                ex = (PublisherException)e.Error;
            }
            else
            {
                ex = new PublisherException(ErrorCodes.UNHANDLED_ERROR, e.Error.Message);
            }

            DataAccess.PublisherDataAdapter.SaveError
            (
                new ErrorInfo
            {
                IdInstance       = instance.Id,
                ErrorCode        = ex.ErrorCode,
                ErrorDescription = ex.Message,
                ErrorStack       = ex.ToString(),
                ErrorDate        = e.EventTime
            }
            );
        }
コード例 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Publish(object sender, Schedule.ScheduledEventArgs e)
        {
            logger.Debug("START Publish");
            string disabled = System.Configuration.ConfigurationManager.AppSettings["PUBLISHER_DISABLED"].ToString().ToLower();

            if (!string.IsNullOrEmpty(disabled))
            {
                bool disa = false;
                Boolean.TryParse(disabled, out disa);
                if (disa)
                {
                    logger.Debug("Publisher disabled [PUBLISHER_DISABLED] key is set to true, to enable it, remove key or set to false");
                    return;
                }
            }

            // Esecuzione di ogni singolo task schedulato
            ChannelRefInfo channel = (ChannelRefInfo)sender;

            // Reperimento dati dell'istanza
            channel = DataAccess.PublisherDataAdapter.GetChannel(channel.Id);

            // Aggiornamento stato istanza
            RefreshChannelState(channel);
            logger.DebugFormat("Canale {0}  stato {1}", channel.ChannelName, channel.State.ToString());
            if (channel.State == ChannelStateEnum.Started)
            {
                Mutex mutex = null;

                try
                {
                    logger.Debug("chiamo CreateMutex");
                    // Creazione o reperimento del mutex
                    mutex = CreateMutex(channel);
                    logger.DebugFormat("Mutex Chiamato");
                    if (mutex.WaitOne())
                    {
                        logger.Debug("Pubblicazione Canale");
                        // Pubblicazione istanza
                        IInstancePublisher publisher = new VtDocs.InstancePublisher();
                        publisher.Publish(channel);
                        logger.Debug("Canale Pubblicato");
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (mutex != null)
                    {
                        mutex.ReleaseMutex();
                        mutex.Close();
                        mutex = null;
                        logger.Debug("Mutex Rimosso");
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Verifica se il canale di pubblicazione risulta avviato o meno su un server remoto
        /// </summary>
        /// <param name="channelRef"></param>
        /// <returns></returns>
        private static bool IsChannelStartedOnRemoteMachine(ChannelRefInfo channelRef)
        {
            bool onRemote = false;

            if (channelRef.State == ChannelStateEnum.Started)
            {
                // Il canale è sicuramente avviato;
                // verifica se risulta avviato sul computer corrente o su un computer remoto
                onRemote = (string.Compare(channelRef.MachineName, ApplicationContext.GetMachineName(), true) != 0);
            }

            return(onRemote);
        }
コード例 #4
0
        /// <summary>
        /// Reperimento stato del canale di pubblicazione
        /// </summary>
        /// <param name="channelRef"></param>
        /// <returns></returns>
        public static ChannelStateEnum GetChannelState(ChannelRefInfo channelRef)
        {
            try
            {
                // Aggiorna lo stato del canale
                RefreshChannelState(channelRef);

                return(channelRef.State);
            }
            catch (Exception ex)
            {
                throw new PublisherException(ErrorCodes.UNHANDLED_ERROR, ex.Message);
            }
        }
コード例 #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="channelRef"></param>
        private static void StopTimer(ChannelRefInfo channelRef)
        {
            if (_dictionary.ContainsKey(channelRef.GetKey()))
            {
                StartedChannelTimer timer = _dictionary[channelRef.GetKey()];

                if (timer != null)
                {
                    timer.Timer.ClearJobs();
                    timer.Timer.Stop();
                    timer.Timer.Dispose();

                    lock (_dictionary)
                        _dictionary.Remove(channelRef.GetKey());
                }
            }
        }
コード例 #6
0
 /// <summary>
 /// Avvio del canale di pubblicazione su un server remoto
 /// </summary>
 /// <param name="channelRef"></param>
 /// <param name="publisherServiceUrl"></param>
 private static void StartRemoteChannel(ChannelRefInfo channelRef, string publisherServiceUrl)
 {
     try
     {
         using (Publisher.Proxy.PublisherWebService realWs = CreatePublisherInstance(publisherServiceUrl))
         {
             realWs.StartChannelById(channelRef.Id);
         }
     }
     catch (PublisherException pubEx)
     {
         throw pubEx;
     }
     catch (Exception ex)
     {
         throw new PublisherException(ErrorCodes.START_CHANNEL_ON_REMOTE_SERVER_ERROR,
                                      string.Format(ErrorDescriptions.START_CHANNEL_ON_REMOTE_SERVER_ERROR, ex.ToString()));
     }
 }
コード例 #7
0
        /// <summary>
        /// Riavvia l'esecuzione di un canale di pubblicazione
        /// </summary>
        /// <param name="channelRef">Dati del canale di pubblicazione</param>
        /// <remarks>
        /// Il canale sarà riavviato sullo stesso server
        /// </remarks>
        public static void ReStartChannel(ChannelRefInfo channelRef)
        {
            // Verifica se il canale di pubblicazione risulta avviato su un server remoto
            if (!IsChannelStartedOnRemoteMachine(channelRef))
            {
                try
                {
                    // Fermo del canale di pubblicazione
                    StopChannel(channelRef);
                }
                catch (PublisherException pubEx)
                {
                    logger.Error(pubEx.Message);
                    if (pubEx.ErrorCode != ErrorCodes.OPERATION_NOT_ALLOWED_PER_SERVICE_STOPPED)
                    {
                        throw pubEx;
                    }
                }

                // Il canale è avviato su un computer locale
                try
                {
                    // Avvio locale del canale
                    StartChannel(channelRef);
                }
                catch (PublisherException pubEx)
                {
                    logger.Error(pubEx.Message);

                    if (pubEx.ErrorCode != ErrorCodes.OPERATION_NOT_ALLOWED_PER_SERVICE_STARTED)
                    {
                        throw pubEx;
                    }
                }
            }
            else
            {
                // Il canale è avviato su un computer remoto, non fa nulla
                logger.Info("Canale su una macchina remota");
            }
        }
コード例 #8
0
        private static Mutex CreateMutex(ChannelRefInfo instance)
        {
            bool createdNew;

            string mutexName = string.Format("PublisherM-{0}-{1}", instance.Admin.Id.ToString(), instance.Id.ToString());

            logger.DebugFormat("GetOrCreateMutex Name {0}", mutexName);
            Mutex m = new Mutex(false, mutexName, out createdNew);

            if (createdNew)
            {
                // the mutex was created and this thread is the owner
                // (we don't need to call WaitOne)
            }
            else
            {
                m.WaitOne();
                logger.DebugFormat("Mutex {0} Devo aspettare un processo che termini in waitone", mutexName);
                // the mutex already exists, we hold a reference to the mutex, but we
                // don't own it (we need to call WaitOne).
            }
            return(m);
        }
コード例 #9
0
        /// <summary>
        /// Avvia l'esecuzione di un canale di pubblicazione
        /// </summary>
        /// <param name="channelRef"></param>
        public static void StartChannel(ChannelRefInfo channelRef)
        {
            // Aggiornamento stato del canale
            RefreshChannelState(channelRef);

            if (channelRef.State == ChannelStateEnum.Stopped)
            {
                using (DocsPaDB.TransactionContext tx = new DocsPaDB.TransactionContext())
                {
                    // Impostazione dello stato di avvio del servizio
                    channelRef = DataAccess.PublisherDataAdapter.StartService(channelRef);

                    // Avvio timer
                    StartTimer(channelRef);

                    tx.Complete();
                }
            }
            else
            {
                // L'istanza risulta già avviata
                throw new PublisherException(ErrorCodes.OPERATION_NOT_ALLOWED_PER_SERVICE_STARTED, ErrorDescriptions.OPERATION_NOT_ALLOWED_PER_SERVICE_STOPPED);
            }
        }
コード例 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="channelRef"></param>
        private static void StartTimer(ChannelRefInfo channelRef)
        {
            // Creazione timer
            Schedule.ScheduleTimer timer = new Schedule.ScheduleTimer();
            timer.Error += new Schedule.ExceptionEventHandler(OnScheduleError);


            if (channelRef.ExecutionConfiguration.IntervalType != JobExecutionConfigurations.IntervalTypesEnum.Block)
            {
                long ticks;
                long.TryParse(channelRef.ExecutionConfiguration.ExecutionTicks, out ticks);

                Schedule.ScheduledTime interval = new Schedule.ScheduledTime(
                    (Schedule.EventTimeBase)Enum.Parse(typeof(Schedule.EventTimeBase), channelRef.ExecutionConfiguration.IntervalType.ToString(), true),
                    TimeSpan.FromTicks(ticks));
                timer.AddJob(interval, new Schedule.ScheduledEventHandler(Publish), channelRef);
            }
            else
            {
                string[] spans           = channelRef.ExecutionConfiguration.ExecutionTicks.Split('|');
                string   strIntervalBase = string.Empty;
                string   strStartTime    = string.Empty;
                string   strStopTime     = string.Empty;
                if (spans.Length > 0)
                {
                    strIntervalBase = spans[0];
                }
                if (spans.Length > 1)
                {
                    strStartTime = spans[1];
                }
                if (spans.Length > 2)
                {
                    strStopTime = spans[2];
                }

                long intervalBase;
                long.TryParse(strIntervalBase, out intervalBase);

                long startTime;
                long.TryParse(strStartTime, out startTime);

                long stopTime;
                long.TryParse(strStopTime, out stopTime);

                Schedule.BlockWrapper interval = new Schedule.BlockWrapper(
                    new Schedule.SimpleInterval(DateTime.Parse("01/01/2000"), TimeSpan.FromTicks(intervalBase)),
                    "Daily",
                    new DateTime(startTime).ToString(),
                    new DateTime(stopTime).ToString());
                timer.AddJob(interval, new Schedule.ScheduledEventHandler(Publish), channelRef);
            }


            // Avvio timer
            timer.Start();

            // Creazione entry
            StartedChannelTimer entry = new StartedChannelTimer
            {
                Timer = timer,
                StartExecutionDate  = channelRef.StartExecutionDate,
                MachineName         = channelRef.MachineName,
                PublisherServiceUrl = channelRef.PublisherServiceUrl
            };

            lock (_dictionary)
                _dictionary.Add(channelRef.GetKey(), entry);
        }
コード例 #11
0
        /// <summary>
        /// Reperimento o creazione del Mutext per l'istanza corrente
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        private static Mutex GetOrCreateMutex(ChannelRefInfo instance)
        {
            string mutexName = string.Format("PublisherM-{0}-{1}", instance.Admin.Id.ToString(), instance.Id.ToString());

            logger.DebugFormat("GetOrCreateMutex Name {0}", mutexName);
            Mutex m            = null;
            bool  doesNotExist = false;
            bool  unauthorized = false;

            // The value of this variable is set by the mutex
            // constructor. It is true if the named system mutex was
            // created, and false if the named mutex already existed.
            //
            bool mutexWasCreated = false;

            // Attempt to open the named mutex.
            try
            {
                // Open the mutex with (MutexRights.Synchronize |
                // MutexRights.Modify), to enter and release the
                // named mutex.
                //
                m = Mutex.OpenExisting(mutexName);
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                logger.DebugFormat("Mutex does not exist.");
                doesNotExist = true;
            }
            catch (UnauthorizedAccessException ex)
            {
                logger.DebugFormat("Unauthorized access: {0}", ex.Message);
                unauthorized = true;
            }

            // There are three cases: (1) The mutex does not exist.
            // (2) The mutex exists, but the current user doesn't
            // have access. (3) The mutex exists and the user has
            // access.
            //
            if (doesNotExist)
            {
                // The mutex does not exist, so create it.

                // Create an access control list (ACL) that denies the
                // current user the right to enter or release the
                // mutex, but allows the right to read and change
                // security information for the mutex.
                //
                string        user = Environment.UserDomainName + "\\" + Environment.UserName;
                MutexSecurity mSec = new MutexSecurity();

                MutexAccessRule rule = new MutexAccessRule(user,
                                                           MutexRights.Synchronize | MutexRights.Modify,
                                                           AccessControlType.Deny);
                mSec.AddAccessRule(rule);

                rule = new MutexAccessRule(user,
                                           MutexRights.ReadPermissions | MutexRights.ChangePermissions,
                                           AccessControlType.Allow);
                mSec.AddAccessRule(rule);

                // Create a Mutex object that represents the system
                // mutex named by the constant 'mutexName', with
                // initial ownership for this thread, and with the
                // specified security access. The Boolean value that
                // indicates creation of the underlying system object
                // is placed in mutexWasCreated.
                //
                m = new Mutex(true, mutexName, out mutexWasCreated, mSec);

                // If the named system mutex was created, it can be
                // used by the current instance of this program, even
                // though the current user is denied access. The current
                // program owns the mutex. Otherwise, exit the program.
                //
                if (mutexWasCreated)
                {
                    logger.DebugFormat("Created the mutex.");
                }
                else
                {
                    logger.DebugFormat("Unable to create the mutex.");
                    throw new ApplicationException("Unable to create the mutex.");
                }
            }
            else if (unauthorized)
            {
                // Open the mutex to read and change the access control
                // security. The access control security defined above
                // allows the current user to do this.
                //
                try
                {
                    m = Mutex.OpenExisting(mutexName,
                                           MutexRights.ReadPermissions | MutexRights.ChangePermissions);

                    // Get the current ACL. This requires
                    // MutexRights.ReadPermissions.
                    MutexSecurity mSec = m.GetAccessControl();

                    string user = Environment.UserDomainName + "\\"
                                  + Environment.UserName;

                    // First, the rule that denied the current user
                    // the right to enter and release the mutex must
                    // be removed.
                    MutexAccessRule rule = new MutexAccessRule(user,
                                                               MutexRights.Synchronize | MutexRights.Modify,
                                                               AccessControlType.Deny);
                    mSec.RemoveAccessRule(rule);

                    // Now grant the user the correct rights.
                    //
                    rule = new MutexAccessRule(user,
                                               MutexRights.Synchronize | MutexRights.Modify,
                                               AccessControlType.Allow);
                    mSec.AddAccessRule(rule);

                    // Update the ACL. This requires
                    // MutexRights.ChangePermissions.
                    m.SetAccessControl(mSec);

                    logger.DebugFormat("Updated mutex security.");

                    // Open the mutex with (MutexRights.Synchronize
                    // | MutexRights.Modify), the rights required to
                    // enter and release the mutex.
                    //
                    m = Mutex.OpenExisting(mutexName);
                }
                catch (UnauthorizedAccessException ex)
                {
                    logger.DebugFormat("Unable to change permissions: {0}", ex.Message);
                    throw new ApplicationException(string.Format("Unable to change permissions: {0}", ex.Message));
                }
            }

            return(m);
        }
コード例 #12
0
        /// <summary>
        /// Aggiornamento stato del canale di pubblicazione
        /// </summary>
        /// <param name="channelRef"></param>
        public static void RefreshChannelState(ChannelRefInfo channelRef)
        {
            //DocsPaUtils.LogsManagement.Debugger.Write("RefreshChannelState - BEGIN");

            try
            {
                if (IsChannelStartedOnRemoteMachine(channelRef))
                {
                    //DocsPaUtils.LogsManagement.Debugger.Write("RefreshChannelState - remote");

                    // Il canale di pubblicazione risulta avviato su un server remoto

                    // Creazione istanza del servizio di pubblicazione remoto
                    using (Publisher.Proxy.PublisherWebService realWs = CreatePublisherInstance(channelRef.PublisherServiceUrl))
                    {
                        Publisher.Proxy.ChannelRefInfo remoteChannel = null;

                        try
                        {
                            // Reperimento dei metadati del canale di pubblicazione
                            remoteChannel = realWs.GetChannel(channelRef.Id);
                        }
                        catch (PublisherException pubEx)
                        {
                            //DocsPaUtils.LogsManagement.Debugger.Write(pubEx);

                            throw pubEx;
                        }
                        catch (Exception ex)
                        {
                            //DocsPaUtils.LogsManagement.Debugger.Write(ex);

                            // Si è verificato un errore nell'esecuzione del servizio di pubblicazione remoto
                            remoteChannel = null;

                            channelRef.State = ChannelStateEnum.UnexpectedStopped;
                        }

                        if (remoteChannel != null)
                        {
                            // Aggiornamento dello stato del canale di pubblicazione
                            if (remoteChannel.State == Proxy.ChannelStateEnum.Started)
                            {
                                channelRef.State = ChannelStateEnum.Started;
                            }
                            else if (remoteChannel.State == Proxy.ChannelStateEnum.Stopped)
                            {
                                channelRef.State = ChannelStateEnum.Stopped;
                            }
                            else if (remoteChannel.State == Proxy.ChannelStateEnum.UnexpectedStopped)
                            {
                                channelRef.State = ChannelStateEnum.UnexpectedStopped;
                            }

                            channelRef.StartExecutionDate  = remoteChannel.StartExecutionDate;
                            channelRef.EndExecutionDate    = remoteChannel.EndExecutionDate;
                            channelRef.MachineName         = remoteChannel.MachineName;
                            channelRef.PublisherServiceUrl = remoteChannel.PublisherServiceUrl;
                        }
                    }
                }
                else
                {
                    StartedChannelTimer timer = GetTimer(channelRef.GetKey());

                    if (timer == null)
                    {
                        if (channelRef.State == ChannelStateEnum.Started &&
                            channelRef.MachineName == ApplicationContext.GetMachineName())
                        {
                            // Se il servizio risulta avviato nella base dati
                            // ma non risulta essere presente nella memoria del server,
                            // significa che è stato fermato in modo non previsto
                            // (es. il server è giù). Pertanto lo stato del servizio viene
                            // impostato a "UnexpectedStopped".
                            channelRef.State = ChannelStateEnum.UnexpectedStopped;
                        }
                    }
                    else
                    {
                        // Il timer è presente: aggiornamento dello stato del canale
                        channelRef.State = ChannelStateEnum.Started;
                        channelRef.StartExecutionDate  = timer.StartExecutionDate;
                        channelRef.EndExecutionDate    = DateTime.MinValue;
                        channelRef.MachineName         = timer.MachineName;
                        channelRef.PublisherServiceUrl = timer.PublisherServiceUrl;
                    }
                }
            }
            catch (Exception ex)
            {
                //DocsPaUtils.LogsManagement.Debugger.Write(ex);
                logger.Error(ex);
                throw new PublisherException(ErrorCodes.UNHANDLED_ERROR, ex.Message);
            }

            //DocsPaUtils.LogsManagement.Debugger.Write("RefreshChannelState - END");
        }
コード例 #13
0
        /// <summary>
        /// Sospende l'esecuzione di un canale di pubblicazione
        /// </summary>
        /// <param name="channelRef"></param>
        public static void StopChannel(ChannelRefInfo channelRef)
        {
            //DocsPaUtils.LogsManagement.Debugger.Write("StopChannel - INIT");

            // Aggiornamento stato del canale
            RefreshChannelState(channelRef);

            if (channelRef.State == ChannelStateEnum.Started ||
                channelRef.State == ChannelStateEnum.UnexpectedStopped)
            {
                // Il canale di pubblicazione risulta avviato su un server diverso da quello attuale
                if (string.Compare(channelRef.MachineName, ApplicationContext.GetMachineName(), false) != 0)
                {
                    // Si sta tentando di fermare un canale di pubblicazione avviato da un altro computer.
                    // Viene richiamato il servizio di pubblicazione da cui è stato avviato per fermarne correttamente lo stato.
                    using (Publisher.Proxy.PublisherWebService realWs = CreatePublisherInstance(channelRef.PublisherServiceUrl))
                    {
                        try
                        {
                            // Fermo del canale nel server di pubblicazione in cui risulta avviato
                            realWs.StopChannelById(channelRef.Id);
                        }
                        catch (PublisherException pubEx)
                        {
                            throw pubEx;
                        }
                        catch (Exception ex)
                        {
                            //DocsPaUtils.LogsManagement.Debugger.Write(ex);

                            // Si è verificato un errore, il server remoto di pubblicazione non risulta raggiungibile,
                            // pertanto viene forzato lo stato di fermo del servizio sul database
                            using (DocsPaDB.TransactionContext tx = new DocsPaDB.TransactionContext())
                            {
                                channelRef = DataAccess.PublisherDataAdapter.StopService(channelRef);

                                tx.Complete();
                            }

                            //throw new PublisherException(ErrorCodes.STOP_CHANNEL_ON_REMOTE_SERVER_ERROR,
                            //                            string.Format(ErrorDescriptions.STOP_CHANNEL_ON_REMOTE_SERVER_ERROR, ex.ToString()));
                        }
                    }
                }
                else
                {
                    using (DocsPaDB.TransactionContext tx = new DocsPaDB.TransactionContext())
                    {
                        // Impostazione dello stato di fermo del servizio
                        channelRef = DataAccess.PublisherDataAdapter.StopService(channelRef);

                        StopTimer(channelRef);

                        tx.Complete();
                    }
                }
            }
            else
            {
                // L'istanza risulta già fermata
                throw new PublisherException(ErrorCodes.OPERATION_NOT_ALLOWED_PER_SERVICE_STOPPED, ErrorDescriptions.OPERATION_NOT_ALLOWED_PER_SERVICE_STARTED);
            }

            //DocsPaUtils.LogsManagement.Debugger.Write("StopChannel - END");
        }