コード例 #1
0
        private async Task <bool> IsFormatSupportedAsync(ResourceFormat resourceFormat)
        {
            if (_supportedFormats.TryGetValue(resourceFormat, out var isSupported))
            {
                return(isSupported);
            }

            var typedStatement = await _conformanceProvider.GetCapabilityStatementAsync();

            CapabilityStatement statement = typedStatement.ToPoco <CapabilityStatement>();

            return(_supportedFormats.GetOrAdd(resourceFormat, format =>
            {
                switch (resourceFormat)
                {
                case ResourceFormat.Json:
                    return statement.Format.Any(f => f.Contains("json", StringComparison.Ordinal));

                case ResourceFormat.Xml:
                    return statement.Format.Any(f => f.Contains("xml", StringComparison.Ordinal));

                default:
                    return false;
                }
            }));
        }
コード例 #2
0
        public override async Task <CapabilityStatement> GetCapabilityStatementAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (_capabilityStatement == null)
            {
                await _sem.WaitAsync(cancellationToken);

                try
                {
                    if (_capabilityStatement == null)
                    {
                        var generated =
                            await _systemConformance.GetSystemListedCapabilitiesStatementAsync(cancellationToken);

                        var configured =
                            await _configuredConformanceProvider.GetCapabilityStatementAsync(cancellationToken);

                        _capabilityStatement =
                            generated.Intersect(configured, _conformanceConfiguration.UseStrictConformance);

                        _capabilityStatement.UrlElement = new FhirUri(_urlResolver.ResolveMetadataUrl(false));
                    }
                }
                finally
                {
                    _sem.Release();
                }
            }

            return(_capabilityStatement);
        }
コード例 #3
0
        public static CapabilityStatement AddOperationDefinition(this CapabilityStatement conformance, IEnumerable <IFhirService> services, Microsoft.AspNetCore.Http.HttpRequest request)
        {
            var operationComponents = new List <CapabilityStatement.OperationComponent>();

            foreach (var service in services)
            {
                var queryService        = service;
                var operationDefinition = queryService?.GetOperationDefinition(request);
                if (!string.IsNullOrEmpty(operationDefinition?.Url))
                {
                    operationComponents.Add(new CapabilityStatement.OperationComponent
                    {
                        Name = operationDefinition.Name,
                        DefinitionElement = new Canonical {
                            Value = operationDefinition.Url
                        }
                    });
                }
            }
            if (operationComponents.Count > 0)
            {
                conformance.Server().Operation.AddRange(operationComponents);
            }
            return(conformance);
        }
コード例 #4
0
        private async Task TestCapabilityStatementFhirVersion(string expectedVersion)
        {
            CapabilityStatement capabilityStatement = await _client.ReadAsync <CapabilityStatement>("metadata");

            Assert.NotNull(capabilityStatement.FhirVersionElement);
            Assert.Equal(expectedVersion, capabilityStatement.FhirVersionElement.ObjectValue);
        }
コード例 #5
0
        public static CapabilityStatement AddOperationDefintion(this CapabilityStatement conformance, IEnumerable <IFhirService> services)
        {
            var operationComponents = new List <CapabilityStatement.OperationComponent>();

            foreach (var service in services)
            {
                var queryService       = service;
                var operationDefintion = queryService?.GetOperationDefinition();
                if (!string.IsNullOrEmpty(operationDefintion?.Url))
                {
                    operationComponents.Add(new CapabilityStatement.OperationComponent
                    {
                        Name       = operationDefintion.Name,
                        Definition = new ResourceReference {
                            Reference = operationDefintion.Url
                        }
                    });
                }
            }
            if (operationComponents.Count > 0)
            {
                conformance.Server().Operation.AddRange(operationComponents);
            }
            return(conformance);
        }
コード例 #6
0
        public ResourceHandlerTests()
        {
            _fhirDataStore       = Substitute.For <IFhirDataStore>();
            _conformanceProvider = Substitute.For <ConformanceProviderBase>();
            _searchService       = Substitute.For <ISearchService>();

            // TODO: FhirRepository instantiate ResourceDeserializer class directly
            // which will try to deserialize the raw resource. We should mock it as well.
            _rawResourceFactory     = Substitute.For <RawResourceFactory>(new FhirJsonSerializer());
            _resourceWrapperFactory = Substitute.For <IResourceWrapperFactory>();
            _resourceWrapperFactory
            .Create(Arg.Any <ResourceElement>(), Arg.Any <bool>(), Arg.Any <bool>())
            .Returns(x => CreateResourceWrapper(x.ArgAt <ResourceElement>(0), x.ArgAt <bool>(1)));

            _conformanceStatement = CapabilityStatementMock.GetMockedCapabilityStatement();
            CapabilityStatementMock.SetupMockResource(_conformanceStatement, ResourceType.Observation, null);
            var observationResource = _conformanceStatement.Rest.First().Resource.Find(x => x.Type == ResourceType.Observation);

            observationResource.ReadHistory       = false;
            observationResource.UpdateCreate      = true;
            observationResource.ConditionalCreate = true;
            observationResource.ConditionalUpdate = true;
            observationResource.Versioning        = CapabilityStatement.ResourceVersionPolicy.Versioned;

            CapabilityStatementMock.SetupMockResource(_conformanceStatement, ResourceType.Patient, null);
            var patientResource = _conformanceStatement.Rest.First().Resource.Find(x => x.Type == ResourceType.Patient);

            patientResource.ReadHistory       = true;
            patientResource.UpdateCreate      = true;
            patientResource.ConditionalCreate = true;
            patientResource.ConditionalUpdate = true;
            patientResource.Versioning        = CapabilityStatement.ResourceVersionPolicy.VersionedUpdate;

            _conformanceProvider.GetCapabilityStatementOnStartup().Returns(_conformanceStatement.ToTypedElement().ToResourceElement());
            var lazyConformanceProvider = new Lazy <IConformanceProvider>(() => _conformanceProvider);

            var collection = new ServiceCollection();

            // an auth service that allows all.
            _authorizationService = Substitute.For <IAuthorizationService <DataActions> >();
            _authorizationService.CheckAccess(Arg.Any <DataActions>(), Arg.Any <CancellationToken>()).Returns(ci => ci.Arg <DataActions>());

            var referenceResolver = new ResourceReferenceResolver(_searchService, new TestQueryStringParser());

            _resourceIdProvider = new ResourceIdProvider();
            collection.Add(x => _mediator).Singleton().AsSelf();
            collection.Add(x => new CreateResourceHandler(_fhirDataStore, lazyConformanceProvider, _resourceWrapperFactory, _resourceIdProvider, referenceResolver, _authorizationService)).Singleton().AsSelf().AsImplementedInterfaces();
            collection.Add(x => new UpsertResourceHandler(_fhirDataStore, lazyConformanceProvider, _resourceWrapperFactory, _resourceIdProvider, _authorizationService, ModelInfoProvider.Instance)).Singleton().AsSelf().AsImplementedInterfaces();
            collection.Add(x => new ConditionalCreateResourceHandler(_fhirDataStore, lazyConformanceProvider, _resourceWrapperFactory, _searchService, x.GetService <IMediator>(), _resourceIdProvider, _authorizationService)).Singleton().AsSelf().AsImplementedInterfaces();
            collection.Add(x => new ConditionalUpsertResourceHandler(_fhirDataStore, lazyConformanceProvider, _resourceWrapperFactory, _searchService, x.GetService <IMediator>(), _resourceIdProvider, _authorizationService)).Singleton().AsSelf().AsImplementedInterfaces();
            collection.Add(x => new GetResourceHandler(_fhirDataStore, lazyConformanceProvider, _resourceWrapperFactory, _resourceIdProvider, _authorizationService)).Singleton().AsSelf().AsImplementedInterfaces();
            collection.Add(x => new DeleteResourceHandler(_fhirDataStore, lazyConformanceProvider, _resourceWrapperFactory, _resourceIdProvider, _authorizationService)).Singleton().AsSelf().AsImplementedInterfaces();

            ServiceProvider provider = collection.BuildServiceProvider();

            _mediator = new Mediator(type => provider.GetService(type));

            _deserializer = new ResourceDeserializer(
                (FhirResourceFormat.Json, new Func <string, string, DateTimeOffset, ResourceElement>((str, version, lastUpdated) => _fhirJsonParser.Parse(str).ToResourceElement())));
        }
コード例 #7
0
        public FhirRepositoryTests()
        {
            _dataStore           = Substitute.For <IDataStore>();
            _conformanceProvider = Substitute.For <ConformanceProviderBase>();

            // TODO: FhirRepository instantiate ResourceDeserializer class directly
            // which will try to deserialize the raw resource. We should mock it as well.
            _rawResourceFactory     = Substitute.For <RawResourceFactory>(new FhirJsonSerializer());
            _resourceWrapperFactory = Substitute.For <IResourceWrapperFactory>();
            _resourceWrapperFactory
            .Create(Arg.Any <Resource>(), Arg.Any <bool>())
            .Returns(x => CreateResourceWrapper(x.ArgAt <Resource>(0), x.ArgAt <bool>(1)));

            _conformanceStatement = CapabilityStatementMock.GetMockedCapabilityStatement();
            CapabilityStatementMock.SetupMockResource(_conformanceStatement, ResourceType.Observation, null);
            var observationResource = _conformanceStatement.Rest.First().Resource.Find(x => x.Type == ResourceType.Observation);

            observationResource.ReadHistory  = false;
            observationResource.UpdateCreate = true;
            observationResource.Versioning   = CapabilityStatement.ResourceVersionPolicy.Versioned;

            CapabilityStatementMock.SetupMockResource(_conformanceStatement, ResourceType.Patient, null);
            var patientResource = _conformanceStatement.Rest.First().Resource.Find(x => x.Type == ResourceType.Patient);

            patientResource.ReadHistory  = true;
            patientResource.UpdateCreate = true;
            patientResource.Versioning   = CapabilityStatement.ResourceVersionPolicy.VersionedUpdate;

            _conformanceProvider.GetCapabilityStatementAsync().Returns(_conformanceStatement);
            _repository = new FhirRepository(_dataStore, new Lazy <IConformanceProvider>(() => _conformanceProvider), _resourceWrapperFactory);
        }
コード例 #8
0
        public static CapabilityStatement.RestComponent Server(this CapabilityStatement capabilityStatement)
        {
            var server =
                capabilityStatement.Rest.FirstOrDefault(r => r.Mode == CapabilityStatement.RestfulCapabilityMode.Server);

            return(server ?? capabilityStatement.AddRestComponent(true));
        }
コード例 #9
0
ファイル: CdrService.cs プロジェクト: HelloGao1/StudyGitHub
        public CapabilityStatement GetConformance(ModelBaseInputs request, SummaryType summary)
        {
            CapabilityStatement con = new CapabilityStatement
            {
                Url           = request.BaseUri + "metadata",
                Description   = new Markdown("CDR based FHIR server"),
                DateElement   = new Hl7.Fhir.Model.FhirDateTime("2017-04-30"),
                Version       = "1.0.0.0",
                Name          = "CDR FHIR API",
                Experimental  = true,
                Status        = PublicationStatus.Active,
                FhirVersion   = Hl7.Fhir.Model.ModelInfo.Version,
                AcceptUnknown = CapabilityStatement.UnknownContentCode.Extensions,
                Format        = new string[] { "xml", "json" },
                Kind          = CapabilityStatement.CapabilityStatementKind.Instance,
                Meta          = new Meta()
            };

            con.Meta.LastUpdatedElement = Instant.Now();

            con.Rest = new List <CapabilityStatement.RestComponent>()
            {
                new CapabilityStatement.RestComponent
                {
                    Mode      = CapabilityStatement.RestfulCapabilityMode.Server,
                    Resource  = new List <CapabilityStatement.ResourceComponent>(),
                    Operation = new List <CapabilityStatement.OperationComponent>(),
                    Security  = new CapabilityStatement.SecurityComponent
                    {
                        Extension = new List <Extension>()
                        {
                            new Extension()
                            {
                                Url       = "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris",
                                Extension = new List <Extension>()
                                {
                                    new Extension
                                    {
                                        Url   = "token",
                                        Value = new FhirString("https://teams-fhir-auth.dapasoft.com/connect/token")
                                    },
                                    new Extension
                                    {
                                        Url   = "authorize",
                                        Value = new FhirString("https://teams-fhir-auth.dapasoft.com/connect/authorize")
                                    }
                                }
                            }
                        }
                    }
                }
            };
            //foreach (var model in ModelFactory.GetAllModels(GetInputs(buri)))
            //{
            //    con.Rest[0].Resource.Add(model.GetRestResourceComponent());
            //}

            return(con);
        }
コード例 #10
0
        public static CapabilityStatement AddSearchSetInteraction(this CapabilityStatement conformance)
        {
            var searchSet = CapabilityStatement.SystemRestfulInteraction.SearchSystem;

            conformance.AddSystemInteraction(searchSet);

            return(conformance);
        }
コード例 #11
0
        public async Task <bool> SatisfiesAsync(IEnumerable <CapabilityQuery> queries, CancellationToken cancellationToken = default(CancellationToken))
        {
            EnsureArg.IsNotNull(queries, nameof(queries));

            CapabilityStatement capabilityStatement = await GetCapabilityStatementAsync(cancellationToken);

            return(queries.All(x => _evaluatedQueries.GetOrAdd(x.FhirPathPredicate, _ => capabilityStatement.Predicate(x.FhirPathPredicate))));
        }
コード例 #12
0
        public static void AddOperation(this CapabilityStatement capabilityStatement, string name, string definition)
        {
            var operation = new CapabilityStatement.OperationComponent {
                Name = name, Definition = definition
            };

            capabilityStatement.Server().Operation.Add(operation);
        }
コード例 #13
0
        public static void AddSystemInteraction(this CapabilityStatement conformance, CapabilityStatement.SystemRestfulInteraction code)
        {
            var interaction = new CapabilityStatement.SystemInteractionComponent();

            interaction.Code = code;

            conformance.Rest().Interaction.Add(interaction);
        }
コード例 #14
0
 public static CapabilityStatement AddMultipleResourceComponents(this CapabilityStatement conformance, List <String> resourcetypes, Boolean readhistory, Boolean updatecreate, CapabilityStatement.ResourceVersionPolicy versioning)
 {
     foreach (var type in resourcetypes)
     {
         AddSingleResourceComponent(conformance, type, readhistory, updatecreate, versioning);
     }
     return(conformance);
 }
コード例 #15
0
 public static CapabilityStatement AddAllSystemInteractions(this CapabilityStatement conformance)
 {
     foreach (CapabilityStatement.SystemRestfulInteraction code in Enum.GetValues(typeof(CapabilityStatement.SystemRestfulInteraction)))
     {
         conformance.AddSystemInteraction(code);
     }
     return(conformance);
 }
コード例 #16
0
 public static CapabilityStatement AddAllCoreResources(this CapabilityStatement conformance, Boolean readhistory, Boolean updatecreate, CapabilityStatement.ResourceVersionPolicy versioning)
 {
     foreach (var resource in ModelInfo.SupportedResources)
     {
         conformance.AddSingleResourceComponent(resource, readhistory, updatecreate, versioning);
     }
     return(conformance);
 }
コード例 #17
0
        public static void AddOperation(this CapabilityStatement conformance, String name, ResourceReference definition)
        {
            var operation = new CapabilityStatement.OperationComponent();

            operation.Name       = name;
            operation.Definition = definition;

            conformance.Server().Operation.Add(operation);
        }
コード例 #18
0
 public static CapabilityStatement AddAllInteractionsForAllResources(this CapabilityStatement conformance)
 {
     foreach (var r in conformance.Rest.FirstOrDefault().Resource.ToList())
     {
         conformance.Rest().Resource.Remove(r);
         conformance.Rest().Resource.Add(AddAllResourceInteractions(r));
     }
     return(conformance);
 }
コード例 #19
0
 public static CapabilityStatement AddCoreSearchParamsAllResources(this CapabilityStatement conformance)
 {
     foreach (var r in conformance.Rest.FirstOrDefault().Resource.ToList())
     {
         conformance.Rest().Resource.Remove(r);
         conformance.Rest().Resource.Add(AddCoreSearchParamsResource(r));
     }
     return(conformance);
 }
コード例 #20
0
        public FhirStorageTests(FhirStorageTestsFixture fixture)
        {
            _fixture       = fixture;
            _searchService = Substitute.For <ISearchService>();
            _dataStore     = fixture.DataStore;

            _conformance = CapabilityStatementMock.GetMockedCapabilityStatement();

            CapabilityStatementMock.SetupMockResource(_conformance, ResourceType.Observation, null);
            var observationResource = _conformance.Rest[0].Resource.Find(r => r.Type == ResourceType.Observation);

            observationResource.UpdateCreate = true;
            observationResource.Versioning   = CapabilityStatement.ResourceVersionPolicy.Versioned;

            CapabilityStatementMock.SetupMockResource(_conformance, ResourceType.Organization, null);
            var organizationResource = _conformance.Rest[0].Resource.Find(r => r.Type == ResourceType.Organization);

            organizationResource.UpdateCreate = true;
            organizationResource.Versioning   = CapabilityStatement.ResourceVersionPolicy.NoVersion;

            var provider = Substitute.For <ConformanceProviderBase>();

            provider.GetCapabilityStatementAsync().Returns(_conformance.ToTypedElement().ToResourceElement());

            // TODO: FhirRepository instantiate ResourceDeserializer class directly
            // which will try to deserialize the raw resource. We should mock it as well.
            var rawResourceFactory = Substitute.For <RawResourceFactory>(new FhirJsonSerializer());

            var resourceWrapperFactory = Substitute.For <IResourceWrapperFactory>();

            resourceWrapperFactory
            .Create(Arg.Any <ResourceElement>(), Arg.Any <bool>(), Arg.Any <bool>())
            .Returns(x =>
            {
                ResourceElement resource = x.ArgAt <ResourceElement>(0);

                return(new ResourceWrapper(resource, rawResourceFactory.Create(resource, keepMeta: true), new ResourceRequest(HttpMethod.Post, "http://fhir"), x.ArgAt <bool>(1), null, null, null));
            });

            var collection = new ServiceCollection();

            var resourceIdProvider = new ResourceIdProvider();

            _searchParameterUtilities = Substitute.For <ISearchParameterUtilities>();

            collection.AddSingleton(typeof(IRequestHandler <CreateResourceRequest, UpsertResourceResponse>), new CreateResourceHandler(_dataStore, new Lazy <IConformanceProvider>(() => provider), resourceWrapperFactory, resourceIdProvider, new ResourceReferenceResolver(_searchService, new TestQueryStringParser()), DisabledFhirAuthorizationService.Instance, _searchParameterUtilities));
            collection.AddSingleton(typeof(IRequestHandler <UpsertResourceRequest, UpsertResourceResponse>), new UpsertResourceHandler(_dataStore, new Lazy <IConformanceProvider>(() => provider), resourceWrapperFactory, resourceIdProvider, DisabledFhirAuthorizationService.Instance, ModelInfoProvider.Instance));
            collection.AddSingleton(typeof(IRequestHandler <GetResourceRequest, GetResourceResponse>), new GetResourceHandler(_dataStore, new Lazy <IConformanceProvider>(() => provider), resourceWrapperFactory, resourceIdProvider, DisabledFhirAuthorizationService.Instance));
            collection.AddSingleton(typeof(IRequestHandler <DeleteResourceRequest, DeleteResourceResponse>), new DeleteResourceHandler(_dataStore, new Lazy <IConformanceProvider>(() => provider), resourceWrapperFactory, resourceIdProvider, DisabledFhirAuthorizationService.Instance));

            ServiceProvider services = collection.BuildServiceProvider();

            Mediator = new Mediator(type => services.GetService(type));

            _deserializer = new ResourceDeserializer(
                (FhirResourceFormat.Json, new Func <string, string, DateTimeOffset, ResourceElement>((str, version, lastUpdated) => _fhirJsonParser.Parse(str).ToResourceElement())));
        }
コード例 #21
0
        public static string ConformanceToXML(this CapabilityStatement conformance)
        {
            var xmlSerializer = new FhirXmlSerializer();
            //var xml = FhirSerializer.SerializeResourceToXml(resource, summary);
            var xml = xmlSerializer.SerializeToString(conformance);

            //   return FhirSerializer.SerializeResourceToXml(conformance);
            return(xml);
        }
コード例 #22
0
 public FhirStorageTests(FhirStorageTestsFixture fixture)
 {
     _fixture             = fixture;
     _capabilityStatement = fixture.CapabilityStatement;
     _deserializer        = fixture.Deserializer;
     _dataStore           = fixture.DataStore;
     _fhirJsonParser      = fixture.JsonParser;
     _conformanceProvider = fixture.ConformanceProvider;
     Mediator             = fixture.Mediator;
 }
コード例 #23
0
        public static void AddSystemInteraction(
            this CapabilityStatement capabilityStatement,
            CapabilityStatement.SystemRestfulInteraction code)
        {
            var interaction = new CapabilityStatement.SystemInteractionComponent {
                Code = code
            };

            capabilityStatement.Rest().Interaction.Add(interaction);
        }
コード例 #24
0
 public static void SetupMockResource(CapabilityStatement capability, ResourceType type, IEnumerable <TypeRestfulInteraction> interactions, IEnumerable <SearchParamComponent> searchParams = null)
 {
     capability.Rest[0].Resource.Add(new ResourceComponent
     {
         Type        = type,
         Interaction = interactions?.Select(x => new ResourceInteractionComponent {
             Code = x
         }).ToList(),
         SearchParam = searchParams?.ToList(),
     });
 }
コード例 #25
0
 public static CapabilityStatement AddSummaryForAllResources(this CapabilityStatement conformance)
 {
     foreach (var resource in conformance.Rest.FirstOrDefault().Resource.ToList())
     {
         var p = new CapabilityStatement.SearchParamComponent();
         p.Name          = "_summary";
         p.Type          = SearchParamType.String;
         p.Documentation = "Summary for resource";
         resource.SearchParam.Add(p);
     }
     return(conformance);
 }
コード例 #26
0
        public static CapabilityStatement AddSingleResourceComponent(this CapabilityStatement conformance, String resourcetype, Boolean readhistory, Boolean updatecreate, CapabilityStatement.ResourceVersionPolicy versioning, ResourceReference profile = null)
        {
            var resource = new CapabilityStatement.ResourceComponent();

            resource.Type         = Hacky.GetResourceTypeForResourceName(resourcetype);
            resource.Profile      = profile;
            resource.ReadHistory  = readhistory;
            resource.UpdateCreate = updatecreate;
            resource.Versioning   = versioning;
            conformance.Server().Resource.Add(resource);
            return(conformance);
        }
コード例 #27
0
        public ValidateContentTypeFilterAttributeTests()
        {
            _statement = new CapabilityStatement
            {
                Format = new List <string> {
                    "json"
                },
            };

            _conformanceProvider = Substitute.For <IConformanceProvider>();
            _conformanceProvider.GetCapabilityStatementAsync().Returns(_statement.ToTypedElement().ToResourceElement());
        }
コード例 #28
0
        public static bool TryGetSmartUrls(
            FhirClient fhirClient,
            out string authorizeUrl,
            out string tokenUrl
            )
        {
            authorizeUrl = string.Empty;
            tokenUrl     = string.Empty;

            CapabilityStatement capabilities = (CapabilityStatement)fhirClient.Get("metadata");

            foreach (CapabilityStatement.RestComponent restComponent in capabilities.Rest)
            {
                if (restComponent.Security == null)
                {
                    continue;
                }

                foreach (Extension securityExt in restComponent.Security.Extension)
                {
                    if (securityExt.Url != "http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris")
                    {
                        continue;
                    }

                    if ((securityExt.Extension == null) || (securityExt.Extension.Count == 0))
                    {
                        continue;
                    }

                    foreach (Extension smartExt in securityExt.Extension)
                    {
                        switch (smartExt.Url)
                        {
                        case "authorize":
                            authorizeUrl = ((FhirUri)smartExt.Value).Value.ToString();
                            break;

                        case "token":
                            tokenUrl = ((FhirUri)smartExt.Value).Value.ToString();
                            break;
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(authorizeUrl) || string.IsNullOrEmpty(tokenUrl))
            {
                return(false);
            }

            return(true);
        }
コード例 #29
0
        public static CapabilityStatement CreateServer(string server, string publisher,
                                                       string fhirVersion)
        {
            var capabilityStatement = new CapabilityStatement
            {
                Name        = server,
                Publisher   = publisher,
                FhirVersion = fhirVersion,
                Date        = Date.Today().Value,
            };

            return(capabilityStatement);
        }
コード例 #30
0
        public static CapabilityStatement.RestComponent AddRestComponent(this CapabilityStatement conformance, Boolean isServer, String documentation = null)
        {
            var server = new CapabilityStatement.RestComponent();

            server.Mode = (isServer) ? CapabilityStatement.RestfulCapabilityMode.Server : CapabilityStatement.RestfulCapabilityMode.Client;

            if (documentation != null)
            {
                server.Documentation = documentation;
            }
            conformance.Rest.Add(server);
            return(server);
        }