private async Task LoadAsync() { var data = (IDictionary <string, string>) new Dictionary <string, string>(); try { if (!_elements.Any()) { return; } await using (var stream = new MemoryStream()) { await using (var sw = new StreamWriter(stream)) { using (var writer = new XmlNoNamespaceWriter(sw, new XmlWriterSettings { CloseOutput = false })) { foreach (var element in _elements) { element.Save(writer); } writer.Flush(); await sw.FlushAsync(); data = XmlStreamToDictionaryParser.Parse(stream, options => { options.IsIndexAttribute = (attribute, stack) => { switch (stack.FirstOrDefault()) { case "Endpoint": return(string.Equals(attribute, "Id", StringComparison.OrdinalIgnoreCase)); case "Route": return(string.Equals(attribute, "RouteId", StringComparison.OrdinalIgnoreCase)); } return(false); }; } ); } } } } finally { Data = data; } }
/// <summary> /// Gets the labels from the extensions of the provided raw service manifest. /// </summary> private async Task <IDictionary <string, string> > ExtractLabelsAsync( string rawServiceManifest, string targetServiceTypeName, CancellationToken cancellationToken) { using (var reader = XmlReader.Create(new StringReader(rawServiceManifest), CreateSafeXmlSetting(1024 * 1024, 1024))) { XDocument parsedManifest; try { parsedManifest = await XDocument.LoadAsync(reader, LoadOptions.None, cancellationToken); } catch (System.Xml.XmlException ex) { // TODO: we don't know if the service wants to use the gateway yet, so not sure if this classifies as config error (considering it will escalate into a bad health report) throw new ConfigException("Failed to parse service manifest XML.", ex); } var elements = parsedManifest .Elements(XNSServiceManifest + "ServiceManifest") .Elements(XNSServiceManifest + "ServiceTypes") .Elements().Where(s => (string)s.Attribute("ServiceTypeName") == targetServiceTypeName) .Elements(XNSServiceManifest + "Extensions") .Elements(XNSServiceManifest + "Extension").Where(s => (string)s.Attribute("Name") == ConfigurationValues.ExtensionName) .Elements(XNSFabricNoSchema + "Service"); if (!elements.Any()) { return(new Dictionary <string, string>()); } await using (var stream = new MemoryStream()) { await using (var sw = new StreamWriter(stream)) { using (var writer = new XmlNoNamespaceWriter(sw, new XmlWriterSettings { CloseOutput = false })) { foreach (var element in elements) { element.Save(writer); } writer.Flush(); await sw.FlushAsync(); var labels = XmlStreamToDictionaryParser.Parse(stream, (options) => { options.KeyDelimiter = "."; options.Parents = new List <string> { "Service" }; options.IsIndexAttribute = (attribute, stack) => { switch (stack.FirstOrDefault()) { case "Endpoint": return(string.Equals(attribute, "Id", StringComparison.OrdinalIgnoreCase)); case "Route": return(string.Equals(attribute, "Id", StringComparison.OrdinalIgnoreCase)); } return(false); }; }); return(labels); } } } } }
private async Task LoadServiceDataAsync(Dictionary <string, string> data, ApplicationWrapper application, string appPrefix, ServiceWrapper service, CancellationToken cancellationToken) { string serviceManifestName; try { serviceManifestName = await _serviceFabricCaller.GetServiceManifestName(application.ApplicationTypeName, application.ApplicationTypeVersion, service.ServiceTypeName, cancellationToken); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { throw; } catch (Exception ex) // TODO: davidni: not fatal? { throw new ServiceFabricIntegrationException( $"Failed to get service manifest name for service type {service.ServiceTypeName} of application type {application.ApplicationTypeName} {application.ApplicationTypeVersion} from Service Fabric: {ex}."); } if (serviceManifestName == null) { throw new ServiceFabricIntegrationException( $"No service manifest name was found for service type {service.ServiceTypeName} of application type {application.ApplicationTypeName} {application.ApplicationTypeVersion}."); } string rawServiceManifest; try { rawServiceManifest = await _serviceFabricCaller.GetServiceManifestAsync(application.ApplicationTypeName, application.ApplicationTypeVersion, serviceManifestName, cancellationToken); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { throw; } catch (Exception ex) // TODO: davidni: not fatal? { throw new ServiceFabricIntegrationException( $"Failed to get service manifest {serviceManifestName} of service type {service.ServiceTypeName} of application type {application.ApplicationTypeName} {application.ApplicationTypeVersion} from Service Fabric: {ex}."); } if (rawServiceManifest == null) { throw new ServiceFabricIntegrationException( $"No service manifest named '{serviceManifestName}' was found for service type {service.ServiceTypeName} of application type {application.ApplicationTypeName} {application.ApplicationTypeVersion}."); } using (var reader = XmlReader.Create(new StringReader(rawServiceManifest), XmlReaderHelper.CreateSafeXmlSetting())) { XDocument parsedManifest; try { parsedManifest = await XDocument.LoadAsync(reader, LoadOptions.None, cancellationToken); } catch (System.Xml.XmlException ex) { // TODO: we don't know if the service wants to use the gateway yet, so not sure if this classifies as config error (considering it will escalate into a bad health report) throw new ConfigException("Failed to parse service manifest XML.", ex); } var elements = parsedManifest .Elements(XmlReaderHelper.XNSServiceManifest + "ServiceManifest") .Elements(XmlReaderHelper.XNSServiceManifest + "ServiceTypes") .Elements().Where(s => (string)s.Attribute("ServiceTypeName") == service.ServiceTypeName) .Elements(XmlReaderHelper.XNSServiceManifest + "Extensions") .Elements(XmlReaderHelper.XNSServiceManifest + "Extension").Where(s => (string)s.Attribute("Name") == ConfigurationValues.ExtensionName) .Elements(XmlReaderHelper.XNSFabricNoSchema + "Service"); if (!elements.Any()) { return; } var serviceId = service.ServiceName.ToString().Replace($"{application.ApplicationName}/", string.Empty); var servicePrefix = $"{appPrefix}Services{ConfigurationPath.KeyDelimiter}{serviceId}{ConfigurationPath.KeyDelimiter}"; data[$"{servicePrefix}Id"] = serviceId; data[$"{servicePrefix}Name"] = service.ServiceName.ToString(); data[$"{servicePrefix}TypeName"] = service.ServiceTypeName; data[$"{servicePrefix}Kind"] = service.ServiceKind.ToString(); data[$"{servicePrefix}ManifestVersion"] = service.ServiceManifestVersion; await using (var stream = new MemoryStream()) { await using (var sw = new StreamWriter(stream)) { using (var writer = new XmlNoNamespaceWriter(sw, new XmlWriterSettings { CloseOutput = false })) { foreach (var element in elements) { element.Save(writer); } writer.Flush(); await sw.FlushAsync(); var sections = XmlStreamToDictionaryParser.Parse(stream, (options) => { options.KeyDelimiter = ConfigurationPath.KeyDelimiter; options.Parents = new List <string>(servicePrefix.Split(ConfigurationPath.KeyDelimiter, StringSplitOptions.RemoveEmptyEntries)); options.IsIndexAttribute = (attribute, stack) => { switch (stack.FirstOrDefault()) { case "Endpoint": return(string.Equals(attribute, "Id", StringComparison.OrdinalIgnoreCase)); case "Route": return(string.Equals(attribute, "Id", StringComparison.OrdinalIgnoreCase)); } return(false); }; }); foreach (var section in sections) { data[section.Key] = section.Value; } } } } } }