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 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; }
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; }