/// <summary>
        /// Returns the free busy times for the specified exchange users
        /// </summary>
        /// <param name="users">The user which free/busy blocks will be looked up for</param>
        /// <param name="window">The time period to look up FB info for</param>
        /// <returns></returns>
        public Dictionary <ExchangeUser, FreeBusy> LookupFreeBusyTimes(
            ExchangeUserDict users,
            DateTimeRange window)
        {
            /* Create an array of mailboxes to retrieve from exchange */
            Dictionary <ExchangeUser, FreeBusy> result = new Dictionary <ExchangeUser, FreeBusy>();

            try
            {
                using (BlockTimer bt = new BlockTimer("LookupFreeBusyTimes"))
                {
                    /* Perform the retrieval of free busy times through WebDav */
                    result = webDavQuery.LoadFreeBusy(exchangeServerUrl, users, window);
                }
            }
            catch (Exception ex)
            {
                throw new GCalExchangeException(
                          GCalExchangeErrorCode.ExchangeUnreachable,
                          "Error occured while retrieving free busy ranges",
                          ex);
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Load a set of appointments from the server
        /// </summary>
        /// <param name="folderUrl">The mailbox URL</param>
        /// <param name="start">Start time of date range to fetch</param>
        /// <param name="end">End time of date range to fetch</param>
        /// <returns>A list of appointments from the mailbox</returns>
        public virtual List <Appointment> LoadAppointments(
            string folderUrl, DateTime start, DateTime end)
        {
            using (BlockTimer bt = new BlockTimer("LoadAppointments"))
            {
                string request = WebDavXmlResources.GetText(
                    WebDavXmlResources.FindAppointments,
                    folderUrl,
                    DateUtil.FormatDateForDASL(start),
                    DateUtil.FormatDateForDASL(end));

                string      response    = IssueRequestAndFetchReponse(folderUrl, Method.SEARCH, request);
                XmlDocument responseXML = ParseExchangeXml(response);
                return(ParseAppointmentResultSetXml(responseXML));
            }
        }
示例#3
0
        private EventFeed QueryGCal(FeedQuery query, string userName, DateTime modifiedSince)
        {
            if (log.IsInfoEnabled)
            {
                log.Info(String.Format("Querying GCal for User '{0}': {1}", userName, query.Uri));
            }

            EventFeed feed = null;

            // Wait as necessary before making new request.

            connectionThrottler.WaitBeforeNewConnection();

            try
            {
                using (BlockTimer bt = new BlockTimer("QueryGCal"))
                {
                    feed = service.Query(query, modifiedSince) as EventFeed;
                }
            }
            catch (GDataNotModifiedException e)
            {
                // Content was not modified
                log.InfoFormat("NotModified: {0}", e.Message);
            }
            catch (Exception)
            {
                // Report a failure, regardless of the exception, as long as it is not GDataNotModifiedException.
                // This could be a bit overly aggressive, but it is hard to make bets
                // what exception was caught and rethrown in GData and what was let to fly.
                connectionThrottler.ReportFailure();

                throw;
            }

            // Everything went well, report it.
            // Note this is valid even when we caught GDataNotModifiedException.
            connectionThrottler.ReportSuccess();

            LogResponse(feed, userName);

            return(feed);
        }
示例#4
0
        /// <summary>
        /// Perform sync of users from Google Calendar to Exchnage until there are no more
        /// users to sync. This can be called from a worker thread.
        /// </summary>
        public void SyncUsers()
        {
            ExchangeUser user;
            int          userCount = 0;
            string       login     = string.Empty;

            errorThreshold = ConfigCache.ServiceErrorCountThreshold;
            errorCount     = 0;

            while (exchangeUsers.Count > 0)
            {
                lock ( lockObject )
                {
                    if (exchangeUsers.Count == 0)
                    {
                        break;
                    }
                    else
                    {
                        user = exchangeUsers[0];
                        exchangeUsers.RemoveAt(0);
                    }
                }

                try
                {
                    userCount++;

                    login = user.Email.ToLower();

                    DateTime modifiedDate = modifiedDateUtil.GetModifiedDateForUser(login);
                    DateTime currentDate  = DateUtil.NowUtc;

                    // Pick a window to synchronize for:
                    //
                    // [-N, +2N] days where N is settable in the config file
                    //
                    // Scanning back in time is necessary so that we pickup changes to meetings and events that were
                    // made invisible.
                    //
                    // TODO: The window we're syncing for should also be used when we modify events in Exchange
                    // so we only modify events in the window.

                    DateTime      start      = currentDate.AddDays(-ConfigCache.GCalSyncWindow);
                    DateTime      end        = currentDate.AddDays(2 * ConfigCache.GCalSyncWindow);
                    DateTimeRange syncWindow = new DateTimeRange(start, end);

                    log.InfoFormat("Processing user {0} for {1}", login, syncWindow);

                    EventFeed feed = gcalGateway.QueryGCal(
                        user.Email,
                        GCalVisibility.Private,
                        ConfigCache.FreeBusyDetailLevel,
                        modifiedDate,
                        syncWindow);

                    // if feed is null, then that means no calendar items changed for the user since we last queried.
                    if (feed == null)
                    {
                        log.DebugFormat(
                            "Calendar has not changed for user {0}.  User will not be synced this round.",
                            login);

                        continue;
                    }

                    if (!ValidateFeed(feed))
                    {
                        /* No Google App Feed was returned,  skip to next user */
                        log.WarnFormat(
                            "GCal feed could not be read for '{0}'.  This user may not have activated their account or may be inactive." +
                            "For resources the admin must share their calendars for the domain and set correctly the timezone.",
                            login);

                        continue;
                    }

                    log.InfoFormat("Calendar Query returned {0} events", feed.Entries.Count);

                    using (BlockTimer freeBusyTimer = new BlockTimer("WriteFreeBusy"))
                    {
                        /* User and feed retrieval was succesful, merge the two datasources down into Exchange */
                        freeBusyWriter.SyncUser(user, feed, exchangeGateway, syncWindow);
                    }

                    // Only update the modified time if we sync'd
                    modifiedDateUtil.UpdateUserModifiedTime(login, currentDate);
                }
                catch (Exception ex)
                {
                    Interlocked.Increment(ref errorCount);

                    log.Error(string.Format(
                                  "Error occured while executing sync process for user '{0}'. [running error count={1}]", login, errorCount),
                              ex);
                }

                if (errorCount > errorThreshold)
                {
                    throw new GCalExchangeException(
                              GCalExchangeErrorCode.GenericError,
                              "Error threshold has been surpassed, aborting sync process.");
                }
            }

            log.InfoFormat("User synchronization complete.  {0} users processed.", userCount);
        }
示例#5
0
        /// <summary>
        /// Run the sync process from Google Calendar to Exchange
        /// </summary>
        /// <param name="threadCount">Number of threads to use to sync</param>
        public void RunSyncProcess(int threadCount)
        {
            log.Info("Exchange synchronization process started.");

            using (BlockTimer bt = new BlockTimer("RunSyncProcess"))
            {
                gcalGateway =
                    new GCalGateway(googleAppsLogin, googleAppsPassword, googleAppsDomain, null);
                exchangeGateway =
                    new ExchangeService(exchangeServer, networkLogin, networkPassword);

                ExchangeUserDict users;

                using (BlockTimer loadUserTimer = new BlockTimer("LoadUserList"))
                {
                    users = QueryExchangeForValidUsers();
                }

                exchangeUsers = new List <ExchangeUser>();

                freeBusyWriter = FreeBusyWriterFactory.GetWriter(exchangeUsers);

                foreach (ExchangeUser user in users.Values)
                {
                    exchangeUsers.Add(user);
                }

                if (exchangeUsers.Count == 0)
                {
                    log.Warn("No eligible users found for synchronization.  Aborting sync process.");
                    return;
                }

                if (threadCount < 1)
                {
                    threadCount = 1;
                }

                modifiedDateUtil = new ModifiedDateUtil(ConfigCache.ServiceModifiedXmlFileName);
                modifiedDateUtil.LoadModifiedTimes();

                if (threadCount == 1)
                {
                    SyncUsers();
                }
                else
                {
                    StartSyncUserThreads(threadCount);
                }

                modifiedDateUtil.PersistModifiedTimes();

                gcalGateway      = null;
                exchangeGateway  = null;
                freeBusyWriter   = null;
                modifiedDateUtil = null;
                exchangeUsers    = null;

                System.GC.Collect();
                log.DebugFormat("Memory after sync: {0}", System.GC.GetTotalMemory(false));
            }
        }
        public static void test_reduce_profiling()
        {
            LocalProfiler p = new LocalProfiler();

            p.Start("load");
            //DMesh3 mesh = TestUtil.LoadTestMesh("c:\\scratch\\bunny_solid.obj");
            //DMesh3 mesh = TestUtil.LoadTestMesh("C:\\scratch\\current_test\\g3sharp_user_OBJ\\OBJ\\dizhi.obj");
            //DMesh3 mesh = TestUtil.LoadTestMesh("C:\\scratch\\current_test\\g3sharp_user_OBJ\\exported.obj");
            //DMesh3 mesh = TestUtil.LoadTestMesh("c:\\scratch\\bunny_open.obj");
            DMesh3 loadMesh = TestUtil.LoadTestMesh("c:\\scratch\\ZentrigDoo_Hires_Upper.stl");

            System.Console.WriteLine("Loaded...");

            p.StopAllAndStartNew("check");
            //mesh.CheckValidity();
            System.Console.WriteLine("Checked...");


            double time_ticks = 0;
            int    Niters     = 10;

            DMesh3 mesh = null;

            for (int k = 0; k < Niters; ++k)
            {
                mesh = new DMesh3(loadMesh);

                int N = 100000;
                System.Console.WriteLine("Reducing from {0} to {1}...", mesh.TriangleCount, N);
                BlockTimer reduceT = p.StopAllAndStartNew("reduce");
                Reducer    r       = new Reducer(mesh);
                //r.MinimizeQuadricPositionError = false;
                r.ENABLE_PROFILING = true;

                //DMeshAABBTree3 tree = new DMeshAABBTree3(new DMesh3(mesh));
                //tree.Build();
                //MeshProjectionTarget target = new MeshProjectionTarget(tree.Mesh, tree);
                //r.SetProjectionTarget(target);
                //r.ProjectionMode = Reducer.TargetProjectionMode.Inline;

                //r.SetExternalConstraints(new MeshConstraints());
                ////MeshConstraintUtil.PreserveBoundaryLoops(r.Constraints, mesh);
                //MeshConstraintUtil.FixAllBoundaryEdges(r.Constraints, mesh);

                r.ReduceToTriangleCount(N);
                //double min, max, avg;
                //MeshQueries.EdgeLengthStats(mesh, out min, out max, out avg);
                //r.ReduceToEdgeLength(avg * 1.5);
                //System.Console.WriteLine("Reduced...");

                p.Stop("reduce");
                time_ticks += reduceT.Watch.Elapsed.Ticks;
                System.Console.WriteLine(p.AllTimes());
                GC.Collect();
            }


            TimeSpan total = new TimeSpan((int)(time_ticks / (double)Niters));

            System.Console.WriteLine("AVERAGE: {0}", string.Format("{0:ss}.{0:ffffff}", total));

            TestUtil.WriteDebugMesh(mesh, "__REDUCED.obj");
        }
        /// <summary>
        /// Combines the free busy and appointment blocks supplied to the exchange user object
        /// If no appointments are supplied the user will still have free busy time blocks assigned
        /// to them, with a null appointment assigned to the free busy time.
        /// </summary>
        /// <param name="exchangeUser">Exchange users to apply freeBusy and appointments</param>
        /// <param name="freeBusy">The collection of FreeBusy blocks to assign to exchangeUser</param>
        /// <param name="appointments">The collection of appointment blocks to assign to exchangeUser</param>
        /// <param name="window">Window to merge for</param>
        protected void MergeFreeBusyWithAppointments(
            ExchangeUser exchangeUser,
            FreeBusy freeBusy,
            List <Appointment> appointments,
            DateTimeRange window)
        {
            using (BlockTimer bt = new BlockTimer("MergeFreeBusyWithAppointments"))
            {
                IntervalTree <FreeBusyTimeBlock> busyIntervals =
                    new IntervalTree <FreeBusyTimeBlock>();
                FreeBusyCollection busyTimes       = new FreeBusyCollection();
                int appointmentsCount              = 0;
                List <DateTimeRange> combinedTimes =
                    FreeBusyConverter.MergeFreeBusyLists(freeBusy.All, freeBusy.Tentative);

                /* Add the date ranges from each collection in the FreeBusy object */
                ConvertFreeBusyToBlocks(window,
                                        combinedTimes,
                                        busyTimes,
                                        busyIntervals);

                if (appointments != null && appointments.Count > 0)
                {
                    appointmentsCount = appointments.Count;
                    foreach (Appointment appt in appointments)
                    {
                        log.DebugFormat("Appt \"{0}\" {1} {2} response = {3} status = {4} busy = {5}",
                                        appt.Subject,
                                        appt.Range,
                                        appt.StartDate.Kind,
                                        appt.ResponseStatus,
                                        appt.MeetingStatus,
                                        appt.BusyStatus);

                        if (appt.BusyStatus == BusyStatus.Free)
                        {
                            continue;
                        }

                        DateTimeRange            range  = new DateTimeRange(appt.StartDate, appt.EndDate);
                        List <FreeBusyTimeBlock> result =
                            busyIntervals.FindAll(range, IntervalTreeMatch.Overlap);

                        log.DebugFormat("Found {0} ranges overlap {1}", result.Count, range);

                        foreach (FreeBusyTimeBlock block in result)
                        {
                            log.DebugFormat("Adding \"{0}\" to FB {1} {2}",
                                            appt.Subject,
                                            block.Range,
                                            block.StartDate.Kind);
                            block.Appointments.Add(appt);
                        }

                        busyTimes.Appointments.Add(appt);
                    }
                }

                foreach (FreeBusyTimeBlock block in busyTimes.Values)
                {
                    block.Appointments.Sort(CompareAppointmentsByRanges);
                }

                log.InfoFormat("Merge Result of {0} + Appointment {1} -> {2}",
                               combinedTimes.Count,
                               appointmentsCount,
                               busyTimes.Count);

                /* Assign the data structure to the exchange user */
                exchangeUser.BusyTimes = busyTimes;
            }
        }