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