Пример #1
0
        public static int GetConflictPriority(SyncFeedDigest digest, string endpoint)
        {
            foreach (SyncFeedDigestEntry entry in digest.Entries)
                if ((entry.Endpoint != null) && (entry.Endpoint.Equals(endpoint, StringComparison.InvariantCultureIgnoreCase)))
                    return entry.ConflictPriority;

            return 10000;
        }
Пример #2
0
 public static SyncState GetSyncState(SyncFeedDigest digest, string endpoint)
 {
     foreach (SyncFeedDigestEntry entry in digest.Entries)
     {
         if ((entry.Endpoint != null) && (entry.Endpoint.Equals(endpoint, StringComparison.InvariantCultureIgnoreCase)))
         {
             SyncState result = new SyncState();
             result.Endpoint = entry.Endpoint;
             result.Stamp = entry.Stamp;
             result.Tick = entry.Tick;
             return result;
         }
     }
     return null;
 }
            // Asynchronous called method
            private void Execute(NorthwindConfig config, SyncFeedDigest syncDigestInfo)
            {
                #region Declaration

                SdataContext sdataContext;
                SupportedResourceKinds resource;
                IAppBookmarkInfoStore appBookmarkInfoStore;
                ICorrelatedResSyncInfoStore correlatedResSyncInfoStore;
                ISyncSyncDigestInfoStore syncDigestStore;
                ISyncTickProvider tickProvider;
                string resourceKind;
                string endpoint;
                int nextTick = 0;
                Token lastToken;
                Token nextToken;
                Identity[] changedIdentites;
                IEntityWrapper wrapper;

                #endregion

                #region init

                sdataContext = _parentPerformer._requestContext.SdataContext;
                resource = _parentPerformer._requestContext.ResourceKind;
                resourceKind = resource.ToString();
                endpoint = _parentPerformer._requestContext.DatasetLink + resourceKind;
                appBookmarkInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetAppBookmarkStore(sdataContext);
                correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(sdataContext);
                syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext);
                tickProvider = RequestReceiver.NorthwindAdapter.StoreLocator.GetTickProvider(sdataContext);

                wrapper = EntityWrapperFactory.Create(resource, _parentPerformer._requestContext);

                #endregion

                #region get last token or create a new one

                if (!appBookmarkInfoStore.Get<Token>(resourceKind, out lastToken))
                {
                    lastToken = new Token();
                    lastToken.InitRequest = true;
                }

                #endregion

                #region Get local identities of changed entries since last synchronisation

                changedIdentites = wrapper.Entity.GetLastChanges(lastToken, config, out nextToken);

                #endregion

                if (resource == SupportedResourceKinds.phoneNumbers)
                {
                    #region workaround for phones
                    for (int index = 0; index < changedIdentites.Length; index++)
                    {
                        string phoneid = changedIdentites[index].Id + Sage.Integration.Northwind.Application.API.Constants.PhoneIdPostfix;
                        string faxId = changedIdentites[index].Id + Sage.Integration.Northwind.Application.API.Constants.FaxIdPostfix;

                        // receive the feed entry for local identity
                        SyncFeedEntry phoneentry = wrapper.GetFeedEntry(phoneid);
                        SyncFeedEntry faxentry = wrapper.GetFeedEntry(faxId);
                        if (phoneentry == null && faxentry == null)
                            continue;
                        // receive the correlation for the local identity

                        if (phoneentry != null)
                        {
                            CorrelatedResSyncInfo[] correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { phoneid });

                            string etag = EtagServices.ComputeEtag(phoneentry.Payload, true);   // new etag
                            if (correlatedResSyncInfos.Length == 0)
                            {
                                nextTick = tickProvider.CreateNextTick(resourceKind); // create next tick

                                ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), endpoint, nextTick, etag, DateTime.Now);
                                CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(phoneid, resyncInfo);

                                correlatedResSyncInfoStore.Put(resourceKind, info);

                                syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo);

                            }
                            else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag))
                            {
                                nextTick = tickProvider.CreateNextTick(resourceKind);
                                correlatedResSyncInfos[0].ResSyncInfo.Etag = etag;
                                correlatedResSyncInfos[0].ResSyncInfo.Tick = nextTick;
                                correlatedResSyncInfos[0].ResSyncInfo.Endpoint = endpoint;
                                correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now;
                                correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]);

                                syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo);
                            }
                        }
                        if (faxentry != null)
                        {
                            CorrelatedResSyncInfo[] correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { faxId });

                            string etag = EtagServices.ComputeEtag(faxentry.Payload, true);   // new etag
                            if (correlatedResSyncInfos.Length == 0)
                            {
                                nextTick = tickProvider.CreateNextTick(resourceKind); // create next tick

                                ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), endpoint, nextTick, etag, DateTime.Now);
                                CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(faxId, resyncInfo);

                                correlatedResSyncInfoStore.Put(resourceKind, info);

                                syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo);

                            }
                            else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag))
                            {
                                nextTick = tickProvider.CreateNextTick(resourceKind);
                                correlatedResSyncInfos[0].ResSyncInfo.Etag = etag;
                                correlatedResSyncInfos[0].ResSyncInfo.Tick = nextTick;
                                correlatedResSyncInfos[0].ResSyncInfo.Endpoint = endpoint;
                                correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now;
                                correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]);

                                syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo);
                            }
                        }

                    }
                    #endregion
                }
                else
                {
                    for (int index = 0; index < changedIdentites.Length; index++)
                    {
                        string id = changedIdentites[index].Id;
                        // receive the feed entry for local identity
                        SyncFeedEntry entry = wrapper.GetFeedEntry(id);
                        if (entry == null)
                            continue;
                        // receive the correlation for the local identity

                        CorrelatedResSyncInfo[] correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { id });

                        string etag = EtagServices.ComputeEtag(entry.Payload, true);   // new etag
                        if (correlatedResSyncInfos.Length == 0)
                        {
                            nextTick = tickProvider.CreateNextTick(resourceKind); // create next tick

                            ResSyncInfo resyncInfo = new ResSyncInfo(Guid.NewGuid(), endpoint, nextTick, etag, DateTime.Now);
                            CorrelatedResSyncInfo info = new CorrelatedResSyncInfo(id, resyncInfo);

                            correlatedResSyncInfoStore.Put(resourceKind, info);

                            syncDigestStore.PersistNewer(resourceKind, info.ResSyncInfo);

                        }
                        else if (!correlatedResSyncInfos[0].ResSyncInfo.Etag.Equals(etag))
                        {
                            nextTick = tickProvider.CreateNextTick(resourceKind);
                            correlatedResSyncInfos[0].ResSyncInfo.Etag = etag;
                            correlatedResSyncInfos[0].ResSyncInfo.Tick = nextTick;
                            correlatedResSyncInfos[0].ResSyncInfo.Endpoint = endpoint;
                            correlatedResSyncInfos[0].ResSyncInfo.ModifiedStamp = DateTime.Now;
                            correlatedResSyncInfoStore.Put(resourceKind, correlatedResSyncInfos[0]);

                            syncDigestStore.PersistNewer(resourceKind, correlatedResSyncInfos[0].ResSyncInfo);
                        }
                    }

                }

                #region store next token

                appBookmarkInfoStore.Put(resourceKind, nextToken);

                #endregion

                // set tracking phase
                lock (_parentPerformer._asyncStateObj)
                {
                    _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.GETCHANGESBYTICK;
                }

                // Receive syncDigestInfo
                if (null != syncDigestInfo)
                {
                    ICorrelatedResSyncInfoEnumerator enumerator;
                    List<string> endpoints = new List<string>();

                    foreach (SyncFeedDigestEntry digestEntry in syncDigestInfo.Entries)
                    {
                        endpoints.Add(digestEntry.Endpoint);
                        enumerator = correlatedResSyncInfoStore.GetSinceTick(resourceKind, digestEntry.Endpoint, digestEntry.Tick-2);
                        while (enumerator.MoveNext())
                        {
                            // No lock needed, as we expect that CorrelatedResSyncInfos list is
                            // only acceeded anywhere else when Tracking phase is 'finish'.
                            //lock(_parentPerformer._asyncStateObj)
                            //{
                            _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current);
                            //}
                        }
                    }

                    SyncDigestInfo sourceSyncDigestInfo = syncDigestStore.Get(resourceKind);
                    foreach (SyncDigestEntryInfo digestEntry in sourceSyncDigestInfo)
                    {
                        if (endpoints.Contains(digestEntry.Endpoint))
                            continue;
                        endpoints.Add(digestEntry.Endpoint);
                        enumerator = correlatedResSyncInfoStore.GetSinceTick(resourceKind, digestEntry.Endpoint, -1);
                        while (enumerator.MoveNext())
                        {
                            // No lock needed, as we expect that CorrelatedResSyncInfos list is
                            // only acceeded anywhere else when Tracking phase is 'finish'.
                            //lock(_parentPerformer._asyncStateObj)
                            //{
                            _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current);
                            //}
                        }
                    }
                    if (!endpoints.Contains(endpoint))
                    {
                        enumerator = correlatedResSyncInfoStore.GetSinceTick(resourceKind, endpoint, -1);
                        while (enumerator.MoveNext())
                        {
                            // No lock needed, as we expect that CorrelatedResSyncInfos list is
                            // only acceeded anywhere else when Tracking phase is 'finish'.
                            //lock(_parentPerformer._asyncStateObj)
                            //{
                            _parentPerformer._asyncStateObj.CorrelatedResSyncInfos.Add(enumerator.Current);
                            //}
                        }
                    }
                }

                // Set tracking phase
                lock (_parentPerformer._asyncStateObj.Tracking)
                {
                    _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.FINISH;
                }
            }
            public void DoWork(NorthwindConfig config, SyncFeedDigest syncDigestInfo)
            {
                ExecuteDelegate worker = new ExecuteDelegate(Execute);
                AsyncCallback completedCallback = new AsyncCallback(ExecuteCompletedCallback);

                AsyncOperation async = AsyncOperationManager.CreateOperation(null);

                // Begin asynchronous method call
                worker.BeginInvoke(config, syncDigestInfo, completedCallback, async);
            }