protected string GetLocalId(Guid uuid) { CorrelatedResSyncInfo[] results = _correlatedResSyncInfoStore.GetByUuid(_resourceKindString, new Guid[] { uuid }); if (results.Length > 0) { return(results[0].LocalId); } return(null); }
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(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()); }
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()); }