public void WhenUnProcessedKeyIsPresent()
        {
            string thing =
                @"<thing><thing-id version-stamp=""583a502e-69a1-4546-be74-dc2ba8db7d98"">e4bfb506-e94e-4d69-ba04-0c12197c0bb8</thing-id><type-id name=""Exercise"">85a21ddb-db20-4c65-8d30-33c899ccf612</type-id><thing-state>Active</thing-state><flags>0</flags><eff-date>2017-01-31T20:00:00</eff-date><created><timestamp>2017-02-01T00:55:06.92Z</timestamp><app-id name=""HealthVault Insights"">52e62dc1-0834-4e25-9612-36f6692a9bcf</app-id><person-id name=""Test"">b54d4b92-9e05-4f60-a428-8b6262d18ec7</person-id><access-avenue>Offline</access-avenue><audit-action>Created</audit-action></created><updated><timestamp>2017-02-01T00:55:06.92Z</timestamp><app-id name=""HealthVault Insights"">52e62dc1-0834-4e25-9612-36f6692a9bcf</app-id><person-id name=""Test"">b54d4b92-9e05-4f60-a428-8b6262d18ec7</person-id><access-avenue>Offline</access-avenue><audit-action>Created</audit-action></updated><data-xml><exercise><when><structured><date><y>2017</y><m>1</m><d>31</d></date><time><h>20</h><m>0</m><s>0</s><f>0</f></time></structured></when><activity><text>Bicycling</text><code><value>Bicycling</value><family>wc</family><type>exercise-activities</type><version>1</version></code></activity><duration>120</duration><detail><name><value>CaloriesBurned_calories</value><family>wc</family><type>exercise-detail-names</type><version>1</version></name><value><value>544</value><units><text>Calories</text><code><value>Calories</value><family>wc</family><type>exercise-units</type><version>1</version></code></units></value></detail><detail><name><value>ElevationGain_meters</value><family>wc</family><type>exercise-detail-names</type><version>1</version></name><value><value>0</value><units><text>meters</text><code><value>Meters</value><family>wc</family><type>exercise-units</type><version>1</version></code></units></value></detail><detail><name><value>ElevationLoss_meters</value><family>wc</family><type>exercise-detail-names</type><version>1</version></name><value><value>0</value><units><text>meters</text><code><value>Meters</value><family>wc</family><type>exercise-units</type><version>1</version></code></units></value></detail></exercise><common><source>Microsoft HealthVault Insights</source><client-thing-id>Biking_a01442b7-213e-4ccf-b057-bf00fb809b46_636214896000000000-Duration</client-thing-id></common></data-xml><eff-permissions immutable=""false""><permission>Read</permission><permission>Update</permission><permission>Create</permission><permission>Delete</permission></eff-permissions></thing>";
            string unprocessedThingKeyInfo =
                @"<unprocessed-thing-key-info><thing-id version-stamp=""583a502e-69a1-4546-be74-dc2ba8db7d98"">e4bfb506-e94e-4d69-ba04-0c12197c0bb8</thing-id></unprocessed-thing-key-info>";

            string xml = $"<group>{thing}{unprocessedThingKeyInfo}</group>";

            HealthRecordSearcher query = new HealthRecordSearcher(_healthRecordAccessor);

            HealthServiceResponseData responseData = new HealthServiceResponseData
            {
                InfoNavigator = new XPathDocument(new StringReader(xml)).CreateNavigator()
            };

            IReadOnlyCollection <ThingCollection> thingCollections = _thingDeserializer.Deserialize(responseData, query);

            ThingCollection thingCollection = thingCollections.FirstOrDefault();

            // validate that we have both thing and unprocessed thing is parsed
            Assert.AreEqual(2, thingCollection.Count);

            // validate that the max full thing is 1 and doesn't include partial item
            Assert.AreEqual(1, thingCollection.MaxResultsPerRequest);
        }
Exemple #2
0
        /// <summary>
        /// Gets the instance where a HealthVault account should be created
        /// for the specified account location.
        /// </summary>
        ///
        /// <param name="connection">
        /// The connection to use to perform the operation.
        /// </param>
        ///
        /// <param name="preferredLocation">
        /// A user's preferred geographical location, used to select the best instance
        /// in which to create a new HealthVault account. If there is a location associated
        /// with the credential that will be used to log into the account, that location
        /// should be used.
        /// </param>
        ///
        /// <remarks>
        /// If no suitable instance can be found, a null value is returned. This can happen,
        /// for example, if the account location is not supported by HealthVault.
        ///
        /// Currently the returned instance IDs all parse to integers, but that is not
        /// guaranteed and should not be relied upon.
        /// </remarks>
        ///
        /// <returns>
        /// A <see cref="HealthServiceInstance"/> object represents the selected instance,
        /// or null if no suitable instance exists.
        /// </returns>
        ///
        /// <exception cref="HealthServiceException">
        /// The HealthVault service returned an error.
        /// </exception>
        ///
        /// <exception cref="ArgumentException">
        /// If <paramref name="preferredLocation"/> is <b>null</b>.
        /// </exception>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="connection"/> parameter is <b>null</b>.
        /// </exception>
        public virtual async Task <HealthServiceInstance> SelectInstanceAsync(
            IHealthVaultConnection connection,
            Location preferredLocation)
        {
            Validator.ThrowIfArgumentNull(connection, nameof(connection), Resources.TypeManagerConnectionNull);
            Validator.ThrowIfArgumentNull(preferredLocation, nameof(preferredLocation), Resources.SelectInstanceLocationRequired);

            StringBuilder     requestParameters = new StringBuilder();
            XmlWriterSettings settings          = SDKHelper.XmlUnicodeWriterSettings;

            using (XmlWriter writer = XmlWriter.Create(requestParameters, settings))
            {
                preferredLocation.WriteXml(writer, "preferred-location");
                writer.Flush();
            }

            HealthServiceResponseData responseData = await connection.ExecuteAsync(
                HealthVaultMethods.SelectInstance,
                1,
                requestParameters.ToString()).ConfigureAwait(false);

            XPathExpression infoPath = SDKHelper.GetInfoXPathExpressionForMethod(
                responseData.InfoNavigator,
                "SelectInstance");
            XPathNavigator infoNav = responseData.InfoNavigator.SelectSingleNode(infoPath);

            XPathNavigator instanceNav = infoNav.SelectSingleNode("selected-instance");

            if (instanceNav != null)
            {
                return(HealthServiceInstance.CreateInstance(instanceNav));
            }

            return(null);
        }
Exemple #3
0
        public virtual async Task <Collection <HealthRecordInfo> > GetAuthorizedRecordsAsync(IList <Guid> recordIds)
        {
            StringBuilder parameters = new StringBuilder(128);

            foreach (Guid id in recordIds)
            {
                parameters.Append(
                    "<id>" + id + "</id>");
            }

            HealthServiceResponseData responseData = await _connection.ExecuteAsync(
                HealthVaultMethods.GetAuthorizedRecords,
                1,
                parameters.ToString())
                                                     .ConfigureAwait(false);

            Collection <HealthRecordInfo> results = new Collection <HealthRecordInfo>();

            XPathNodeIterator records = responseData.InfoNavigator.Select(GetRecordXPathExpression(responseData.InfoNavigator));

            foreach (XPathNavigator recordNav in records)
            {
                results.Add(HealthRecordInfo.CreateFromXml(_connection, recordNav));
            }

            return(results);
        }
Exemple #4
0
        public IReadOnlyCollection <ThingCollection> Deserialize(
            HealthServiceResponseData responseData,
            HealthRecordSearcher searcher)
        {
            XPathNavigator navigator = responseData.InfoNavigator;

            Collection <ThingCollection> result = new Collection <ThingCollection>();

            if (navigator != null)
            {
                XPathNodeIterator groupNodeIterator = navigator.Select("//group");

                foreach (XPathNavigator groupNavigator in groupNodeIterator)
                {
                    ThingCollection resultGroup = CreateResultGroupFromResponse(
                        searcher.Record,
                        groupNavigator,
                        searcher.Filters);

                    if (resultGroup != null)
                    {
                        result.Add(resultGroup);
                    }
                }
            }

            return(new ReadOnlyCollection <ThingCollection>(result));
        }
Exemple #5
0
        public virtual async Task <PersonInfo> GetPersonInfoAsync()
        {
            HealthServiceResponseData responseData = await _connection.ExecuteAsync(HealthVaultMethods.GetPersonInfo, 1).ConfigureAwait(false);

            XPathExpression personPath = GetPersonXPathExpression(responseData.InfoNavigator);
            XPathNavigator  infoNav    = responseData.InfoNavigator.SelectSingleNode(personPath);

            return(PersonInfo.CreateFromXml(infoNav));
        }
Exemple #6
0
        /// <summary>
        /// Gets a list of <see cref="HealthRecordUpdateInfo"/> objects for the current application,
        /// that optionally have been updated since a specified date.
        /// </summary>
        ///
        /// <param name="connection">The connection to use to perform the operation. This connection
        /// must be application level. </param>
        ///
        /// <param name="updatedDate">
        /// Date that is used to filter health record IDs according to whether or not they have
        /// been updated since the specified date.
        /// </param>
        ///
        /// <returns>
        /// List of <see cref="HealthRecordUpdateInfo"/> objects filtered by any specified input parameters.
        /// </returns>
        ///
        public virtual async Task <IList <HealthRecordUpdateInfo> > GetUpdatedRecordInfoForApplicationAsync(
            IHealthVaultConnection connection,
            Instant?updatedDate)
        {
            string parameters = GetUpdateDateParameters(updatedDate);

            HealthServiceResponseData responseData = await connection.ExecuteAsync(HealthVaultMethods.GetUpdatedRecordsForApplication, 2, parameters).ConfigureAwait(false);

            return(ParseGetUpdatedRecordsForApplicationResponseHealthRecordUpdateInfos(responseData));
        }
Exemple #7
0
        /// <summary>
        /// Generates a new signup code that should be passed to HealthVault Shell in order
        /// to create a new user account.
        /// </summary>
        ///
        /// <param name="connection">The connection to use to perform the operation. This connection
        /// must be application level. </param>
        ///
        /// <returns>
        /// A signup code that can be used to create an account.
        /// </returns>
        ///
        public virtual async Task <string> NewSignupCodeAsync(IHealthVaultConnection connection)
        {
            HealthServiceResponseData responseData = await connection.ExecuteAsync(HealthVaultMethods.NewSignupCode, 1).ConfigureAwait(false);

            XPathExpression infoPath = SDKHelper.GetInfoXPathExpressionForMethod(responseData.InfoNavigator, "NewSignupCode");

            XPathNavigator infoNav = responseData.InfoNavigator.SelectSingleNode(infoPath);

            return(infoNav.SelectSingleNode("signup-code").Value);
        }
Exemple #8
0
        public static HealthServiceResponseData GetResponseData(string fileName)
        {
            var response = new HealthServiceResponseData
            {
                InfoNavigator =
                    new XPathDocument(new StringReader(GetSampleContent(fileName)))
                    .CreateNavigator()
            };

            return(response);
        }
        /// <summary>
        /// Helper method that allows the SDK to throw the appropriate
        /// HealthServiceException based on the status code returned by
        /// HealthVault.
        /// </summary>
        ///
        /// <param name="responseData">
        /// The HealthServiceResponseData object created by parsing response returned by HealthVault.
        /// </param>
        ///
        internal static HealthServiceException GetHealthServiceException(HealthServiceResponseData responseData)
        {
            HealthServiceStatusCode errorCode =
                HealthServiceStatusCodeManager.GetStatusCode(responseData.CodeId);

            var e = errorCode != HealthServiceStatusCode.UnmappedError ? GetHealthServiceException(errorCode, responseData.Error) : new HealthServiceException(responseData.CodeId, responseData.Error);

            e.Response = responseData;

            return(e);
        }
        /// <summary>
        /// Retrieves a collection of key information for identifying and
        /// describing the vocabularies in the system.
        /// </summary>
        ///
        /// <param name="connection">
        /// The connection to use for this operation. The connection
        /// must have application capability.
        /// </param>
        ///
        /// <returns>
        /// A collection of keys identifying the vocabularies in the system.
        /// </returns>
        ///
        public virtual async Task <ReadOnlyCollection <VocabularyKey> > GetVocabularyKeysAsync(IHealthVaultConnection connection)
        {
            var method        = HealthVaultMethods.GetVocabulary;
            int methodVersion = 1;

            HealthServiceResponseData responseData = await connection.ExecuteAsync(method, methodVersion).ConfigureAwait(false);

            ReadOnlyCollection <VocabularyKey> keys = CreateVocabularyKeysFromResponse(method.ToString(), responseData);

            return(keys);
        }
        private async Task <HealthServiceResponseData> SendRequestAsync(string requestXml, Guid?correlationId = null)
        {
            try
            {
                Debug.WriteLine($"Sent message: {requestXml}");

                byte[] requestXmlBytes = Encoding.UTF8.GetBytes(requestXml);

                CancellationTokenSource cancellationTokenSource = null;
                HttpResponseMessage     response;
                try
                {
                    cancellationTokenSource = new CancellationTokenSource(Configuration.RequestTimeoutDuration);

                    response = await _webRequestClient.SendAsync(
                        ServiceInstance.HealthServiceUrl,
                        requestXmlBytes,
                        requestXml.Length,
                        new Dictionary <string, string> {
                        { CorrelationIdContextKey, correlationId.GetValueOrDefault(Guid.NewGuid()).ToString() }
                    },
                        (CancellationToken)cancellationTokenSource?.Token).ConfigureAwait(false);
                }
                finally
                {
                    cancellationTokenSource?.Dispose();
                }

                // Platform returns a platform request id with the responses. This allows
                // developers to have additional information if necessary for debugging/logging purposes.
                Guid responseId;
                if (response.Headers != null &&
                    response.Headers.Contains(ResponseIdContextKey) &&
                    Guid.TryParse(response.Headers.GetValues(ResponseIdContextKey)?.FirstOrDefault(), out responseId))
                {
                    // TODO: Provide a plug in for applications to plug in their telemetry
                    if (HealthVaultPlatformTrace.LoggingEnabled)
                    {
                        HealthVaultPlatformTrace.Log(TraceEventType.Information, "Response Id: {0}", responseId);
                    }
                }

                HealthServiceResponseData responseData = await _healthServiceResponseParser.ParseResponseAsync(response).ConfigureAwait(false);

                return(responseData);
            }
            catch (XmlException xmlException)
            {
                throw new HealthServiceException(
                          Resources.InvalidResponseFromXMLRequest,
                          xmlException);
            }
        }
        public void WhenAppSpecificTypesAreRegistered()
        {
            HealthServiceResponseData responseData = Samples.SampleUtils.GetResponseData("ApplicationSpecificThing.xml");

            _thingTypeRegistrar.RegisterApplicationSpecificHandler(
                "some-appid",
                "some-tag",
                typeof(CustomThingType));

            ThingBase thingBase = _thingDeserializer.DeserializeItem(responseData.InfoNavigator.SelectSingleNode("thing"));

            Assert.IsNotNull(thingBase as CustomThingType);
        }
        public void InitializeTest()
        {
            _connection = Substitute.For <IConnectionInternal>();
            _client     = new VocabularyClient(_connection);

            var response = new HealthServiceResponseData
            {
                InfoNavigator = new XPathDocument(new StringReader(SampleUtils.GetSampleContent("VocabularySample.xml"))).CreateNavigator(),
            };

            _connection.ExecuteAsync(Arg.Any <HealthVaultMethods>(), Arg.Any <int>(), Arg.Any <string>())
            .Returns(response);
        }
        public async Task <SessionCredential> GetSessionCredentialAsync(CancellationToken token)
        {
            if (Connection == null)
            {
                throw new NotSupportedException($"{nameof(Connection)} is required");
            }

            HealthServiceResponseData responseData = await Connection
                                                     .ExecuteAsync(HealthVaultMethods.CreateAuthenticatedSessionToken, 2, ConstructCreateTokenInfoXml())
                                                     .ConfigureAwait(false);

            return(GetSessionCredential(responseData));
        }
        public async Task CreateNewThingsAsync <T>(Guid recordId, ICollection <T> things)
            where T : IThing
        {
            Validator.ThrowIfArgumentNull(recordId, nameof(recordId), Resources.NewItemsNullItem);
            Validator.ThrowIfArgumentNull(things, nameof(things), Resources.NewItemsNullItem);

            StringBuilder     infoXml  = new StringBuilder();
            XmlWriterSettings settings = SDKHelper.XmlUnicodeWriterSettings;

            using (XmlWriter infoXmlWriter =
                       XmlWriter.Create(infoXml, settings))
            {
                foreach (IThing thing in things)
                {
                    Validator.ThrowIfArgumentNull(thing, nameof(thing), Resources.NewItemsNullItem);

                    thing.WriteItemXml(infoXmlWriter);
                }

                infoXmlWriter.Flush();
            }

            HealthServiceResponseData responseData = await _connection.ExecuteAsync(
                HealthVaultMethods.PutThings,
                2,
                infoXml.ToString(),
                recordId,
                CorrelationId);

            // Now update the Id for the new item
            XPathNodeIterator thingIds =
                responseData.InfoNavigator.Select(
                    GetThingIdXPathExpression(responseData.InfoNavigator));

            int thingIndex = 0;

            foreach (XPathNavigator thingIdNav in thingIds)
            {
                var thing = things.ElementAt(thingIndex) as ThingBase;
                if (thing != null)
                {
                    thing.Key =
                        new ThingKey(
                            new Guid(thingIdNav.Value),
                            new Guid(thingIdNav.GetAttribute(
                                         "version-stamp", string.Empty)));
                }

                thingIndex++;
            }
        }
        /// <summary>
        /// Gets valid group memberships for a record.
        /// </summary>
        ///
        /// <remarks>
        /// Group membership thing types allow an application to signify that the
        /// record belongs to an application defined group.  A record in the group may be
        /// eligible for special programs offered by other applications, for example.
        /// Applications then need a away to query for valid group memberships.
        /// <br/>
        /// Valid group memberships are those memberships which are not expired, and whose
        /// last updating application is authorized by the last updating person to
        /// read and delete the membership.
        /// </remarks>
        /// <param name="connection">
        /// The connection to use to access the data.
        /// </param>
        /// <param name="accessor">
        /// The record to use.
        /// </param>
        /// <param name="applicationIds">
        /// A collection of unique application identifiers for which to
        /// search for group memberships.  For a null or empty application identifier
        /// list, return all valid group memberships for the record.  Otherwise,
        /// return only those group memberships last updated by one of the
        /// supplied application identifiers.
        /// </param>
        /// <returns>
        /// A List of things representing the valid group memberships.
        /// </returns>
        /// <exception cref="HealthServiceException">
        /// If an error occurs while contacting the HealthVault service.
        /// </exception>
        public virtual async Task <Collection <ThingBase> > GetValidGroupMembershipAsync(
            IHealthVaultConnection connection,
            HealthRecordAccessor accessor,
            IList <Guid> applicationIds)
        {
            StringBuilder parameters = new StringBuilder(128);

            if (applicationIds != null)
            {
                XmlWriterSettings settings = SDKHelper.XmlUnicodeWriterSettings;
                using (XmlWriter writer = XmlWriter.Create(parameters, settings))
                {
                    foreach (Guid guid in applicationIds)
                    {
                        writer.WriteElementString(
                            "application-id",
                            guid.ToString());
                    }
                }
            }

            var thingDeserializer = Ioc.Container.Locate <IThingDeserializer>(
                new
            {
                connection         = connection,
                thingTypeRegistrar = Ioc.Get <IThingTypeRegistrar>()
            });

            HealthServiceResponseData responseData = await connection.ExecuteAsync(HealthVaultMethods.GetValidGroupMembership, 1, parameters.ToString()).ConfigureAwait(false);

            XPathExpression infoPath =
                SDKHelper.GetInfoXPathExpressionForMethod(
                    responseData.InfoNavigator,
                    "GetValidGroupMembership");

            XPathNavigator infoNav = responseData.InfoNavigator.SelectSingleNode(infoPath);

            Collection <ThingBase> memberships = new Collection <ThingBase>();

            XPathNodeIterator membershipIterator = infoNav.Select("thing");

            if (membershipIterator != null)
            {
                foreach (XPathNavigator membershipNav in membershipIterator)
                {
                    memberships.Add(thingDeserializer.Deserialize(membershipNav.OuterXml));
                }
            }

            return(memberships);
        }
        private SessionCredential GetSessionCredential(HealthServiceResponseData responseData)
        {
            if (responseData == null)
            {
                throw new ArgumentNullException($"{nameof(responseData)}");
            }

            SessionCredential sessionCredential = GetAuthenticationToken(responseData.InfoNavigator);

            // TODO: Update with returned expiry when #55406 is completed. 4h is the default HealthVault token expiry time
            sessionCredential.ExpirationUtc = DateTimeOffset.UtcNow.AddHours(4);

            return(sessionCredential);
        }
        public async Task SearchVocabulariesTest()
        {
            var response = new HealthServiceResponseData
            {
                InfoNavigator = new XPathDocument(new StringReader(SampleUtils.GetSampleContent("VocabularySearchSample.xml"))).CreateNavigator()
            };

            _connection.ExecuteAsync(Arg.Any <HealthVaultMethods>(), Arg.Any <int>(), Arg.Any <string>())
            .Returns(response);
            var searchTerm = "hypertension";
            await _client.SearchVocabularyAsync(searchTerm, VocabularySearchType.Contains, null);

            await _connection.Received().ExecuteAsync(HealthVaultMethods.SearchVocabulary, Arg.Any <int>(), Arg.Is <string>(x => x.Contains(searchTerm)));
        }
Exemple #19
0
        private static IList <HealthRecordUpdateInfo> ParseGetUpdatedRecordsForApplicationResponseHealthRecordUpdateInfos(
            HealthServiceResponseData response)
        {
            IList <HealthRecordUpdateInfo> healthRecordPersonUpdateInfos = new List <HealthRecordUpdateInfo>();

            XPathNodeIterator iterator = response.InfoNavigator.SelectSingleNode("updated-records").Select("updated-record");

            foreach (XPathNavigator navigator in iterator)
            {
                healthRecordPersonUpdateInfos.Add(ParseHealthRecordUpdateInfo(navigator));
            }

            return(healthRecordPersonUpdateInfos);
        }
        /// <summary>
        /// Retrieves lists of vocabulary items for the specified
        /// vocabularies and culture.
        /// </summary>
        ///
        /// <param name="connection">
        /// The connection to use for this operation. The connection
        /// must have application capability.
        /// </param>
        ///
        /// <param name="vocabularyKeys">
        /// A list of keys identifying the requested vocabularies.
        /// </param>
        ///
        /// <param name="cultureIsFixed">
        /// HealthVault looks for the vocabulary items for the culture info
        /// specified using <see cref="HealthServiceConnection.Culture"/>.
        /// If <paramref name="cultureIsFixed"/> is set to <b>false</b> and if
        /// items are not found for the specified culture, items for the
        /// default fallback culture are returned. If
        /// <paramref name="cultureIsFixed"/> is set to <b>true</b>,
        /// fallback will not occur, and if items are not found for the
        /// specified culture, empty strings are returned.
        /// </param>
        ///
        /// <returns>
        /// The specified vocabularies and their items, or empty strings.
        /// </returns>
        ///
        /// <exception cref="ArgumentException">
        /// The <paramref name="vocabularyKeys"/> list is empty.
        /// </exception>
        ///
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="vocabularyKeys"/> list is <b>null</b>
        /// or contains a <b>null</b> entry.
        /// </exception>
        ///
        /// <exception cref="HealthServiceException">
        /// There is an error in the server request.
        /// <br></br>
        /// -Or-
        /// <br></br>
        /// One of the requested vocabularies is not found on the server.
        /// <br></br>
        /// -Or-
        /// <br></br>
        /// One of the requested vocabularies does not contain representations
        /// for its items for the specified culture when
        /// <paramref name="cultureIsFixed"/> is <b>true</b>.
        /// <br></br>
        /// -Or-
        /// <br></br>
        /// There is an error loading the vocabulary.
        /// </exception>
        ///
        public virtual async Task <ReadOnlyCollection <Vocabulary> > GetVocabularyAsync(
            IHealthVaultConnection connection,
            IList <VocabularyKey> vocabularyKeys,
            bool cultureIsFixed)
        {
            Validator.ThrowIfArgumentNull(vocabularyKeys, nameof(vocabularyKeys), Resources.VocabularyKeysNullOrEmpty);

            if (vocabularyKeys.Count == 0)
            {
                throw new ArgumentException(Resources.VocabularyKeysNullOrEmpty, nameof(vocabularyKeys));
            }

            var method        = HealthVaultMethods.GetVocabulary;
            int methodVersion = 2;

            StringBuilder     requestParameters = new StringBuilder(256);
            XmlWriterSettings settings          = SDKHelper.XmlUnicodeWriterSettings;

            settings.OmitXmlDeclaration = true;
            settings.ConformanceLevel   = ConformanceLevel.Fragment;

            using (XmlWriter writer = XmlWriter.Create(requestParameters, settings))
            {
                writer.WriteStartElement("vocabulary-parameters");

                for (int i = 0; i < vocabularyKeys.Count; i++)
                {
                    Validator.ThrowIfArgumentNull(vocabularyKeys[i], "vocabularyKeys[i]", Resources.VocabularyKeysNullOrEmpty);

                    vocabularyKeys[i].WriteXml(writer);
                }

                writer.WriteElementString(
                    "fixed-culture",
                    SDKHelper.XmlFromBool(cultureIsFixed));

                writer.WriteEndElement();
                writer.Flush();
            }

            string parameters = requestParameters.ToString();

            HealthServiceResponseData responseData = await connection.ExecuteAsync(method, methodVersion, parameters).ConfigureAwait(false);

            ReadOnlyCollection <Vocabulary> vocabularies
                = CreateVocabulariesFromResponse(method.ToString(), responseData);

            return(vocabularies);
        }
        public async Task <HealthServiceResponseData> ExecuteAsync(
            HealthVaultMethods method,
            int methodVersion,
            string parameters  = null,
            Guid?recordId      = null,
            Guid?correlationId = null)
        {
            bool isMethodAnonymous = IsMethodAnonymous(method);

            // Make sure that session credential is set for method calls requiring
            // authentication
            if (!isMethodAnonymous && string.IsNullOrEmpty(SessionCredential?.Token))
            {
                await AuthenticateAsync().ConfigureAwait(false);
            }

            // Create the message using a Func in case we need to re-generate it for a retry later
            Func <string> requestXmlCreator = () => _requestMessageCreator.Create(
                method,
                methodVersion,
                isMethodAnonymous,
                parameters,
                recordId,
                isMethodAnonymous && method == HealthVaultMethods.CreateAuthenticatedSessionToken
                   ? ApplicationId
                   : Configuration.MasterApplicationId);

            var requestXml = requestXmlCreator();

            HealthServiceResponseData responseData = null;

            try
            {
                responseData = await SendRequestAsync(requestXml, correlationId).ConfigureAwait(false);
            }
            catch (HealthServiceAuthenticatedSessionTokenExpiredException)
            {
                if (!isMethodAnonymous)
                {
                    await RefreshSessionAsync(CancellationToken.None);

                    // Re-generate the message so it pulls in the new SessionCredential
                    requestXml = requestXmlCreator();
                    return(await SendRequestAsync(requestXml, correlationId).ConfigureAwait(false));
                }
            }

            return(responseData);
        }
        private static VocabularyItemCollection CreateVocabularyItemCollectionFromResponse(
            string methodNSSuffix,
            HealthServiceResponseData response)
        {
            XPathNavigator infoNav =
                response.InfoNavigator.SelectSingleNode(
                    Vocabulary.GetInfoXPathExpression(
                        methodNSSuffix,
                        response.InfoNavigator));

            XPathNavigator           vocabNav       = infoNav.SelectSingleNode("code-set-result");
            VocabularyItemCollection itemCollection = new VocabularyItemCollection();

            itemCollection.PopulateFromXml(vocabNav);
            return(itemCollection);
        }
        public async Task <IReadOnlyCollection <ThingCollection> > GetThingsAsync(Guid recordId, IEnumerable <ThingQuery> queries)
        {
            Validator.ThrowIfGuidEmpty(recordId, nameof(recordId));

            List <ThingQuery> queriesList = queries.ToList();

            Validator.ThrowIfCollectionNullOrEmpty(queriesList, nameof(queries));

            HealthRecordAccessor accessor = new HealthRecordAccessor(_connection, recordId);
            HealthRecordSearcher searcher = new HealthRecordSearcher(accessor);

            HealthServiceResponseData response = await GetRequestWithParameters(recordId, searcher, queriesList).ConfigureAwait(false);

            IReadOnlyCollection <ThingCollection> resultSet = _thingDeserializer.Deserialize(response, searcher);

            return(resultSet);
        }
Exemple #24
0
        private static async Task <ServiceInfo> GetServiceDefinitionAsync(IHealthVaultConnection connection, string parameters)
        {
            HealthServiceResponseData responseData = await connection.ExecuteAsync(HealthVaultMethods.GetServiceDefinition, 2, parameters).ConfigureAwait(false);

            if (responseData.InfoNavigator.HasChildren)
            {
                XPathExpression infoPath = SDKHelper.GetInfoXPathExpressionForMethod(
                    responseData.InfoNavigator,
                    "GetServiceDefinition2");

                XPathNavigator infoNav = responseData.InfoNavigator.SelectSingleNode(infoPath);

                return(ServiceInfo.CreateServiceInfo(infoNav));
            }

            return(null);
        }
        /// <summary>
        /// Gets the application settings for the current application and
        /// person.
        /// </summary>
        ///
        /// <param name="connection">The connection to use to perform the operation. This connection
        /// must be authenticated. </param>
        ///
        /// <returns>
        /// The complete set application settings including the XML settings, selected record ID, etc.
        /// </returns>
        ///
        public virtual async Task <ApplicationSettings> GetApplicationSettingsAsync(IHealthVaultConnection connection)
        {
            HealthServiceResponseData responseData = await connection.ExecuteAsync(HealthVaultMethods.GetApplicationSettings, 1).ConfigureAwait(false);

            XPathExpression xPathExpression = GetPersonAppSettingsXPathExpression(responseData.InfoNavigator);

            XPathNavigator appSettingsNav = responseData.InfoNavigator.SelectSingleNode(xPathExpression);

            ApplicationSettings settings = null;

            if (appSettingsNav != null)
            {
                settings = new ApplicationSettings();
                settings.ParseXml(appSettingsNav);
            }

            return(settings);
        }
Exemple #26
0
        private Dictionary <Guid, ThingTypeDefinition> CreateThingTypesFromResponse(
            string cultureName,
            HealthServiceResponseData response,
            ThingTypeSections sections,
            Dictionary <Guid, ThingTypeDefinition> cachedThingTypes)
        {
            Dictionary <Guid, ThingTypeDefinition> thingTypes;

            if (cachedThingTypes != null && cachedThingTypes.Count > 0)
            {
                thingTypes = new Dictionary <Guid, ThingTypeDefinition>(cachedThingTypes);
            }
            else
            {
                thingTypes = new Dictionary <Guid, ThingTypeDefinition>();
            }

            XPathNodeIterator thingTypesIterator =
                response.InfoNavigator.Select("thing-type");

            lock (_sectionCache)
            {
                if (!_sectionCache.ContainsKey(cultureName))
                {
                    _sectionCache.Add(cultureName, new Dictionary <ThingTypeSections, Dictionary <Guid, ThingTypeDefinition> >());
                }

                if (!_sectionCache[cultureName].ContainsKey(sections))
                {
                    _sectionCache[cultureName].Add(sections, new Dictionary <Guid, ThingTypeDefinition>());
                }

                foreach (XPathNavigator navigator in thingTypesIterator)
                {
                    ThingTypeDefinition thingType =
                        ThingTypeDefinition.CreateFromXml(navigator);

                    _sectionCache[cultureName][sections][thingType.TypeId] = thingType;
                    thingTypes[thingType.TypeId] = thingType;
                }
            }

            return(thingTypes);
        }
        /// <summary>
        /// Calls the BeginPutBlob HealthVault method.
        /// </summary>
        ///
        /// <returns>
        /// The result of the BeginPutBlob method call as a BlobPutParameters instance.
        /// </returns>
        ///
        /// <exception cref="HealthServiceException">
        /// If the call to HealthVault fails in some way.
        /// </exception>
        ///
        private async Task <BlobPutParameters> BeginPutBlobAsync()
        {
            HealthServiceResponseData responseData = await _record.Connection.ExecuteAsync(HealthVaultMethods.BeginPutBlob, 1).ConfigureAwait(false);

            XPathExpression infoPath =
                SDKHelper.GetInfoXPathExpressionForMethod(
                    responseData.InfoNavigator,
                    "BeginPutBlob");

            XPathNavigator infoNav =
                responseData.InfoNavigator.SelectSingleNode(infoPath);

            Uri               blobReferenceUrl  = new Uri(infoNav.SelectSingleNode("blob-ref-url").Value);
            int               chunkSize         = infoNav.SelectSingleNode("blob-chunk-size").ValueAsInt;
            long              maxBlobSize       = infoNav.SelectSingleNode("max-blob-size").ValueAsLong;
            string            blobHashAlgString = infoNav.SelectSingleNode("blob-hash-algorithm").Value;
            BlobHashAlgorithm blobHashAlg;

            try
            {
                blobHashAlg =
                    (BlobHashAlgorithm)Enum.Parse(
                        typeof(BlobHashAlgorithm), blobHashAlgString);
            }
            catch (ArgumentException)
            {
                blobHashAlg = BlobHashAlgorithm.Unknown;
            }

            int            blocksize = 0;
            XPathNavigator blockNav  = infoNav.SelectSingleNode("blob-hash-parameters/block-size");

            if (blockNav != null)
            {
                blocksize = blockNav.ValueAsInt;
            }

            return(new BlobPutParameters(
                       blobReferenceUrl,
                       chunkSize,
                       maxBlobSize,
                       blobHashAlg,
                       blocksize));
        }
        public async Task <T> GetThingAsync <T>(Guid recordId, Guid thingId)
            where T : IThing
        {
            Validator.ThrowIfArgumentNull(recordId, nameof(recordId), Resources.NewItemsNullItem);

            // Create a new searcher to get the item.
            HealthRecordAccessor accessor = new HealthRecordAccessor(_connection, recordId);
            HealthRecordSearcher searcher = new HealthRecordSearcher(accessor);

            ThingQuery query = new ThingQuery();

            query.ItemIds.Add(thingId);
            query.View.Sections      = ThingSections.Default;
            query.CurrentVersionOnly = true;

            HealthServiceResponseData result = await GetRequestWithParameters(recordId, searcher, new[] { query });

            IReadOnlyCollection <ThingCollection> resultSet = _thingDeserializer.Deserialize(result, searcher);

            // Check in case HealthVault returned invalid data.
            if (resultSet.Count == 0)
            {
                return(default(T));
            }

            if (resultSet.Count > 1 || resultSet.ElementAt(0).Count > 1)
            {
                throw new MoreThanOneThingException(Resources.GetSingleThingTooManyResults);
            }

            if (resultSet.Count == 1)
            {
                ThingCollection resultGroup = resultSet.ElementAt(0);

                if (resultGroup.Count == 1)
                {
                    return((T)resultGroup[0]);
                }
            }

            return(default(T));
        }
Exemple #29
0
        private void InitializeResponse(params string[] samples)
        {
            _client = new ThingClient(_connection, new ThingDeserializer(_connection, _itemTypeManager));
            _connection.CreateThingClient().Returns(_client);

            var responseData = new List <HealthServiceResponseData>();

            foreach (string sample in samples)
            {
                var infoReader = XmlReader.Create(new StringReader(sample), SDKHelper.XmlReaderSettings);

                infoReader.NameTable.Add("wc");
                infoReader.ReadToFollowing("wc:info");

                var response = new HealthServiceResponseData
                {
                    InfoNavigator = new XPathDocument(new StringReader(sample)).CreateNavigator(),
                };

                responseData.Add(response);
            }

            if (responseData.Count == 1)
            {
                _connection.ExecuteAsync(
                    Arg.Any <HealthVaultMethods>(),
                    Arg.Any <int>(),
                    Arg.Any <string>(),
                    Arg.Any <Guid?>(),
                    Arg.Any <Guid?>()).Returns(responseData[0]);
            }
            else
            {
                _connection.ExecuteAsync(
                    Arg.Any <HealthVaultMethods>(),
                    Arg.Any <int>(),
                    Arg.Any <string>(),
                    Arg.Any <Guid?>(),
                    Arg.Any <Guid?>()).Returns(responseData[0], responseData.Skip(1).ToArray());
            }
        }
        /// <summary>
        /// Gets the permissions which the authenticated person
        /// has when using the calling application for the specified item types
        /// in this health record as well as the other permission settings such as MeaningfulUseOptIn.
        /// </summary>
        /// <param name="connection">
        /// The connection to use to access the data.
        /// </param>
        /// <param name="accessor">
        /// The record to use.
        /// </param>
        /// <param name="healthRecordItemTypeIds">
        /// A collection of uniqueidentifiers to identify the health record
        /// item types, for which the permissions are being queried.
        /// </param>
        /// <returns>
        /// A <see cref="HealthRecordPermissions"/> object
        /// which contains a collection of <see cref="ThingTypePermission"/> objects and
        /// other permission settings.
        /// </returns>
        ///
        /// <remarks>
        /// If the list of thing types is empty, an empty list is
        /// returned for <see cref="HealthRecordPermissions"/> object's ItemTypePermissions property.
        /// If for a thing type, the person has
        /// neither online access nor offline access permissions,
        /// ThingTypePermission object is not returned for that
        /// thing type.
        /// </remarks>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="healthRecordItemTypeIds"/> is <b>null</b>.
        /// </exception>
        ///
        /// <exception cref="HealthServiceException">
        /// There is an error in the server request.
        /// </exception>
        ///
        public virtual async Task <HealthRecordPermissions> QueryRecordPermissionsAsync(
            IHealthVaultConnection connection,
            HealthRecordAccessor accessor,
            IList <Guid> healthRecordItemTypeIds)
        {
            Validator.ThrowIfArgumentNull(healthRecordItemTypeIds, nameof(healthRecordItemTypeIds), Resources.CtorhealthRecordItemTypeIdsArgumentNull);

            string parameters = GetQueryPermissionsParametersXml(healthRecordItemTypeIds);

            HealthServiceResponseData responseData = await connection.ExecuteAsync(HealthVaultMethods.QueryPermissions, 1, parameters).ConfigureAwait(false);

            XPathNavigator infoNav =
                responseData.InfoNavigator.SelectSingleNode(
                    GetQueryPermissionsInfoXPathExpression(
                        responseData.InfoNavigator));

            HealthRecordPermissions recordPermissions         = new HealthRecordPermissions();
            XPathNodeIterator       thingTypePermissionsNodes =
                infoNav.Select("thing-type-permission");

            foreach (XPathNavigator nav in thingTypePermissionsNodes)
            {
                ThingTypePermission thingTypePermissions =
                    ThingTypePermission.CreateFromXml(nav);
                recordPermissions.ItemTypePermissions.Add(thingTypePermissions);
            }

            XPathNavigator valueNav = infoNav.SelectSingleNode("other-settings/meaningfuluse-opt-in");

            if (valueNav != null)
            {
                recordPermissions.MeaningfulUseOptIn = valueNav.ValueAsBoolean;
            }
            else
            {
                recordPermissions.MeaningfulUseOptIn = null;
            }

            return(recordPermissions);
        }
        private static ReadOnlyCollection<VocabularyKey> CreateVocabularyKeysFromResponse(
            string methodNameNSSuffix,
            HealthServiceResponseData response)
        {
            XPathNavigator infoNav =
                response.InfoNavigator.SelectSingleNode(
                    Vocabulary.GetInfoXPathExpression(
                        methodNameNSSuffix,
                        response.InfoNavigator));

            List<VocabularyKey> vocabularyKeys = new List<VocabularyKey>();

            XPathNodeIterator vocabKeyIter = infoNav.Select("vocabulary-key");
            foreach (XPathNavigator vocabKeyNav in vocabKeyIter)
            {
                VocabularyKey vocabularyKey = new VocabularyKey();
                vocabularyKey.ParseXml(vocabKeyNav);
                vocabularyKeys.Add(vocabularyKey);
            }
            return new ReadOnlyCollection<VocabularyKey>(vocabularyKeys);
        }
        private static VocabularyItemCollection CreateVocabularyItemCollectionFromResponse(
            string methodNSSuffix,
            HealthServiceResponseData response)
        {
            XPathNavigator infoNav =
                response.InfoNavigator.SelectSingleNode(
                    Vocabulary.GetInfoXPathExpression(
                        methodNSSuffix,
                        response.InfoNavigator));

            XPathNavigator vocabNav = infoNav.SelectSingleNode("code-set-result");
            VocabularyItemCollection itemCollection = new VocabularyItemCollection();
            itemCollection.PopulateFromXml(vocabNav);
            return itemCollection;
        }
        private static void ParseGetUpdatedRecordsForApplicationResponse(
            HealthServiceResponseData response,
            out IList<HealthRecordUpdateInfo> healthRecordUpdateInfos)
        {
            healthRecordUpdateInfos = new List<HealthRecordUpdateInfo>();

            XPathNodeIterator iterator = response.InfoNavigator.Select("record-id");
            foreach (XPathNavigator navigator in iterator)
            {
                healthRecordUpdateInfos.Add(ParseHealthRecordUpdateInfo(navigator));
            }
        }