Esempio n. 1
0
    /// <summary>
    /// Initializes the <see cref="EngineCore"/>.
    /// </summary>
    /// <param name="processSynchronizer">
    /// The <see cref="IProcessSynchronizer"/> to use for communication with the host.
    /// </param>
    public static void Initialize(IProcessSynchronizer processSynchronizer)
    {
      lock (_syncRoot)
      {
        if (_initialized) return;
        // Initialize variables.
        _currentProcessId = RemoteHooking.GetCurrentProcessId();
        _serverReporter = processSynchronizer;
        _logBus = new LogBus(processSynchronizer);
#if !SYNCLOG
        _logBus.Enabled = true;
#endif
        _engine = VirtualizationEngine.InitializeEngine(processSynchronizer);
        // Attach ProcessExit event handler.
        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
        // Mark instance as initialized.
        _initialized = true;
        Log.Message("Successfully initialized core components.");
      }
    }
Esempio n. 2
0
 /// <summary>
 /// Updates the items.
 /// </summary>
 /// <param name="job">The job.</param>
 /// <param name="itemsToSynchronize">The items to synchronize.</param>
 /// <param name="fieldUpdaters">The field updaters.</param>
 /// <param name="dynamicItem">The dynamic item.</param>
 /// <param name="context">The context.</param>
 /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
 private bool UpdateItems(
     IProcessSynchronizer job,
     IEnumerable<int> itemsToSynchronize,
     IEnumerable<IFieldUpdater> fieldUpdaters,
     ISyncDynamicItem dynamicItem,
     SynchronizationContext context)
 {
     return itemsToSynchronize.Aggregate(true, (current, id) => current && ExecuteUpdate(job, id, fieldUpdaters, dynamicItem, context));
 }
Esempio n. 3
0
        /// <summary>
        /// Executes the update.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <param name="itemId">The item identifier.</param>
        /// <param name="fieldUpdaters">The field updaters.</param>
        /// <param name="dynamicItem">The dynamic item.</param>
        /// <param name="context">The context.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool ExecuteUpdate(
            IProcessSynchronizer job,
            int itemId,
            IEnumerable<IFieldUpdater> fieldUpdaters,
            ISyncDynamicItem dynamicItem,
            SynchronizationContext context)
        {
            try
            {
                var criteria = new DetailCriteria(itemId) { AllowLazyLoading = true };
                var editItem = DynamicTypeManager.GetEditableRoot<IEditableRoot>(job.ProcessName, criteria);

                if (editItem == null || editItem.Id != itemId)
                {
                    context.AddError(string.Format(CultureInfo.InvariantCulture, "Failed to load item with Id = {0}.", itemId));
                    return false;
                }

                foreach (var fieldUpdater in fieldUpdaters)
                {
                    fieldUpdater.Update(dynamicItem, editItem);

                    if (fieldUpdater.IsKey)
                    {
                        editItem.KeyFields.Add(fieldUpdater.FieldName);
                    }
                }

                if (!((ITrackStatus)editItem).IsValid)
                {
                    AddValidationErrors(editItem, context);
                    return false;
                }

                ((ISavable)editItem).Save();

                return true;
            }
            catch (Exception ex)
            {
                context.AddException(ex);
            }

            return false;
        }
Esempio n. 4
0
        /// <summary>
        /// Synchronizes the specified job.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <param name="filterBuilders">The filter builders.</param>
        /// <param name="fieldUpdaters">The field updaters.</param>
        /// <param name="item">The item.</param>
        /// <param name="context">The context.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        /// <exception cref="System.ArgumentException">At least one key field should be specified.</exception>
        /// <exception cref="System.NotSupportedException"></exception>
        private bool Synchronize(
            IProcessSynchronizer job,
            IList<IFieldFilterBuilder> filterBuilders,
            IList<IFieldUpdater> fieldUpdaters,
            ProviderItem item,
            SynchronizationContext context)
        {
            if (filterBuilders.Count == 0)
                throw new ArgumentException("At least one key field should be specified.");

            var failedAttempts = 0;
            Random random = null;

            while (true)
            {
                try
                {
                    using (var transactionScope = TransactionUtils.CreateTransactionScope())
                    {
                        var dynamicItem = job.CreateDynamicItem(item);
                        var filterList = filterBuilders.Select(filterBuilder => filterBuilder.GetFilter(dynamicItem)).ToList();
                        var itemsToSynchronize = RuntimeDatabase.FindItems(job.ProcessName, filterList);
                        bool isSuccessful;

                        switch (job.Action)
                        {
                            case ESyncAction.Insert:
                                isSuccessful = itemsToSynchronize.Count > 0 || ExecuteInsert(job, fieldUpdaters, dynamicItem, context);
                                break;

                            case ESyncAction.Update:
                                isSuccessful = UpdateItems(job, itemsToSynchronize, fieldUpdaters, dynamicItem, context);
                                break;

                            case ESyncAction.InsertOrUpdate:
                                isSuccessful = itemsToSynchronize.Count > 0
                                                   ? UpdateItems(job, itemsToSynchronize, fieldUpdaters, dynamicItem, context)
                                                   : ExecuteInsert(job, fieldUpdaters, dynamicItem, context);
                                break;

                            default:
                                throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Action \"{0}\" is not supported.", job.Action));
                        }

                        if (isSuccessful)
                            transactionScope.Complete();

                        return isSuccessful;
                    }
                }
                catch (Exception ex)
                {
                    ++failedAttempts;

                    if (failedAttempts < MaximumAttempts && CanRetry(ex))
                    {
                        Logger.Log(LogSeverity.Error, "eSync", ex);
                        Logger.Log(LogSeverity.Warning, "eSync", "A recoverable error occurred. The transaction will be rerun.");

                        if (random == null)
                        {
                            random = new Random(Thread.CurrentThread.ManagedThreadId);
                        }

                        var delay = MinimumRetryDelay + TimeSpan.FromSeconds((MaximumRetryDelay - MinimumRetryDelay).TotalSeconds * random.NextDouble());

                        Thread.Sleep(delay);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Executes the insert.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <param name="fieldUpdaters">The field updaters.</param>
        /// <param name="dynamicItem">The dynamic item.</param>
        /// <param name="context">The context.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        private bool ExecuteInsert(
            IProcessSynchronizer job, IEnumerable<IFieldUpdater> fieldUpdaters, ISyncDynamicItem dynamicItem, SynchronizationContext context)
        {
            try
            {
                var editItem = DynamicTypeManager.NewEditableRoot<IEditableRoot>(job.ProcessName);
                editItem.AllowLazyLoading = true;

                foreach (var fieldUpdater in fieldUpdaters)
                {
                    fieldUpdater.Update(dynamicItem, editItem);

                    if (fieldUpdater.IsKey)
                    {
                        editItem.KeyFields.Add(fieldUpdater.FieldName);
                    }
                }

                if (!((ITrackStatus)editItem).IsValid)
                {
                    AddValidationErrors(editItem, context);
                    return false;
                }

                ((ISavable)editItem).Save();

                return true;
            }
            catch (Exception ex)
            {
                context.AddException(ex);
            }

            return false;
        }
Esempio n. 6
0
        /// <summary>
        /// Creates the key filter builders.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <returns>List{IFieldFilterBuilder}.</returns>
        /// <exception cref="Cebos.Veyron.SharedTypes.VeyronException">Invalid mapping</exception>
        private List<IFieldFilterBuilder> CreateKeyFilterBuilders(IProcessSynchronizer job)
        {
            var filterBuilders = new List<IFieldFilterBuilder>();

            try
            {
                foreach (var field in job.SynchronizationMap.SynchronizedFields.Where(f => f.IsKey))
                {
                    var builder = FilterBuilderFactory.CreateFilterBuilder(job.ProcessName, field, job.ValueCalculator);
                    filterBuilders.Add(builder);
                }
            }
            catch (Exception ex)
            {
                throw new VeyronException("Invalid mapping", ex);
            }

            return filterBuilders;
        }
Esempio n. 7
0
        /// <summary>
        /// Creates the field updaters.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <returns>List{IFieldUpdater}.</returns>
        /// <exception cref="Cebos.Veyron.SharedTypes.VeyronException">Invalid mapping</exception>
        private List<IFieldUpdater> CreateFieldUpdaters(IProcessSynchronizer job)
        {
            var fieldUpdaters = new List<IFieldUpdater>();

            try
            {
                fieldUpdaters.AddRange(
                    job.SynchronizationMap.SynchronizedFields.Select(
                        synchronizedField => FieldUpdaterFactory.CreateFieldUpdater(job.ProcessName, synchronizedField, job.ValueCalculator)));
            }
            catch (Exception ex)
            {
                throw new VeyronException("Invalid mapping", ex);
            }

            return fieldUpdaters;
        }
 /// <summary>
 /// Initializes a new instance of <see cref="ConnectionManager"/>.
 /// Before the underlying IPC-channel can be used, <see cref="Connect"/> must be called.
 /// </summary>
 /// <param name="processSynchronizer">The object responsible for the synchronization between the server process and the virtualized process.</param>
 public ConnectionManager(IProcessSynchronizer processSynchronizer)
 {
   _syncRoot = new object();
   _processSynchronizer = processSynchronizer;
 }
Esempio n. 9
0
        /// <summary>
        /// Gets the last successful session.
        /// </summary>
        /// <param name="synchronizer">The synchronizer.</param>
        /// <returns>IESyncSessionInfo.</returns>
        private IESyncSessionInfo GetLastSuccessfulSession(IProcessSynchronizer synchronizer)
        {
            try
            {
                var filterList = new FilterList
                                     {
                                         new FilterDescriptor("SynchronizedProcessName", FilterOperator.IsEqualTo, synchronizer.ProcessName),
                                         new FilterDescriptor(Constants.ESyncSessionSyncProcessGuidColumnName, FilterOperator.IsEqualTo, synchronizer.Guid.ToString()),
                                         new FilterDescriptor(Constants.ESyncSessionIsSuccessfulColumnName, FilterOperator.IsEqualTo, 1),
                                     };

                var sortList = new SortList
                               {
                                   new SortDescriptor(Constants.ESyncSessionEndTimeColumnName, SortDirection.Descending)
                               };

                var list = DynamicTypeManager.GetList<IInfoList>(Constants.ESyncSessionProcessName, string.Empty, 0, 1, sortList, filterList);

                if (list != null && list.Count > 0)
                    return list.Cast<IESyncSessionInfo>().First();
            }
            catch (Exception ex)
            {
                Logger.Log(LogSeverity.Error, "ESYNC", ex);
            }

            return null;
        }
    /// <summary>
    /// Initializes a new instance of <see cref="PackagingProcess"/>.
    /// </summary>
    /// <param name="startInfo">
    /// The <see cref="VirtualProcessStartInfo"/> containing the information used to start the process with.
    /// </param>
    /// <param name="synchronizer">
    /// The <see cref="ProcessSynchronizer"/> to use for data synchronization with the <see cref="VirtualizedProcess"/>.
    /// </param>
    private PackagingProcess(VirtualProcessStartInfo startInfo, IProcessSynchronizer synchronizer)
      : base(startInfo, synchronizer)
    {

    }
Esempio n. 11
0
 /// <summary>
 /// Gets the name of the job.
 /// </summary>
 /// <param name="synchronizer">The synchronizer.</param>
 /// <returns>System.String.</returns>
 private static string GetJobName(IProcessSynchronizer synchronizer)
 {
     return GetJobName(synchronizer.Guid);
 }
Esempio n. 12
0
        /// <summary>
        /// Gets the job detail.
        /// </summary>
        /// <param name="synchronizer">The synchronizer.</param>
        /// <returns>JobDetail.</returns>
        private JobDetail GetJobDetail(IProcessSynchronizer synchronizer)
        {
            var jobName = GetJobName(synchronizer);
            var jobDetail = Scheduler.GetJobDetail(jobName, QuartzGroupName);

            if (jobDetail != null && jobDetail.JobType != typeof(SyncProcessWorker))
            {
                Scheduler.DeleteJob(jobName, QuartzGroupName);
                jobDetail = null;
            }

            if (jobDetail != null)
                return jobDetail;

            jobDetail = new JobDetail(jobName, QuartzGroupName, typeof(SyncProcessWorker), false, true, false);

            jobDetail.JobDataMap["processName"] = synchronizer.ProcessName;
            jobDetail.JobDataMap["syncProcessGuid"] = synchronizer.Guid;

            Scheduler.AddJob(jobDetail, true);

            return jobDetail;
        }
Esempio n. 13
0
        /// <summary>
        /// Updates the job.
        /// </summary>
        /// <param name="synchronizer">The synchronizer.</param>
        public void UpdateJob(IProcessSynchronizer synchronizer)
        {
            CheckInitialized();

            var jobDetail = GetJobDetail(synchronizer);
            var triggers = Scheduler.GetTriggersOfJob(jobDetail.Name, QuartzGroupName);

            // Remove obsolete triggers.
            foreach (var trigger in triggers)
            {
                var esyncTrigger = trigger as ESyncTrigger;

                if (esyncTrigger == null)
                {
                    Scheduler.UnscheduleJob(trigger.Name, QuartzGroupName);
                    continue;
                }

                if (synchronizer == null)
                    continue;

                var schedule = synchronizer.Schedules.FirstOrDefault(s => GetTriggerName(s) == esyncTrigger.Name);

                // If schedule was deleted, is inactive or changed, delete existing trigger.
                if (schedule == null || !schedule.IsActive || !schedule.Equals(esyncTrigger.Schedule))
                    Scheduler.UnscheduleJob(trigger.Name, QuartzGroupName);
            }

            triggers = Scheduler.GetTriggersOfJob(jobDetail.Name, QuartzGroupName);

            // Schedule job with new triggers.
            if (synchronizer == null)
                return;

            foreach (var schedule in synchronizer.Schedules.Where(s => s.IsActive))
            {
                try
                {
                    // Find existing trigger.
                    var trigger = triggers.FirstOrDefault(t => t.Name == GetTriggerName(schedule));

                    if (trigger != null)
                        continue;

                    trigger = GetTrigger(schedule, jobDetail);

                    if (trigger == null)
                        continue;

                    var calendar = (ICalendar)null;

                    if (trigger.CalendarName != null)
                        calendar = Scheduler.GetCalendar(trigger.CalendarName);

                    var firstFireTime = trigger.ComputeFirstFireTimeUtc(calendar);

                    if (!firstFireTime.HasValue)
                        continue;

                    Scheduler.ScheduleJob(trigger);
                }
                catch (Exception ex)
                {
                    Logger.Log(LogSeverity.Error, GetType().ToString(), ex);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of <see cref="VirtualizedProcess"/>,
 /// using the <see cref="ProcessSynchronizer"/> specified.
 /// </summary>
 /// <param name="startInfo">
 /// The <see cref="VirtualProcessStartInfo"/> containing the information used to start the process with.
 /// </param>
 /// <param name="processSynchronizer">
 /// The <see cref="IProcessSynchronizer"/> to use for data synchronization with the <see cref="VirtualizedProcess"/>.
 /// </param>
 protected VirtualizedProcess(VirtualProcessStartInfo startInfo, IProcessSynchronizer processSynchronizer)
 {
   _exitEventSyncRoot = new object();
   _startInfo = startInfo;
   _connection = new ConnectionManager(processSynchronizer);
   _gacManager = new GacManager(startInfo.Files.Executable.FileName,
                                HostCore.Configuration.Application.LibsToShare);
 }