diff --git a/src/Stars.Services/Model/Atom/AtomRouter.cs b/src/Stars.Services/Model/Atom/AtomRouter.cs index d7474324..c13396fb 100644 --- a/src/Stars.Services/Model/Atom/AtomRouter.cs +++ b/src/Stars.Services/Model/Atom/AtomRouter.cs @@ -13,6 +13,9 @@ using Terradue.Stars.Services.Supplier; using System.IO; using System.Threading; +using Terradue.OpenSearch; +using System.Xml.Serialization; +using Terradue.OpenSearch.Schema; namespace Terradue.Stars.Services.Model.Atom { @@ -22,6 +25,8 @@ public class AtomRouter : IRouter private static string[] supportedTypes = new string[] { "application/atom+xml", "application/xml", "text/xml" }; + private static string opensearchDescriptionType = "application/opensearchdescription+xml"; + private readonly IResourceServiceProvider resourceServiceProvider; public AtomRouter(IResourceServiceProvider resourceServiceProvider) @@ -63,6 +68,17 @@ private async Task AffineRouteAsync(IResource route, CancellationToke { return route; } + if (route.ContentType.MediaType == opensearchDescriptionType && route is IStreamResource streamResource) + { + XmlSerializer xmlSerializer = new XmlSerializer(typeof(OpenSearchDescription)); + var openSearchDescription = (OpenSearchDescription)xmlSerializer.Deserialize(XmlReader.Create(await streamResource.GetStreamAsync(ct))); + var url = openSearchDescription.Url.FirstOrDefault(u => supportedTypes.Contains(u.Type)); + if (url != null) + { + OpenSearchUrl searchUri = OpenSearchFactory.BuildRequestUrlFromTemplate(url, new System.Collections.Specialized.NameValueCollection(), new QuerySettings(url.Type, null)); + return await resourceServiceProvider.CreateStreamResourceAsync(new GenericResource(searchUri), ct); + } + } IResource newRoute = await resourceServiceProvider.CreateStreamResourceAsync(new GenericResource(new Uri(route.Uri.ToString())), ct); return newRoute; } @@ -105,7 +121,7 @@ public async Task FetchResourceAsync(IResource node, Cancellati public async Task RouteLinkAsync(IResource resource, IResourceLink childLink, CancellationToken ct) { - if (!(resource is AtomFeedCatalog) + if (!(resource is AtomFeedCatalog) && !(resource is AtomItemNode)) { throw new Exception("Cannot route link from non-atom resource");