public EntityWrapperBase(RequestContext context, SupportedResourceKinds resourceKind) { _context = context; _resourceKind = resourceKind; _emptyToken = new Token(); _correlatedResSyncInfoStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); }
public EntityWrapperBase(RequestContext context, SupportedResourceKinds resourceKind) { _context = context; _resourceKind = resourceKind; _emptyToken = new Token(); _correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); }
public TransformationBase(RequestContext context, SupportedResourceKinds resourceKind) { _context = context; _datasetLink = _context.DatasetLink; _config = _context.Config; _resourceKind = resourceKind; _resourceKindString = _resourceKind.ToString(); _originApplication = _datasetLink + _resourceKindString; _correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); }
public TransformationBase(RequestContext context, SupportedResourceKinds resourceKind) { _context = context; _datasetLink = _context.DatasetLink; _config = _context.Config; _resourceKind = resourceKind; _resourceKindString = _resourceKind.ToString(); _originApplication = _datasetLink + _resourceKindString; _correlatedResSyncInfoStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); }
private void CheckExisting(ICorrelatedResSyncInfoStore correlatedResSyncInfoStore, string localId) { CorrelatedResSyncInfo[] existingCorrelations = correlatedResSyncInfoStore.GetByLocalId(_requestContext.ResourceKind.ToString(), new string[] { localId }); if (existingCorrelations.Length > 0) { StringBuilder b = new StringBuilder(existingCorrelations.Length + " correlations for " + localId + " already exist ( "); foreach (CorrelatedResSyncInfo existingCorrelation in existingCorrelations) { b.Append(existingCorrelation.ResSyncInfo.Uuid); b.Append(" "); } b.Append(")"); throw new RequestException(b.ToString()); } }
public void DoWork(IRequest request) { if (String.IsNullOrEmpty(_requestContext.ResourceKey)) { throw new RequestException("Please use a uuid predicate."); } // TODO: Check resourceKind for value None??? Guid uuid = (Guid)TypeDescriptor.GetConverter(typeof(Guid)).ConvertFrom(_requestContext.ResourceKey); string resourceKind = _requestContext.ResourceKind.ToString(); ICorrelatedResSyncInfoStore correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext); correlatedResSyncInfoStore.Delete(resourceKind, uuid); }
public void GetTrackingState(IRequest request) { lock (_asyncStateObj) { if (null == _asyncStateObj.Tracking) { throw new InvalidOperationException("Performer has not been started."); } if (_asyncStateObj.Tracking.Phase == TrackingPhase.FINISH) { request.Response.ContentType = MediaType.Atom; int startindex = Convert.ToInt32(request.Uri.StartIndex); int count = Convert.ToInt32(request.Uri.Count); SdataContext sdataContext = _requestContext.SdataContext; ICorrelatedResSyncInfoStore correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(sdataContext); request.Response.Serializer = new SyncFeedSerializer(); SyncFeed syncFeed = _asyncPerformer.GetFeed(_requestContext.Config, startindex, count); syncFeed.FeedType = FeedType.SyncSource; request.Response.Feed = syncFeed; } else if (_asyncStateObj.Tracking.Phase == TrackingPhase.ERROR) { request.Response.Xml = XmlSerializationHelpers.SerializeObjectToXml(_asyncStateObj.Tracking); request.Response.ContentType = MediaType.Xml; request.Response.StatusCode = HttpStatusCode.InternalServerError; request.Response.Serializer = new XmlSerializer(); request.Response.Protocol.SendUnknownResponseHeader("location", String.Format("{0}{1}/$syncSource('{2}')", _requestContext.DatasetLink, _requestContext.ResourceKind.ToString(), _requestContext.TrackingId)); } else { request.Response.Xml = XmlSerializationHelpers.SerializeObjectToXml(_asyncStateObj.Tracking); request.Response.ContentType = MediaType.Xml; request.Response.StatusCode = HttpStatusCode.Accepted; request.Response.Serializer = new XmlSerializer(); request.Response.Protocol.SendUnknownResponseHeader("location", String.Format("{0}{1}/$syncSource('{2}')", _requestContext.DatasetLink, _requestContext.ResourceKind.ToString(), _requestContext.TrackingId)); } } }
public override SyncFeed GetFeed() { bool includeUuid; string whereClause = string.Empty; OleDbParameter[] oleDbParameters = null; if (this is IEntityQueryWrapper) { QueryFilterBuilder queryFilterBuilder = new QueryFilterBuilder((IEntityQueryWrapper)this); queryFilterBuilder.BuildSqlStatement(_context, out whereClause, out oleDbParameters); } SyncFeed feed = new SyncFeed(); feed.Title = _resourceKind.ToString() + ": " + DateTime.Now.ToString(); Token emptyToken = new Token(); List <Identity> identities = new List <Identity>(); if (String.IsNullOrEmpty(_context.ResourceKey)) { identities = _entity.GetAll(_context.Config, whereClause, oleDbParameters); } else { identities.Add(new Identity(_entity.EntityName, _context.ResourceKey)); } int totalResult = identities.Count; #region PAGING & OPENSEARCH /* PAGING */ feed.Links = FeedMetadataHelpers.CreatePageFeedLinks(_context, totalResult, FeedMetadataHelpers.RequestKeywordType.none); /* OPENSEARCH */ PageController pageController = FeedMetadataHelpers.GetPageLinkBuilder(_context, totalResult, FeedMetadataHelpers.RequestKeywordType.none); feed.Opensearch_ItemsPerPageElement = pageController.GetOpensearch_ItemsPerPageElement(); feed.Opensearch_StartIndexElement = pageController.GetOpensearch_StartIndexElement(); feed.Opensearch_TotalResultsElement = pageController.GetOpensearch_TotalResultsElement(); #endregion feed.Id = _context.SdataUri.ToString(); string tmpValue; // ?includeUuid includeUuid = false; // default value, but check for settings now if (_context.SdataUri.QueryArgs.TryGetValue("includeUuid", out tmpValue)) { includeUuid = System.Xml.XmlConvert.ToBoolean(tmpValue); } ICorrelatedResSyncInfoStore correlatedResSyncStore = null; if (includeUuid) { // get store to request the correlations correlatedResSyncStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); } for (int pageIndex = pageController.StartIndex; pageIndex <= pageController.LastIndex; pageIndex++) //for (int index = startIndex; index < startIndex + count; index++) { int zeroBasedIndex = pageIndex - 1; Identity identity = identities[zeroBasedIndex]; AccountDocument accountDocument = (AccountDocument)_entity.GetDocument(identity, emptyToken, _context.Config); if (accountDocument.LogState == LogState.Deleted) { continue; } SyncFeedEntry entry = new SyncFeedEntry(); if (accountDocument.addresses.documents.Count == 0) { return(null); } entry.Id = String.Format("{0}{1}('{2}')", _context.DatasetLink, _resourceKind.ToString(), identity.Id); entry.Title = String.Format("{0}: {1}", _resourceKind.ToString(), identity.Id); entry.Updated = DateTime.Now; if (_context.SdataUri.Precedence == null) { List <SyncFeedEntryLink> links; Document document = accountDocument.addresses.documents[0]; entry.Payload = GetTransformedPayload(document, out links); string taUuid = GetTradingAccountUuid(accountDocument.Id); if (!String.IsNullOrEmpty(taUuid)) { SyncFeedEntryLink tradingAccountLink = SyncFeedEntryLink.CreateRelatedLink( String.Format("{0}{1}('{2}')", _context.DatasetLink, SupportedResourceKinds.tradingAccounts.ToString(), accountDocument.Id), SupportedResourceKinds.tradingAccounts.ToString(), _tradingAccountUuidPayloadPath, taUuid); links.Add(tradingAccountLink); } entry.SyncLinks = links; } if (includeUuid) { CorrelatedResSyncInfo[] infos = correlatedResSyncStore.GetByLocalId(_context.ResourceKind.ToString(), new string[] { identity.Id }); entry.Uuid = (infos.Length > 0) ? infos[0].ResSyncInfo.Uuid : Guid.Empty; } if (entry != null) { feed.Entries.Add(entry); } } return(feed); }
public void DoWork(IRequest request) { // only atom entry supported!!! if (request.ContentType != Sage.Common.Syndication.MediaType.AtomEntry) { throw new RequestException("Atom entry content type expected"); } // deserialize the request stream to a SyncFeedEntry SyncFeedEntry entry = new SyncFeedEntry(); XmlReader reader = XmlReader.Create(request.Stream); reader.MoveToContent(); entry.ReadXml(reader, typeof(SyncDigestPayload)); if (null == entry.Linked) { throw new RequestException("Invalid content: element 'linked' missing"); } // We check for equality of the urls of the request url and // in the linked element up to the resourceKind. string requestEndpointUrl = _requestContext.OriginEndPoint; RequestContext entryResourceAsRequestContext = new RequestContext(new Sage.Common.Syndication.SDataUri(entry.Linked.Resource)); // 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(); Guid currentUuid = (Guid)TypeDescriptor.GetConverter(typeof(Guid)).ConvertFrom(_requestContext.ResourceKey); Guid newUuid = entry.Linked.Uuid; string newLocalId = entryResourceAsRequestContext.SdataUri.CollectionPredicate; // update the correlation entry in the sync store. // if the uuid should be updated we have to remove the current correlation and then add a new one. // otherwise we update the current correlation. ICorrelatedResSyncInfoStore correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext); // create the target correlation ResSyncInfo targetResSyncInfo = new ResSyncInfo(newUuid, requestEndpointUrl, 0, string.Empty, DateTime.Now); CorrelatedResSyncInfo targetInfo = new CorrelatedResSyncInfo(newLocalId, targetResSyncInfo); if (currentUuid == newUuid) { correlatedResSyncInfoStore.Update(resourceKindName, targetInfo); } else { correlatedResSyncInfoStore.Delete(resourceKindName, currentUuid); correlatedResSyncInfoStore.Add(resourceKindName, targetInfo); } // create response SyncFeed feed = new SyncFeed(); feed.FeedType = FeedType.LinkedSingle; // create entry SyncFeedEntry responseEntry = new SyncFeedEntry(); responseEntry.Id = FeedMetadataHelpers.BuildLinkedEntryUrl(_requestContext, targetInfo.ResSyncInfo.Uuid); responseEntry.Title = FeedMetadataHelpers.BuildLinkedEntryTitle(_requestContext, targetInfo.ResSyncInfo.Uuid); LinkedElement linkedElement = new LinkedElement(); linkedElement.Resource = FeedMetadataHelpers.BuildEntryResourceUrl(_requestContext, targetInfo.LocalId); linkedElement.Uuid = targetInfo.ResSyncInfo.Uuid; responseEntry.Linked = linkedElement; feed.Entries.Add(responseEntry); request.Response.Serializer = new SyncFeedSerializer(); request.Response.Feed = (IFeed)feed; request.Response.ContentType = MediaType.AtomEntry; }
private CommodityIdentity[] GetCommodityIds(ComputePriceRequestFeedEntry payloadContainer) { List <CommodityIdentity> identities = new List <CommodityIdentity>(); // The commodities are situated under the pricing document lines. // The commodities are linked resources. That means that the schema provides a sme:relationship="reference" // on the commodity schema node. // Example: (<xs:element sme:label="Commodity" name="commodity" type="commodity--type" sme:relationship="reference" minOccurs="0" maxOccurs="1" sme:mandatory="true" >) // // The commodity payload is an empty payload providing all or some sdata attributes as follows: // url, key, uuid, lookup, descriptor. // // To be able to receive commodity data we need the local commodity ids. // So we iterate through all line items of the given entry and read the commodity payload attributes. // Dependent on the existence of the attributes an id can be requested in 3 ways: // 1. Using attribute key (MS: SHOULD or MUST exist??? cannot find compliance info) // 2. Parsing attribute url (MS: SHOULD or MUST exist??? cannot find compliance info) // 3. Using the uuid attribute and using the correlation repository. int noOfLines; // The number of line items CommodityFeedEntry tmpCommodityPayload; noOfLines = payloadContainer.pricingDocumentLines.Entries.Count; for (int i = 0; i < noOfLines; i++) { tmpCommodityPayload = payloadContainer.pricingDocumentLines.Entries[i].commodity; if (null == tmpCommodityPayload) { throw new RequestException(string.Format("Failed to parse feed. Commodity payload missing in pricing document lines[{0}].", i)); } if (!string.IsNullOrEmpty(tmpCommodityPayload.Key)) { identities.Add(new CommodityIdentity(tmpCommodityPayload.Key)); continue; } if (!string.IsNullOrEmpty(tmpCommodityPayload.Uri)) { if (tmpCommodityPayload.Uri.StartsWith(_context.DatasetLink + SupportedResourceKinds.commodities.ToString())) { RequestContext tmpRequestContext = new RequestContext(new SDataUri(tmpCommodityPayload.Uri)); if (tmpRequestContext.RequestType == RequestType.Resource) { identities.Add(new CommodityIdentity(tmpRequestContext.ResourceKey)); continue; // continue iteration (parse next line item) } } } if (tmpCommodityPayload.UUID != null && Guid.Empty != tmpCommodityPayload.UUID) { Guid uuid = tmpCommodityPayload.UUID; // get the local id using synch correlation (linking) ICorrelatedResSyncInfoStore correlationStore = NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_context.SdataContext); CorrelatedResSyncInfo[] correlations = correlationStore.GetByUuid(SupportedResourceKinds.commodities.ToString(), new Guid[] { uuid }); if (correlations.Length == 1) { identities.Add(new CommodityIdentity(correlations[0].LocalId)); continue; // continue iteration (parse next line item) } } // Add an empty CommodityIdentity if everything failed. identities.Add(CommodityIdentity.Empty); } return(identities.ToArray()); }
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)); }
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; }
private CommodityIdentity[] GetCommodityIds(SyncFeedEntry requestEntry) { List <CommodityIdentity> identities = new List <CommodityIdentity>(); // To be able to receive commodity data we need the local commodity ids. // These ids can be requested in 2 ways: // 1a) Using reference link: If attribute 'href' is a valid url of this adapter and has a resource key we can use the given resourceKey. // 1b) Using reference link: Otherwise we use the attribute 'uuid' and use the correlation repository. // 2) Using the value contained in line property 'uuid' and using the correlation repository. // If 1) and 2) do not succeed we add an empty object. ComputePriceRequestPayload payload = (ComputePriceRequestPayload)requestEntry.Payload; int noOflines = payload.ComputePriceRequest.pricingDocumentLines.Length; for (int i = 0; i < noOflines; i++) { string payloadPath = string.Format("computePrice/pricingDocumentLines[{0}]/commodity", i); SyncFeedEntryLink feedLink = Helper.FindLinkByPayloadPath(requestEntry.SyncLinks.ToArray(), payloadPath); //if (null == feedLink) // throw new RequestException(string.Format("Link for payloadPath '{0}' missing", payloadPath)); if (null != feedLink) { // validate string strRel = SyncFeedEntryLink.GetRelString(Sage.Integration.Northwind.Feeds.RelEnum.related); if (feedLink.LinkRel != strRel) { throw new RequestException(string.Format("Parsing link with payloadPath '{0}' failed: Attribute 'rel' must contain value '{1}'.", payloadPath, strRel)); } // TODO: excluded because condition linktype could have valid space character and we cannot check this in a simple way. //string strType = SyncFeedEntryLink.GetTypeString(Sage.Integration.Northwind.Feeds.LinkTypeEnum.entry); //if (feedLink.LinkType != strType) // throw new RequestException(string.Format("Parsing link with payloadPath '{0}' failed: Invalid media type defined in attribute 'type'. Value '{1}' expected.", payloadPath, strType)); string url = feedLink.Href; // 1a) Try to parse href if (url.StartsWith(_requestContext.DatasetLink + SupportedResourceKinds.commodities.ToString())) { RequestContext tmpRequestContext = new RequestContext(new SDataUri(url)); if (tmpRequestContext.RequestType == RequestType.Resource) { identities.Add(new CommodityIdentity(tmpRequestContext.ResourceKey)); continue; // continue iteration (parse next line item) } } // 1b) Try to get uuid from link and to get the local id using synch correlation (linking) if (!string.IsNullOrEmpty(feedLink.Uuid)) { Guid uuid = (Guid)TypeDescriptor.GetConverter(typeof(Guid)).ConvertFrom(feedLink.Uuid); ICorrelatedResSyncInfoStore correlationStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext); CorrelatedResSyncInfo[] correlations = correlationStore.GetByUuid(SupportedResourceKinds.commodities.ToString(), new Guid[] { uuid }); if (correlations.Length == 1) { identities.Add(new CommodityIdentity(correlations[0].LocalId)); continue; // continue iteration (parse next line item) } } } else { // 2) Try to get uuid from property named 'uuid' string strLineUuid = payload.ComputePriceRequest.pricingDocumentLines[i].uuid; if (!string.IsNullOrEmpty(strLineUuid)) { Guid uuid = (Guid)TypeDescriptor.GetConverter(typeof(Guid)).ConvertFrom(strLineUuid); // get the local id using synch correlation (linking) ICorrelatedResSyncInfoStore correlationStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext); CorrelatedResSyncInfo[] correlations = correlationStore.GetByUuid(SupportedResourceKinds.commodities.ToString(), new Guid[] { uuid }); if (correlations.Length == 1) { identities.Add(new CommodityIdentity(correlations[0].LocalId)); continue; // continue iteration (parse next line item) } } } // If 1) and 2) failed add an empty CommodityIdentity identities.Add(CommodityIdentity.Empty); } return(identities.ToArray()); }
public void DoWork(IRequest request) { // only atom entry supported!!! if (request.ContentType != Sage.Common.Syndication.MediaType.AtomEntry) { throw new RequestException("Atom entry content type expected"); } // deserialize the request stream to a SyncFeedEntry SyncFeedEntry entry = new SyncFeedEntry(); XmlReader reader = XmlReader.Create(request.Stream); reader.MoveToContent(); entry.ReadXml(reader, typeof(SyncDigestPayload)); if (null == entry.Linked) { throw new RequestException("Invalid content: element 'linked' missing"); } // Parse the resource url 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. string requestEndpointUrl = _requestContext.OriginEndPoint; RequestContext entryResourceAsRequestContext = new RequestContext(new Sage.Common.Syndication.SDataUri(entry.Linked.Resource)); // 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(); string localId = entryResourceAsRequestContext.SdataUri.CollectionPredicate; Guid uuid = entry.Linked.Uuid; // store a new correlation entry to the sync store ICorrelatedResSyncInfoStore correlatedResSyncInfoStore = RequestReceiver.NorthwindAdapter.StoreLocator.GetCorrelatedResSyncStore(_requestContext.SdataContext); ResSyncInfo newResSyncInfo = new ResSyncInfo(uuid, requestEndpointUrl, 0, string.Empty, DateTime.Now); CorrelatedResSyncInfo newInfo = new CorrelatedResSyncInfo(localId, newResSyncInfo); correlatedResSyncInfoStore.Add(resourceKindName, newInfo); // Set the response values SyncFeed feed = new SyncFeed(); feed.FeedType = FeedType.LinkedSingle; SyncFeedEntry feedEntry = new SyncFeedEntry(); feedEntry.Title = FeedMetadataHelpers.BuildLinkedEntryTitle(_requestContext, uuid); feedEntry.Id = FeedMetadataHelpers.BuildLinkedEntryUrl(_requestContext, uuid); feedEntry.Updated = newInfo.ResSyncInfo.ModifiedStamp; feedEntry.Published = newInfo.ResSyncInfo.ModifiedStamp; feedEntry.Linked = entry.Linked; feed.Entries.Add(feedEntry); request.Response.Serializer = new SyncFeedSerializer(); request.Response.Feed = (IFeed)feed; request.Response.ContentType = MediaType.AtomEntry; request.Response.StatusCode = System.Net.HttpStatusCode.Created; request.Response.Protocol.SendUnknownResponseHeader("location", FeedMetadataHelpers.BuildLinkedEntryUrl(_requestContext, uuid)); }