public void Put(string resourceKind, SyncDigestInfo info)
        {
            if (null == resourceKind)
            {
                throw new ArgumentNullException("resourceKind");
            }
            if (resourceKind == String.Empty)
            {
                throw new ArgumentException("Parameter value is empty.", "resourceKind");
            }

            if (null == info)
            {
                throw new ArgumentNullException("info");
            }

            // TODO: Validate entry property values

            // We set the priority on 'update'.
            lock (lockObj)
            {
                try
                {
                    _provider.Update(resourceKind, info);
                }
                catch (StoreException)
                {
                    _provider.Add(resourceKind, info);
                }
            }
        }
Exemple #2
0
        public SyncDigestInfo Get(int resourceKindId, IJetTransaction jetTransaction)
        {
            SyncDigestInfo resultInfo = new SyncDigestInfo();

            OleDbCommand oleDbCommand = jetTransaction.CreateOleCommand();

            string sqlQuery = string.Empty;

            sqlQuery = "SELECT {0}.Tick, {0}.ConflictPriority, {0}.Stamp, {1}.EndPoint FROM {1} INNER JOIN {0} ON {1}.ID={0}.FKEndPointId WHERE ((({0}.FKResourceKindId)=@ResourceKindId));";
            oleDbCommand.CommandText = string.Format(sqlQuery, _syncDigestTable.TableName, _syncDigestTable.EndPointTable.TableName);
            oleDbCommand.Parameters.AddWithValue("@ResourceKindId", resourceKindId);

            using (OleDbDataReader reader = oleDbCommand.ExecuteReader(CommandBehavior.Default))
            {
                while (reader.Read())
                {
                    string   EndPoint;
                    int      tick;
                    int      conflictPriority;
                    DateTime stamp;

                    EndPoint         = Convert.ToString(reader["EndPoint"]);
                    tick             = Convert.ToInt32(reader["tick"]);
                    conflictPriority = Convert.ToInt32(reader["ConflictPriority"]);
                    stamp            = Convert.ToDateTime(reader["Stamp"]);
                    resultInfo.Add(new SyncDigestEntryInfo(EndPoint, tick, conflictPriority, stamp));
                }
            }

            return(resultInfo);
        }
        public static string ToXml(SyncDigestInfo info, string endpoint)
        {
            StringBuilder sbDigest = new StringBuilder();
            sbDigest.Append(@"<?xml version=""1.0"" encoding=""utf-8"" ?>");
            sbDigest.Append(string.Format(@"<digest xmlns=""{0}"" mark=""current"">", Namespaces.syncNamespace));
            sbDigest.Append(@"<origin>");
            sbDigest.Append(endpoint);
            sbDigest.Append(@"</origin>");

            foreach (SyncDigestEntryInfo digestEntry in info)
            {
                sbDigest.Append(@"<digestEntry>");
                sbDigest.Append(@"<endpoint>");
                sbDigest.Append(digestEntry.Endpoint);
                sbDigest.Append(@"</endpoint>");
                sbDigest.Append(@"<tick>");
                sbDigest.Append(digestEntry.Tick.ToString());
                sbDigest.Append(@"</tick>");
                sbDigest.Append(@"<conflictPriority>");
                sbDigest.Append(digestEntry.ConflictPriority);
                sbDigest.Append(@"</conflictPriority>");
                sbDigest.Append(@"</digestEntry>");
            }
            sbDigest.Append(@"</digest>");
            return sbDigest.ToString();
        }
        public void Put(string resourceKind, SyncDigestInfo info)
        {
            if (null == resourceKind)
                throw new ArgumentNullException("resourceKind");
            if (resourceKind == String.Empty)
                throw new ArgumentException("Parameter value is empty.", "resourceKind");

            if (null == info)
                throw new ArgumentNullException("info");

            // TODO: Validate entry property values

            // We set the priority on 'update'.
            lock (lockObj)
            {
                try
                {
                    _provider.Update(resourceKind, info);
                }
                catch (StoreException)
                {
                    _provider.Add(resourceKind, info);
                }
            }
        }
        public static string ToXml(SyncDigestInfo info, string endpoint)
        {
            StringBuilder sbDigest = new StringBuilder();

            sbDigest.Append(@"<?xml version=""1.0"" encoding=""utf-8"" ?>");
            sbDigest.Append(string.Format(@"<digest xmlns=""{0}"" mark=""current"">", Namespaces.syncNamespace));
            sbDigest.Append(@"<origin>");
            sbDigest.Append(endpoint);
            sbDigest.Append(@"</origin>");


            foreach (SyncDigestEntryInfo digestEntry in info)
            {
                sbDigest.Append(@"<digestEntry>");
                sbDigest.Append(@"<endpoint>");
                sbDigest.Append(digestEntry.Endpoint);
                sbDigest.Append(@"</endpoint>");
                sbDigest.Append(@"<tick>");
                sbDigest.Append(digestEntry.Tick.ToString());
                sbDigest.Append(@"</tick>");
                sbDigest.Append(@"<conflictPriority>");
                sbDigest.Append(digestEntry.ConflictPriority);
                sbDigest.Append(@"</conflictPriority>");
                sbDigest.Append(@"</digestEntry>");
            }
            sbDigest.Append(@"</digest>");
            return(sbDigest.ToString());
        }
Exemple #6
0
        public static int GetConflictPriority(SyncDigestInfo digest, string EndPoint)
        {
            foreach (SyncDigestEntryInfo entry in digest)
                 if ((entry.EndPoint != null) && (entry.EndPoint.Equals(EndPoint, StringComparison.InvariantCultureIgnoreCase)))
                     return entry.ConflictPriority;

             return 10000;
        }
Exemple #7
0
        public void DoWork(IRequest request)
        {
            string       resourceKind = _requestContext.ResourceKind.ToString();
            string       endpoint     = _requestContext.DatasetLink + resourceKind;
            SdataContext sdataContext = _requestContext.SdataContext;

            ISyncSyncDigestInfoStore syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext);

            SyncDigestInfo syncDigestInfo = syncDigestStore.Get(resourceKind);

            SyncDigestPayload syncDigestPayload = new SyncDigestPayload();

            syncDigestPayload.Digest.Origin = endpoint;
            // create a new initial syncDigest and store it.
            if ((null == syncDigestInfo) || (syncDigestInfo.Count == 0))
            {
                SyncFeedDigestEntry entry = new SyncFeedDigestEntry();
                entry.ConflictPriority = 0;
                entry.Endpoint         = endpoint;
                entry.Stamp            = DateTime.Now;
                entry.Tick             = -1;
                syncDigestPayload.Digest.Entries.Add(entry);
            }
            else
            {
                foreach (SyncDigestEntryInfo digestEntry in syncDigestInfo)
                {
                    SyncFeedDigestEntry entry = new SyncFeedDigestEntry();
                    entry.ConflictPriority = digestEntry.ConflictPriority;
                    entry.Endpoint         = digestEntry.Endpoint;
                    //entry.Stamp = digestEntry.;
                    entry.Tick = digestEntry.Tick;
                    syncDigestPayload.Digest.Entries.Add(entry);
                }
            }
            SyncFeed feed = new SyncFeed();
            string   url  = endpoint + "/$syncDigest";
            FeedLink link = new FeedLink(url, LinkType.Self, MediaType.AtomEntry);

            feed.Links = new FeedLinkCollection();
            feed.Links.Add(link);
            feed.Id       = url;
            feed.FeedType = FeedType.ResourceEntry;
            SyncFeedEntry syncFeedEntry = new SyncFeedEntry();

            syncFeedEntry.Payload = syncDigestPayload;
            syncFeedEntry.Title   = "Synchronization digest";
            syncFeedEntry.Id      = url;

            syncFeedEntry.Links.Add(link);
            feed.Entries.Add(syncFeedEntry);

            feed.Id = url;

            request.Response.Serializer  = new SyncFeedSerializer();
            request.Response.Feed        = feed;
            request.Response.ContentType = MediaType.AtomEntry;
        }
Exemple #8
0
        public static int GetConflictPriority(SyncDigestInfo digest, string endpoint)
        {
            foreach (SyncDigestEntryInfo entry in digest)
            {
                if ((entry.Endpoint != null) && (entry.Endpoint.Equals(endpoint, StringComparison.InvariantCultureIgnoreCase)))
                {
                    return(entry.ConflictPriority);
                }
            }

            return(10000);
        }
Exemple #9
0
 public static SyncState GetSyncState(SyncDigestInfo digest, string endpoint)
 {
     foreach (SyncDigestEntryInfo entry in digest)
     {
         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);
 }
        public SyncDigestInfo Get(string resourceKind)
        {
            SyncDigestInfo            resultInfo               = null;
            ISyncDigestTableAdapter   syncDigestTableAdapter   = StoreEnvironment.Resolve <ISyncDigestTableAdapter>(_context);
            IResourceKindTableAdapter resourceKindTableAdapter = StoreEnvironment.Resolve <IResourceKindTableAdapter>(_context);

            using (IJetTransaction jetTransaction = _jetConnectionProvider.GetTransaction(false))
            {
                ResourceKindInfo resourceKindInfo = resourceKindTableAdapter.GetOrCreate(resourceKind, jetTransaction);

                resultInfo = syncDigestTableAdapter.Get(resourceKindInfo.Id, jetTransaction);

                jetTransaction.Commit();
            }

            return(resultInfo);
        }
        public void Add(string resourceKind, SyncDigestInfo info)
        {
            ISyncDigestTableAdapter syncDigestTableAdapter = StoreEnvironment.Resolve<ISyncDigestTableAdapter>(_context);
            IResourceKindTableAdapter resourceKindTableAdapter = StoreEnvironment.Resolve<IResourceKindTableAdapter>(_context);

            using (IJetTransaction jetTransaction = _jetConnectionProvider.GetTransaction(false))
            {
                ResourceKindInfo resourceKindInfo = resourceKindTableAdapter.GetOrCreate(resourceKind, jetTransaction);
                try
                {
                    syncDigestTableAdapter.Insert(resourceKindInfo.Id, info.ToArray(), jetTransaction);
                }
                catch (OleDbException exception)
                {
                    if (exception.Errors.Count == 1 && exception.Errors[0].SQLState == "3022")
                        throw new StoreException(string.Format("An error occured while adding a new syncDigest. A syncDigest already exists for the resourceKind '{0}'.", resourceKind), exception);

                    throw;
                }
                jetTransaction.Commit();
            }
        }
        public void Add(string resourceKind, SyncDigestInfo info)
        {
            ISyncDigestTableAdapter   syncDigestTableAdapter   = StoreEnvironment.Resolve <ISyncDigestTableAdapter>(_context);
            IResourceKindTableAdapter resourceKindTableAdapter = StoreEnvironment.Resolve <IResourceKindTableAdapter>(_context);

            using (IJetTransaction jetTransaction = _jetConnectionProvider.GetTransaction(false))
            {
                ResourceKindInfo resourceKindInfo = resourceKindTableAdapter.GetOrCreate(resourceKind, jetTransaction);
                try
                {
                    syncDigestTableAdapter.Insert(resourceKindInfo.Id, info.ToArray(), jetTransaction);
                }
                catch (OleDbException exception)
                {
                    if (exception.Errors.Count == 1 && exception.Errors[0].SQLState == "3022")
                    {
                        throw new StoreException(string.Format("An error occured while adding a new syncDigest. A syncDigest already exists for the resourceKind '{0}'.", resourceKind), exception);
                    }

                    throw;
                }
                jetTransaction.Commit();
            }
        }
            // 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;
                }
            }
            // Asynchronous called method
            private void Execute(NorthwindConfig config, Digest targetDigest)
            {
                #region Declaration

                SdataContext                sdataContext;
                SupportedResourceKinds      resource;
                IAppBookmarkInfoStore       appBookmarkInfoStore;
                ICorrelatedResSyncInfoStore correlatedResSyncInfoStore;
                ISyncSyncDigestInfoStore    syncDigestStore;
                ISynctickProvider           tickProvider;
                string     resourceKind;
                string     EndPoint;
                int        nexttick = 1;
                Token      lastToken;
                Token      nextToken;
                Identity[] changedIdentites;
                IFeedEntryEntityWrapper wrapper;

                #endregion

                #region init

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

                wrapper = FeedEntryWrapperFactory.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 resource payloads for the phone id and for the fax id
                        // so that we can calculate their current etags.
                        FeedEntry phoneResourcePayloadContainer = wrapper.GetFeedEntry(phoneid);
                        FeedEntry faxResourcePayloadConatainer  = wrapper.GetFeedEntry(faxId);

                        string etag;
                        CorrelatedResSyncInfo[] correlatedResSyncInfos;

                        #region Phone
                        if (phoneResourcePayloadContainer != null)
                        {
                            // calculate etag of the resource
                            etag = EtagServices.ComputeEtag(phoneResourcePayloadContainer, true);   // new etag

                            // retrieve correlations for the current identity from synch storage
                            correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { phoneid });

                            // if no correlation exists AND resource has been deleted:
                            // -> continue with next id
                            // else if no correlation exists:
                            // -> get next tick, create new correlation and add correlation to synch store
                            // otherwise and if the etag stored in synch store is different than etag previously calculated:
                            // -> get next tick, modify existing correlation and update it in synch store.
                            if (correlatedResSyncInfos.Length == 0 && phoneResourcePayloadContainer.IsDeleted)
                            {
                                continue;
                            }
                            else 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);
                            }
                        }

                        #endregion

                        #region Fax
                        if (faxResourcePayloadConatainer != null)
                        {
                            // calculate etag of the resource
                            etag = EtagServices.ComputeEtag(faxResourcePayloadConatainer, true);   // new etag

                            // retrieve correlations for the current identity from synch storage
                            correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { faxId });

                            // if no correlation exists AND resource has been deleted:
                            // -> continue with next id
                            // else if no correlation exists:
                            // -> get next tick, create new correlation and add correlation to synch store
                            // otherwise and if the etag stored in synch store is different than etag previously calculated:
                            // -> get next tick, modify existing correlation and update it in synch store.
                            if (correlatedResSyncInfos.Length == 0 && faxResourcePayloadConatainer.IsDeleted)
                            {
                                continue;
                            }
                            else 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
                    }
                    #endregion
                }
                else
                {
                    string    id;
                    FeedEntry resourcePayloadContainer;
                    CorrelatedResSyncInfo[] correlatedResSyncInfos;
                    string etag;

                    // iterate through the collection of ids of all changed resources.
                    for (int index = 0; index < changedIdentites.Length; index++)
                    {
                        // current id from iterated collection
                        id = changedIdentites[index].Id;

                        // get resource payload container for the current identity so that we can calculated the
                        // etag.
                        // continue with next identity if no resource was found.
                        resourcePayloadContainer = wrapper.GetFeedEntry(id);

                        // calculate etag of the current resource payload
                        etag = EtagServices.ComputeEtag(resourcePayloadContainer, true);


                        // retrieve correlations for the current identity from synch storage
                        correlatedResSyncInfos = correlatedResSyncInfoStore.GetByLocalId(resourceKind, new string[] { id });


                        // if no correlation exists AND resource has been deleted:
                        // -> continue with next id
                        // else if no correlation exists:
                        // -> get next tick, create new correlation and add correlation to synch store
                        // otherwise and if the etag stored in synch store is different than etag previously calculated:
                        // -> get next tick, modify existing correlation and update it in synch store.
                        if (resourcePayloadContainer == null || (correlatedResSyncInfos.Length == 0 && resourcePayloadContainer.IsDeleted))
                        {
                            continue;
                        }
                        else 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;
                }



                if (null != targetDigest)
                {
                    ICorrelatedResSyncInfoEnumerator enumerator;
                    List <string> EndPoints = new List <string>();
#warning remove this workaround
                    if (targetDigest.Entries != null)
                    {
                        foreach (DigestEntry targetDigestEntry in targetDigest.Entries)
                        {
                            EndPoints.Add(targetDigestEntry.EndPoint);
                            enumerator = correlatedResSyncInfoStore.GetSincetick(resourceKind, targetDigestEntry.EndPoint, ((int)targetDigestEntry.Tick) - 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);
                                //}
                            }
                        }
                    }

                    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 to FINISH
                lock (_parentPerformer._asyncStateObj.Tracking)
                {
                    _parentPerformer._asyncStateObj.Tracking.Phase = TrackingPhase.FINISH;
                }
            }
        public SyncDigestInfo Get(int resourceKindId, IJetTransaction jetTransaction)
        {
            SyncDigestInfo resultInfo = new SyncDigestInfo();

            OleDbCommand oleDbCommand = jetTransaction.CreateOleCommand();

            string sqlQuery = string.Empty;

            sqlQuery = "SELECT {0}.Tick, {0}.ConflictPriority, {0}.Stamp, {1}.EndPoint FROM {1} INNER JOIN {0} ON {1}.ID={0}.FKEndPointId WHERE ((({0}.FKResourceKindId)=@ResourceKindId));";
            oleDbCommand.CommandText = string.Format(sqlQuery, _syncDigestTable.TableName, _syncDigestTable.EndPointTable.TableName);
            oleDbCommand.Parameters.AddWithValue("@ResourceKindId", resourceKindId);

            using (OleDbDataReader reader = oleDbCommand.ExecuteReader(CommandBehavior.Default))
            {
                while (reader.Read())
                {
                    string EndPoint;
                    int tick;
                    int conflictPriority;
                    DateTime stamp;

                    EndPoint = Convert.ToString(reader["EndPoint"]);
                    tick = Convert.ToInt32(reader["tick"]);
                    conflictPriority = Convert.ToInt32(reader["ConflictPriority"]);
                    stamp = Convert.ToDateTime(reader["Stamp"]);
                    resultInfo.Add(new SyncDigestEntryInfo(EndPoint, tick, conflictPriority, stamp));
                }
            }

            return resultInfo;
        }
Exemple #16
0
 public static SyncState GetSyncState(SyncDigestInfo digest, string EndPoint)
 {
     foreach (SyncDigestEntryInfo entry in digest)
     {
         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>0)?entry.Tick:1;
             return result;
         }
     }
     return null;
 }
            /// <summary>
            ///
            /// </summary>
            /// <param name="config"></param>
            /// <returns></returns>
            /// <remarks>This method is not threadsafe as the performer must be finished when calling this method.</remarks>
            public SyncFeed GetFeed(NorthwindConfig config, int startIndex, int count)
            {
                SyncFeed               feed;
                SdataContext           sdataContext;
                SupportedResourceKinds resource;
                string resourceKind;
                string endpoint;
                Guid   trackingId;


                List <CorrelatedResSyncInfo> correlatedResSyncInfos;

                sdataContext           = _parentPerformer._requestContext.SdataContext;
                resource               = _parentPerformer._requestContext.ResourceKind;
                resourceKind           = resource.ToString();
                correlatedResSyncInfos = _parentPerformer._asyncStateObj.CorrelatedResSyncInfos;
                endpoint               = _parentPerformer._requestContext.DatasetLink + resourceKind;
                trackingId             = _parentPerformer._requestContext.TrackingId;


                ISyncSyncDigestInfoStore syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext);
                SyncDigestInfo           syncDigestInfo  = syncDigestStore.Get(resourceKind);


                if (count == 0)
                {
                    count = 10;
                }

                feed = new SyncFeed();
                Token emptyToken = new Token();

                feed.Digest         = new SyncFeedDigest();
                feed.Digest.Origin  = _parentPerformer._requestContext.OriginEndPoint;
                feed.Digest.Entries = new List <SyncFeedDigestEntry>();

                if (syncDigestInfo != null)
                {
                    foreach (SyncDigestEntryInfo entryinfo in syncDigestInfo)
                    {
                        SyncFeedDigestEntry entry = new SyncFeedDigestEntry();
                        entry.ConflictPriority = entryinfo.ConflictPriority;
                        entry.Endpoint         = entryinfo.Endpoint;
                        entry.Tick             = entryinfo.Tick;
                        entry.Stamp            = DateTime.Now;
                        feed.Digest.Entries.Add(entry);
                    }
                }



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


                for (int index = startIndex;
                     index < ((startIndex + count > correlatedResSyncInfos.Count) ? correlatedResSyncInfos.Count : startIndex + count);
                     index++)
                {
                    CorrelatedResSyncInfo resSyncInfo = (CorrelatedResSyncInfo)correlatedResSyncInfos[index];
                    SyncFeedEntry         entry       = wrapper.GetFeedEntry(resSyncInfo);
                    if (entry != null)
                    {
                        feed.Entries.Add(entry);
                    }
                    else
                    {
                        entry            = new SyncFeedEntry();
                        entry.HttpMethod = "DELETE";
                        entry.Uuid       = resSyncInfo.ResSyncInfo.Uuid;
                        feed.Entries.Add(entry);
                    }
                }


                // initialize the feed
                string url = string.Format("{0}/$syncSource('{1}')", endpoint, trackingId);

                feed.Id    = url;
                feed.Title = resourceKind;

                #region PAGING & OPENSEARCH

                int totalResults = correlatedResSyncInfos.Count;

                PageController pageController = new PageController(startIndex + 1, FeedMetadataHelpers.DEFAULT_ITEMS_PER_PAGE, totalResults, count, url);

                /* PAGING */
                FeedLinkCollection feedLinks = new FeedLinkCollection();
                feedLinks.Add(new FeedLink(pageController.GetLinkSelf(), LinkType.Self, MediaType.Atom, "Current Page"));
                feedLinks.Add(new FeedLink(pageController.GetLinkFirst(), LinkType.First, MediaType.Atom, "First Page"));
                feedLinks.Add(new FeedLink(pageController.GetLinkLast(), LinkType.Last, MediaType.Atom, "Last Page"));

                string linkUrl;
                if (pageController.GetLinkNext(out linkUrl))
                {
                    feedLinks.Add(new FeedLink(linkUrl, LinkType.Next, MediaType.Atom, "Next Page"));
                }
                if (pageController.GetLinkPrevious(out linkUrl))
                {
                    feedLinks.Add(new FeedLink(linkUrl, LinkType.Previous, MediaType.Atom, "Previous Page"));
                }

                feed.Links = feedLinks;


                /* OPENSEARCH */
                feed.Opensearch_ItemsPerPageElement = pageController.GetOpensearch_ItemsPerPageElement();
                feed.Opensearch_StartIndexElement   = pageController.GetOpensearch_StartIndexElement();
                feed.Opensearch_TotalResultsElement = pageController.GetOpensearch_TotalResultsElement();

                #endregion



                //feed.Id = url;
                //if (startIndex + count < correlatedResSyncInfos.Count)
                //{
                //    FeedLink linkNext = new FeedLink(string.Format("{0}?startIndex={1}&count=10", url, startIndex + count), LinkType.Next);
                //    feed.Links.Add(linkNext);
                //}

                //FeedLink linkFirst = new FeedLink(String.Format("{0}?startIndex=0&count=10", url), LinkType.First);
                //feed.Links.Add(linkFirst);

                //FeedLink linkSelf = new FeedLink(String.Format("{0}?startIndex={1}&count=10", url, startIndex), LinkType.Self);
                //feed.Links.Add(linkSelf);

                return(feed);
            }
            /// <summary>
            ///
            /// </summary>
            /// <param name="config"></param>
            /// <returns></returns>
            /// <remarks>This method is not threadsafe as the performer must be finished when calling this method.</remarks>
            public Feed <FeedEntry> GetFeed(NorthwindConfig config, PageInfo normalizedPageInfo)
            {
                Feed <FeedEntry>       syncSourceFeed;
                SdataContext           sdataContext;
                SupportedResourceKinds resource;
                string resourceKind;
                string EndPoint;
                Guid   trackingId;

                List <CorrelatedResSyncInfo> correlatedResSyncInfos;

                sdataContext           = _parentPerformer._requestContext.SdataContext;
                resource               = _parentPerformer._requestContext.ResourceKind;
                resourceKind           = resource.ToString();
                correlatedResSyncInfos = _parentPerformer._asyncStateObj.CorrelatedResSyncInfos;
                EndPoint               = _parentPerformer._requestContext.DatasetLink + resourceKind;
                trackingId             = _parentPerformer._requestContext.TrackingId;


                //ISyncSyncDigestInfoStore syncDigestStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext);
                ISyncSyncDigestInfoStore syncDigestStore = NorthwindAdapter.StoreLocator.GetSyncDigestStore(sdataContext);
                SyncDigestInfo           syncDigestInfo  = syncDigestStore.Get(resourceKind);

                // Create a new Feed instance
                syncSourceFeed             = new Feed <FeedEntry>();//FeedComponentFactory.Create<ISyncSourceFeed>();
                syncSourceFeed.Author      = new FeedAuthor();
                syncSourceFeed.Author.Name = "Northwind Adapter";
                syncSourceFeed.Category    = new FeedCategory("http://schemas.sage.com/sdata/categories", "collection", "Resource Collection");



                #region Digest

                syncSourceFeed.Digest         = new Digest();
                syncSourceFeed.Digest.Entries = (syncDigestInfo == null) ? new DigestEntry[0] : new DigestEntry[syncDigestInfo.Count];

                // set digest origin
                syncSourceFeed.Digest.Origin = _parentPerformer._requestContext.OriginEndPoint;

                if (syncDigestInfo != null)
                {
                    // convert and set digest entries from synch store object to feed object
                    for (int i = 0; i < syncDigestInfo.Count; i++)
                    {
                        syncSourceFeed.Digest.Entries[i] = new DigestEntry();

                        syncSourceFeed.Digest.Entries[i].ConflictPriority = syncDigestInfo[i].ConflictPriority;
                        syncSourceFeed.Digest.Entries[i].EndPoint         = syncDigestInfo[i].EndPoint;
                        syncSourceFeed.Digest.Entries[i].Tick             = (int)syncDigestInfo[i].Tick;
                        syncSourceFeed.Digest.Entries[i].Stamp            = DateTime.Now;
                    }
                }

                #endregion

                #region Entries

                // retrieve the data connection wrapper
                IFeedEntryEntityWrapper wrapper = FeedEntryWrapperFactory.Create(resource, _parentPerformer._requestContext);

                IEnumerator <CorrelatedResSyncInfo> correlationEnumerator = PagingHelpers.GetPagedEnumerator <CorrelatedResSyncInfo>(normalizedPageInfo, correlatedResSyncInfos.ToArray());
                while (correlationEnumerator.MoveNext())
                {
                    syncSourceFeed.Entries.Add(this.BuildFeedEntry(correlationEnumerator.Current, wrapper));
                }

                #endregion

                // initialize the feed
                string feedUrl             = string.Format("{0}/$syncSource('{1}')", EndPoint, trackingId);
                string feedUrlWithoutQuery = (new Uri(feedUrl)).GetLeftPart(UriPartial.Path);   // the url without query
                // set id tag
                syncSourceFeed.Id = feedUrl;
                // set title tag
                syncSourceFeed.Title = string.Format("{0} synchronization source feed {1}", resourceKind.ToString(), trackingId);
                // set update
                // syncSourceFeed.Updated = DateTime.Now;
                // set syncMode
                syncSourceFeed.SyncMode = SyncMode.catchUp;// syncModeenum.catchUp;

                // add links (general)
                syncSourceFeed.Links.AddRange(LinkFactory.CreateFeedLinks(_parentPerformer._requestContext, feedUrl));

                #region PAGING & OPENSEARCH

                // add links (paging)
                syncSourceFeed.Links.AddRange(LinkFactory.CreatePagingLinks(normalizedPageInfo, correlatedResSyncInfos.Count, feedUrlWithoutQuery));

                /* OPENSEARCH */
                syncSourceFeed.ItemsPerPage = normalizedPageInfo.Count;
                syncSourceFeed.StartIndex   = normalizedPageInfo.StartIndex;
                syncSourceFeed.TotalResults = correlatedResSyncInfos.Count;

                #endregion

                return(syncSourceFeed);
            }