private FeedEntry BuildFeedEntry(CorrelatedResSyncInfo correlation, IFeedEntryEntityWrapper wrapper)
            {
                // create a new empty Feed Entry
                //ISyncSourceResourceFeedEntry feedEntry = FeedComponentFactory.Create<ISyncSourceResourceFeedEntry>();
                // get resource payload container from data store
                FeedEntry feedEntry = wrapper.GetSyncSourceFeedEntry(correlation);


                // create and set SyncState
                feedEntry.SyncState          = new SyncState();
                feedEntry.SyncState.EndPoint = correlation.ResSyncInfo.EndPoint;
                feedEntry.SyncState.Tick     = (correlation.ResSyncInfo.Tick > 0) ? correlation.ResSyncInfo.Tick : 1;
                feedEntry.SyncState.Stamp    = correlation.ResSyncInfo.ModifiedStamp;

                // set the id tag
                feedEntry.Id = feedEntry.Uri;
                // set the title tag
                feedEntry.Title = String.Format("{0}: {1}", _parentPerformer._requestContext.ResourceKind.ToString(), feedEntry.Key);
                // set the updated tag
                feedEntry.Updated = correlation.ResSyncInfo.ModifiedStamp.ToLocalTime();

                // set resource dependent  links (self, edit, schema, template, post, service)
                feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_parentPerformer._requestContext, feedEntry));


                return(feedEntry);
            }
예제 #2
0
 public PriceFeedEntryWrapper(RequestContext context)
     : base(context, Adapter.Common.SupportedResourceKinds.prices)
 {
     _entity = new Price();
     _transform = new PriceTransform(context);
     _commodityFeedEntryWrapper = FeedEntryWrapperFactory.Create(SupportedResourceKinds.commodities, context);
 }
예제 #3
0
 public PriceFeedEntryWrapper(RequestContext context)
     : base(context, Adapter.Common.SupportedResourceKinds.prices)
 {
     _entity    = new Price();
     _transform = new PriceTransform(context);
     _commodityFeedEntryWrapper = FeedEntryWrapperFactory.Create(SupportedResourceKinds.commodities, context);
 }
예제 #4
0
        public void Create(FeedEntry entry)
        {
            if (IsValid(entry))
            {
                IFeedEntryEntityWrapper cWrapper = FeedEntryWrapperFactory.Create(_context.ResourceKind, _context);
                SdataTransactionResult  trResult = cWrapper.Add(entry);
                if (trResult.HttpStatus == System.Net.HttpStatusCode.Created ||
                    trResult.HttpStatus == System.Net.HttpStatusCode.OK)
                {
                    if (string.IsNullOrEmpty(entry.Id))
                    {
                        entry.Id = trResult.Location;
                    }

                    _request.Response.FeedEntry = entry;
                    _request.Response.Protocol.SendKnownResponseHeader(System.Net.HttpResponseHeader.Location, entry.Id);
                }
                else
                {
                    _request.Response.StatusCode = trResult.HttpStatus;
                    _request.Response.Diagnoses  = new Diagnoses();
                    _request.Response.Diagnoses.Add(GetDiagnosis(trResult));
                    //throw new InvalidDataException(trResult.HttpStatus + ": " + trResult.HttpMessage);
                }
            }
            else
            {
                throw new RequestException("Please use valid single resource url");
            }
        }
 public SalesOrderFeedEntryWrapper(RequestContext context)
     : base(context, Adapter.Common.SupportedResourceKinds.salesOrders)
 {
     _entity = new Order();
     _tradingAccountsFeedEntryWrapper = FeedEntryWrapperFactory.Create(SupportedResourceKinds.tradingAccounts, context);
     _commoditiesFeedEntryWrapper = FeedEntryWrapperFactory.Create(SupportedResourceKinds.commodities, context);
     _unitsOfMeasureFeedEntryWrapper = FeedEntryWrapperFactory.Create(SupportedResourceKinds.unitsOfMeasure, context);
 }
예제 #6
0
 public SalesOrderFeedEntryWrapper(RequestContext context)
     : base(context, Adapter.Common.SupportedResourceKinds.salesOrders)
 {
     _entity = new Order();
     _tradingAccountsFeedEntryWrapper = FeedEntryWrapperFactory.Create(SupportedResourceKinds.tradingAccounts, context);
     _commoditiesFeedEntryWrapper     = FeedEntryWrapperFactory.Create(SupportedResourceKinds.commodities, context);
     _unitsOfMeasureFeedEntryWrapper  = FeedEntryWrapperFactory.Create(SupportedResourceKinds.unitsOfMeasure, context);
 }
예제 #7
0
        protected FeedEntry BuildFeedEntryForCorrelation(CorrelatedResSyncInfo corrResSyncInfo, IFeedEntryEntityWrapper wrapper)
        {
            FeedEntry feedEntry;

            #region Payload

            if (null != wrapper)
            {
                // Get resource data
                feedEntry = wrapper.GetFeedEntry(corrResSyncInfo.LocalId);
            }
            else
            {
                // Create an empty payload container
                feedEntry = new FeedEntry();
                feedEntry.IsDeleted = false;

                feedEntry.Key = corrResSyncInfo.LocalId;
            }
            if (feedEntry != null)
            {
                // modify url and set uuid as we are requesting linked resources here.
                feedEntry.Uri = string.Format("{0}{1}('{2}')", _requestContext.DatasetLink, _requestContext.ResourceKind.ToString() , corrResSyncInfo.LocalId);
                feedEntry.UUID = corrResSyncInfo.ResSyncInfo.Uuid;

            #endregion

                // set id tag
                feedEntry.Id = feedEntry.Uri;

                // set title tag
                feedEntry.Title = string.Format("{0}('{1}') : {2}", _requestContext.ResourceKind.ToString(), corrResSyncInfo.LocalId, corrResSyncInfo.ResSyncInfo.Uuid);
                feedEntry.Updated = corrResSyncInfo.ResSyncInfo.ModifiedStamp.ToLocalTime();

                // set resource dependent  links (self, edit, schema, template, post, service)
                feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_requestContext, feedEntry));

            }
            return feedEntry;
        }
예제 #8
0
 public CRUD(IRequest request)
 {
     _context = new RequestContext(request.Uri);
     _wrapper = FeedEntryWrapperFactory.Create(_context.ResourceKind, _context);
     _request = request;
 }
        protected FeedEntry BuildFeedEntryForCorrelation(CorrelatedResSyncInfo corrResSyncInfo, IFeedEntryEntityWrapper wrapper)
        {
            FeedEntry feedEntry;

            #region Payload

            if (null != wrapper)
            {
                // Get resource data
                feedEntry = wrapper.GetFeedEntry(corrResSyncInfo.LocalId);
            }
            else
            {
                // Create an empty payload container
                feedEntry           = new FeedEntry();
                feedEntry.IsDeleted = false;

                feedEntry.Key = corrResSyncInfo.LocalId;
            }
            if (feedEntry != null)
            {
                // modify url and set uuid as we are requesting linked resources here.
                feedEntry.Uri  = string.Format("{0}{1}('{2}')", _requestContext.DatasetLink, _requestContext.ResourceKind.ToString(), corrResSyncInfo.LocalId);
                feedEntry.UUID = corrResSyncInfo.ResSyncInfo.Uuid;

                #endregion

                // set id tag
                feedEntry.Id = feedEntry.Uri;

                // set title tag
                feedEntry.Title   = string.Format("{0}('{1}') : {2}", _requestContext.ResourceKind.ToString(), corrResSyncInfo.LocalId, corrResSyncInfo.ResSyncInfo.Uuid);
                feedEntry.Updated = corrResSyncInfo.ResSyncInfo.ModifiedStamp.ToLocalTime();

                // set resource dependent  links (self, edit, schema, template, post, service)
                feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_requestContext, feedEntry));
            }
            return(feedEntry);
        }
예제 #10
0
        public void Create(FeedEntry entry)
        {
            // only atom entry supported!!!

            if (_request.ContentType != Sage.Common.Syndication.MediaType.AtomEntry)
            {
                throw new RequestException("Atom entry content type expected");
            }

            string         requestEndPointUrl;
            RequestContext entryResourceAsRequestContext;

            string url;             // The url that references an existing resource
            string localId;         // will be parsed from urlAttrValue and set to the key attribute of the result resource payload
            Guid   uuid;            // the new uuid

            if (null == entry)
            {
                throw new RequestException("sdata payload element missing");
            }

            // the consumer MUST provide an sdata:url attribute that references an existing resource.
            url = entry.Uri;
            if (string.IsNullOrEmpty(url))
            {
                throw new RequestException("sdata url attribute missing for resource payload element.");
            }


            // Parse the url of thew url attribute to get the local id.
            // Additionally we check for equality of the urls of the request url and
            // in the linked element up to the resourceKind.
            requestEndPointUrl            = _requestContext.OriginEndPoint;
            entryResourceAsRequestContext = new RequestContext(new Sage.Common.Syndication.SDataUri(url));    // TODO: not really nice here.
            string linkedResourceUrl = entryResourceAsRequestContext.OriginEndPoint;

            if (!string.Equals(requestEndPointUrl, linkedResourceUrl, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new RequestException("Request url and linked entry resource not matching.");
            }

            string resourceKindName = _requestContext.ResourceKind.ToString();

            localId = entryResourceAsRequestContext.ResourceKey;

            ICorrelatedResSyncInfoStore correlatedResSyncInfoStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext);

            CheckExisting(correlatedResSyncInfoStore, localId);

            // try to get the new uuid from uuid attribute
            // if this attribute is not set a new one is created
            if (null == entry.UUID || entry.UUID == Guid.Empty)
            {
                uuid = Guid.NewGuid();
            }
            else
            {
                uuid = entry.UUID;
            }


            // store a new correlation entry to the sync store
            ResSyncInfo           newResSyncInfo = new ResSyncInfo(uuid, requestEndPointUrl, 0, string.Empty, DateTime.Now);
            CorrelatedResSyncInfo newInfo        = new CorrelatedResSyncInfo(localId, newResSyncInfo);

            correlatedResSyncInfoStore.Add(resourceKindName, newInfo);



            // If the service consumer only needs to retrieve the URL, not the actual payload,
            // it may do so by adding an empty select parameter to its request:
            // a) select parameter not exist -> return deep resource payload
            // b) select exists and empty -> return no resource payload
            // c) select exists and not empty -> return deep resource payload as we do not yet support payload filtering
            //    with select parameter.
            string tmpValue;
            // ?select
            bool includeResourcePayloads = true;    // default value, but check for select parameter now

            if (_requestContext.SdataUri.QueryArgs.TryGetValue("select", out tmpValue))
            {
                if (string.IsNullOrEmpty(_requestContext.SdataUri.QueryArgs["select"]))
                {
                    includeResourcePayloads = false;
                }
            }


            // Create an entity wrapper if resource data should be requested. Otherwise
            // leave wrapper null.
            IFeedEntryEntityWrapper wrapper = null;

            //if (includeResourcePayloads) //TODO: Comment this in as soon as there is a possibility to send empty payload objects
            wrapper = FeedEntryWrapperFactory.Create(_requestContext.ResourceKind, _requestContext);

            /* Create the response entry */
            _request.Response.FeedEntry   = (FeedEntry)this.BuildFeedEntryForCorrelation(newInfo, wrapper);
            _request.Response.ContentType = MediaType.AtomEntry;

            _request.Response.StatusCode = System.Net.HttpStatusCode.Created;
            _request.Response.Protocol.SendUnknownResponseHeader("location", FeedMetadataHelpers.BuildLinkedEntryUrl(_requestContext, uuid));
        }
            private FeedEntry BuildFeedEntry(SdataTransactionResult transactionResult, IFeedEntryEntityWrapper wrapper)
            {
                // Create result feed entry
                FeedEntry feedEntry;

                if (null != transactionResult.Diagnosis)
                {
                    /* set diagnosis */
                    feedEntry           = new FeedEntry();
                    feedEntry.Diagnoses = new Diagnoses();
                    feedEntry.Diagnoses.Add(transactionResult.Diagnosis);
                }
                else
                {
                    /* get and the resource payload */

                    // Get resource data
                    feedEntry = wrapper.GetSyncTargetFeedEntry(transactionResult);

                    // set id tag
                    feedEntry.Id = feedEntry.Uri;

                    // set title tag
                    feedEntry.Title = String.Format("{0}: {1}", _parentPerformer._requestContext.ResourceKind.ToString(), feedEntry.Key);

                    // set resource dependent  links (self, edit, schema, template, post, service)
                    feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_parentPerformer._requestContext, feedEntry));
                }


                // set updated
                feedEntry.Updated = DateTime.Now.ToLocalTime();


                feedEntry.HttpStatusCode = transactionResult.HttpStatus;
                feedEntry.HttpMessage    = transactionResult.HttpMessage;;
                if (transactionResult.HttpMethod == HttpMethod.PUT)
                {
                    feedEntry.HttpMethod = "PUT";
                }
                else if (transactionResult.HttpMethod == HttpMethod.POST)
                {
                    feedEntry.HttpMethod = "POST";
                }
                else
                {
                    feedEntry.HttpMethod = "DELETE";
                }

                feedEntry.HttpLocation = transactionResult.Location;


                return(feedEntry);
            }
예제 #12
0
        public void Read()
        {
            string                      resourceKindName;
            EntryRequestType            entryRequestType; // Multi or Single
            bool                        includeResourcePayloads;
            ICorrelatedResSyncInfoStore correlatedResSyncStore;

            CorrelatedResSyncInfo[] correlatedResSyncInfos;
            int      totalResult;               // number of correlations found
            PageInfo normalizedPageInfo;        // normalized pageInfo -> will be used for paging, etc.

            resourceKindName = _requestContext.ResourceKind.ToString();

            // multi or single entry request?
            entryRequestType = (String.IsNullOrEmpty(_requestContext.ResourceKey)) ? EntryRequestType.Multi : EntryRequestType.Single;

            // get store to request the correlations
            correlatedResSyncStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext);


            // receive correlated resource synchronization entries
            if (entryRequestType == EntryRequestType.Multi)
            {
                int pageNumber = PagingHelpers.GetPageNumber(_request.Uri.StartIndex, _request.Uri.Count);

                correlatedResSyncInfos = correlatedResSyncStore.GetPaged(resourceKindName, pageNumber, (int)(_request.Uri.Count ?? DEFAULT_ITEMS_PER_PAGE), out totalResult);
            }
            else
            {
                Guid uuid = (Guid)TypeDescriptor.GetConverter(typeof(Guid)).ConvertFrom(_requestContext.ResourceKey);
                correlatedResSyncInfos = correlatedResSyncStore.GetByUuid(resourceKindName, new Guid[] { uuid });
                totalResult            = correlatedResSyncInfos.Length;
                if (totalResult > 1)
                {
                    throw new ApplicationException("More than one resource for uuid exists.");
                }
                if (totalResult == 0)
                {
                    throw new RequestException("No resource found");
                }
            }


            // If the service consumer only needs to retrieve the URL, not the actual payload,
            // it may do so by adding an empty select parameter to its request:
            // a) select parameter not exist -> return deep resource payload
            // b) select exists and empty -> return no resource payload
            // c) select exists and not empty -> return deep resource payload as we do not yet support payload filtering
            //    with select parameter.
            string tmpValue;

            // ?select
            includeResourcePayloads = true;    // default value, but check for select parameter now
            if (_requestContext.SdataUri.QueryArgs.TryGetValue("select", out tmpValue))
            {
                if (string.IsNullOrEmpty(_requestContext.SdataUri.QueryArgs["select"]))
                {
                    includeResourcePayloads = false;
                }
            }



            if (entryRequestType == EntryRequestType.Single)
            {
                IFeedEntryEntityWrapper wrapper = null;
                //if (includeResourcePayloads) //TODO: Comment this in as soon as there is a possibility to send empty payload objects
                wrapper = FeedEntryWrapperFactory.Create(_requestContext.ResourceKind, _requestContext);

                _request.Response.FeedEntry   = this.BuildFeedEntryForCorrelation(correlatedResSyncInfos[0], wrapper);
                _request.Response.ContentType = MediaType.AtomEntry;
            }
            else
            {
                // Create an empty feed
                Feed <FeedEntry> feed = new Feed <FeedEntry>();
                feed.Author      = new FeedAuthor();
                feed.Author.Name = "Northwind Adapter";
                feed.Category    = new FeedCategory("http://schemas.sage.com/sdata/categories", "collection", "Resource Collection");
                DateTime updateTime = DateTime.Now;

                string feedUrl             = _requestContext.SdataUri.ToString();             // the url requested
                string feedUrlWithoutQuery = (new Uri(feedUrl)).GetLeftPart(UriPartial.Path); // the url without query

                normalizedPageInfo = PagingHelpers.Normalize(_request.Uri.StartIndex, _request.Uri.Count, totalResult);

                IFeedEntryEntityWrapper wrapper = null;
                //if (includeResourcePayloads) //TODO: Comment this in as soon as there is a possibility to send empty payload objects
                wrapper = FeedEntryWrapperFactory.Create(_requestContext.ResourceKind, _requestContext);

                // create a feed entry for each correlation.
                IEnumerator <CorrelatedResSyncInfo> pagedCorrelationEnumerator = PagingHelpers.GetPagedEnumerator <CorrelatedResSyncInfo>(normalizedPageInfo, correlatedResSyncInfos);
                while (pagedCorrelationEnumerator.MoveNext())
                {
                    // Create and append a feed entry per each id
                    FeedEntry entry = this.BuildFeedEntryForCorrelation(pagedCorrelationEnumerator.Current, wrapper);
                    if (entry != null)
                    {
                        feed.Entries.Add(entry);
                    }
                }


                // set feed title
                feed.Title = string.Format("{0} linked {1}", feed.Entries.Count, resourceKindName);

                // set feed update
                feed.Updated = updateTime;

                // set id
                feed.Id = feedUrl;

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

                #region PAGING & OPENSEARCH

                // add links (paging)
                feed.Links.AddRange(LinkFactory.CreatePagingLinks(normalizedPageInfo, totalResult, feedUrlWithoutQuery));

                /* OPENSEARCH */
                feed.ItemsPerPage = normalizedPageInfo.Count;
                feed.StartIndex   = normalizedPageInfo.StartIndex;
                feed.TotalResults = totalResult;

                #endregion

                _request.Response.Feed        = feed;
                _request.Response.ContentType = MediaType.Atom;
            }
        }
            /// <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);
            }
            private FeedEntry BuildFeedEntry(CorrelatedResSyncInfo correlation, IFeedEntryEntityWrapper wrapper)
            {
                // create a new empty Feed Entry
                //ISyncSourceResourceFeedEntry feedEntry = FeedComponentFactory.Create<ISyncSourceResourceFeedEntry>();
                // get resource payload container from data store
                FeedEntry feedEntry = wrapper.GetSyncSourceFeedEntry(correlation);

                // create and set SyncState
                feedEntry.SyncState = new SyncState();
                feedEntry.SyncState.EndPoint = correlation.ResSyncInfo.EndPoint;
                feedEntry.SyncState.Tick = (correlation.ResSyncInfo.Tick > 0) ? correlation.ResSyncInfo.Tick : 1;
                feedEntry.SyncState.Stamp = correlation.ResSyncInfo.ModifiedStamp;

                // set the id tag
                feedEntry.Id = feedEntry.Uri;
                // set the title tag
                feedEntry.Title = String.Format("{0}: {1}", _parentPerformer._requestContext.ResourceKind.ToString(), feedEntry.Key);
                // set the updated tag
                feedEntry.Updated = correlation.ResSyncInfo.ModifiedStamp.ToLocalTime();

                // set resource dependent  links (self, edit, schema, template, post, service)
                feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_parentPerformer._requestContext, feedEntry));

                return feedEntry;
            }
            private FeedEntry BuildFeedEntry(SdataTransactionResult transactionResult, IFeedEntryEntityWrapper wrapper)
            {
                // Create result feed entry
                FeedEntry feedEntry;

                if (null != transactionResult.Diagnosis)
                {
                    /* set diagnosis */
                    feedEntry = new FeedEntry();
                    feedEntry.Diagnoses = new Diagnoses();
                    feedEntry.Diagnoses.Add(transactionResult.Diagnosis);
                }
                else
                {
                    /* get and the resource payload */

                    // Get resource data
                    feedEntry = wrapper.GetSyncTargetFeedEntry(transactionResult);

                    // set id tag
                    feedEntry.Id = feedEntry.Uri;

                    // set title tag
                    feedEntry.Title = String.Format("{0}: {1}", _parentPerformer._requestContext.ResourceKind.ToString(), feedEntry.Key);

                    // set resource dependent  links (self, edit, schema, template, post, service)
                    feedEntry.Links.AddRange(LinkFactory.CreateEntryLinks(_parentPerformer._requestContext, feedEntry));
                }

                // set updated
                feedEntry.Updated = DateTime.Now.ToLocalTime();

                feedEntry.HttpStatusCode = transactionResult.HttpStatus;
                feedEntry.HttpMessage = transactionResult.HttpMessage; ;
                if (transactionResult.HttpMethod == HttpMethod.PUT)
                    feedEntry.HttpMethod = "PUT";
                else if (transactionResult.HttpMethod == HttpMethod.POST)
                    feedEntry.HttpMethod = "POST";
                else
                    feedEntry.HttpMethod = "DELETE";

                feedEntry.HttpLocation = transactionResult.Location;

                return feedEntry;
            }
예제 #16
0
 public CRUD(IRequest request)
 {
     _context = new RequestContext(request.Uri);
     _wrapper = FeedEntryWrapperFactory.Create(_context.ResourceKind, _context);
     _request = request;
 }
예제 #17
0
        public void Update(FeedEntry entry)
        {
            // only atom entry supported!!!
            if (_request.ContentType != Sage.Common.Syndication.MediaType.AtomEntry)
            {
                throw new RequestException("Atom entry content type expected");
            }

            // resource key must exist in url
            if (string.IsNullOrEmpty(_requestContext.ResourceKey))
            {
                throw new RequestException("ResourceKey missing in requested url.");
            }

            string         requestEndPointUrl;
            RequestContext entryResourceAsRequestContext;

            string url;             // The url that references an existing resource
            string localId;         // will be parsed from urlAttrValue and set to the key attribute of the result resource payload
            Guid   uuid;            // the new uuid

            // retrieve the feed entry
            //entry = FeedComponentFactory.Create<ILinkingResourceFeedEntry>(request.Stream);


            // Get the uuid from query
            uuid = (Guid)TypeDescriptor.GetConverter(typeof(Guid)).ConvertFrom(_requestContext.ResourceKey);


            if (null == entry)
            {
                throw new RequestException("sdata payload element missing");
            }

            // the consumer MUST provide an sdata:url attribute that references an existing resource.
            url = entry.Uri;
            if (string.IsNullOrEmpty(url))
            {
                throw new RequestException("sdata url attribute missing for resource payload element.");
            }


            // Parse the url of thew url attribute to get the local id.
            // Additionally we check for equality of the urls of the request url and
            // in the linked element up to the resourceKind.
            requestEndPointUrl            = _requestContext.OriginEndPoint;
            entryResourceAsRequestContext = new RequestContext(new Sage.Common.Syndication.SDataUri(url));    // TODO: not really nice here.
            string linkedResourceUrl = entryResourceAsRequestContext.OriginEndPoint;

            if (!string.Equals(requestEndPointUrl, linkedResourceUrl, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new RequestException("Request url and linked entry resource not matching.");
            }

            string resourceKindName = _requestContext.ResourceKind.ToString();

            localId = entryResourceAsRequestContext.ResourceKey;



            // The correlation store
            ICorrelatedResSyncInfoStore correlatedResSyncInfoStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext);


            // update the correlation entry in the sync store.
            // if uuid is not in use -> throw exception
            // if resource is already linked -> remove existing link, reassign link
            // if resource is not yet linked -> reassign link
            CorrelatedResSyncInfo[] correlations;
            CorrelatedResSyncInfo   correlationToModify = null;

            // retrieve the correlation we want to reassign by given uuid
            correlations = correlatedResSyncInfoStore.GetByUuid(resourceKindName, new Guid[] { uuid });
            if (correlations.Length > 0)
            {
                correlationToModify = correlations[0];
            }
            else
            {
                throw new RequestException("Uuid not in use");
            }

            //remember the old Correlation for the new localId, will be deleted after the update.
            CorrelatedResSyncInfo[] oldCorrelations = correlatedResSyncInfoStore.GetByLocalId(resourceKindName, new string[] { localId });

            // change the local ID to link to the new resource.
            // change the modification stamp and reset the tick
            correlationToModify.LocalId = localId;
            correlationToModify.ResSyncInfo.ModifiedStamp = DateTime.Now;
            correlationToModify.ResSyncInfo.Tick          = 1;

            // update the correlation
            correlatedResSyncInfoStore.Update(resourceKindName, correlationToModify);

            //If updating went OK, delete the old correlation for the new localId (should be only 1, for-loop just to be sure to catch em all)
            foreach (CorrelatedResSyncInfo oldCorrelation in oldCorrelations)
            {
                correlatedResSyncInfoStore.Delete(resourceKindName, oldCorrelation.ResSyncInfo.Uuid);
            }

            // If the service consumer only needs to retrieve the URL, not the actual payload,
            // it may do so by adding an empty select parameter to its request:
            // a) select parameter not exist -> return deep resource payload
            // b) select exists and empty -> return no resource payload
            // c) select exists and not empty -> return deep resource payload as we do not yet support payload filtering
            //    with select parameter.
            string tmpValue;
            // ?select
            bool includeResourcePayloads = true;    // default value, but check for select parameter now

            if (_requestContext.SdataUri.QueryArgs.TryGetValue("select", out tmpValue))
            {
                if (string.IsNullOrEmpty(_requestContext.SdataUri.QueryArgs["select"]))
                {
                    includeResourcePayloads = false;
                }
            }


            // Create an entity wrapper if resource data should be requested. Otherwise
            // leave wrapper null.
            IFeedEntryEntityWrapper wrapper = null;

            //if (includeResourcePayloads) //TODO: Comment this in as soon as there is a possibility to send empty payload objects
            wrapper = FeedEntryWrapperFactory.Create(_requestContext.ResourceKind, _requestContext);

            /* Create the response entry */
            _request.Response.FeedEntry   = (FeedEntry)this.BuildFeedEntryForCorrelation(correlationToModify, wrapper);
            _request.Response.ContentType = MediaType.AtomEntry;
        }
            /// <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> syncTargetFeed = new Feed <FeedEntry>();

                syncTargetFeed.Author      = new FeedAuthor();
                syncTargetFeed.Author.Name = "Northwind Adapter";
                syncTargetFeed.Category    = new FeedCategory("http://schemas.sage.com/sdata/categories", "collection", "Resource Collection");

                SdataContext           sdataContext;
                SupportedResourceKinds resource;
                string resourceKind;
                string EndPoint;
                Guid   trackingId;

                List <SdataTransactionResult> transactinResults;

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


                // Create a new Feed instance


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

                IEnumerator <SdataTransactionResult> transactionResultEnumerator = PagingHelpers.GetPagedEnumerator <SdataTransactionResult>(normalizedPageInfo, transactinResults.ToArray());

                while (transactionResultEnumerator.MoveNext())
                {
                    syncTargetFeed.Entries.Add(this.BuildFeedEntry(transactionResultEnumerator.Current, wrapper));
                }

                // initialize the feed
                string feedUrl             = string.Format("{0}/$syncTarget('{1}')", EndPoint, trackingId);
                string feedUrlWithoutQuery = (new Uri(feedUrl)).GetLeftPart(UriPartial.Path);   // the url without query

                // set id tag
                syncTargetFeed.Id = feedUrl;
                // set title tag
                syncTargetFeed.Title = string.Format("{0} synchronization target feed {1}", resourceKind.ToString(), trackingId);
                // set update
#warning  implement this
                //syncTargetFeed.Updated = DateTime.Now;
                // set syncMode
                syncTargetFeed.SyncMode = SyncMode.catchUp;

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


                #region PAGING & OPENSEARCH

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

                /* OPENSEARCH */
                syncTargetFeed.ItemsPerPage = normalizedPageInfo.Count;
                syncTargetFeed.StartIndex   = normalizedPageInfo.StartIndex;
                syncTargetFeed.TotalResults = transactinResults.Count;

                #endregion


                return(syncTargetFeed);
            }