diff --git a/healthcare/fhir/README.md b/healthcare/fhir/README.md new file mode 100644 index 0000000000..e40f55da11 --- /dev/null +++ b/healthcare/fhir/README.md @@ -0,0 +1,71 @@ +Google Cloud Platform logo + +# Cloud Healthcare API Node.js FHIR store and FHIR resource example + +This sample app demonstrates FHIR store and FHIR resource management for the Cloud Healthcare API. + +# Setup + +Run the following command to install the library dependencies for Node.js: + + npm install + +# Running the samples + +## FHIR stores + + fhir_stores.js + + Commands: + fhir_stores.js createFhirStore Creates a new FHIR store within the parent dataset. + fhir_stores.js deleteFhirStore Deletes the FHIR store and removes all resources that + are contained within it. + fhir_stores.js getFhirStore Gets the specified FHIR store or returns NOT_FOUND if it + doesn't exist. + fhir_stores.js listFhirStores Lists the FHIR stores in the given dataset. + fhir_stores.js patchFhirStore Updates the FHIR store. + + fhir_stores.js getMetadata Gets the capabilities statement for the FHIR store. + + Options: + --version Show version number [boolean] + --apiKey, -a The API key used for discovering the API. + [string] + --cloudRegion, -c [string] [default: "us-central1"] + --projectId, -p The Project ID to use. Defaults to the value of the GCLOUD_PROJECT or GOOGLE_CLOUD_PROJECT + environment variables. [string] + --serviceAccount, -s The path to your service credentials JSON. + [string] + --help Show help [boolean] + + +## FHIR resources + + Commands: + fhir_resources.js createResource Creates a new resource in a FHIR store. + + fhir_resources.js updateResource Updates an existing resource in a FHIR store. + + fhir_resources.js patchResource Patches an existing resource in a FHIR store. + + fhir_resources.js deleteResource Deletes a FHIR resource or returns NOT_FOUND if it + doesn't exist. + fhir_resources.js getResource Gets a FHIR resource. + + fhir_resources.js searchResourcesGet Searches resources in the given FHIR store using the + searchResources GET method. + fhir_resources.js searchResourcesPost Searches resources in the given FHIR store using the + _search POST method. + fhir_resources.js getPatientEverything Gets all the resources in the patient compartment. + + + Options: + --version Show version number [boolean] + --cloudRegion, -c [string] [default: "us-central1"] + --projectId, -p The Project ID to use. Defaults to the value of the GCLOUD_PROJECT or GOOGLE_CLOUD_PROJECT + environment variables. [string] + --serviceAccount, -s The path to your service credentials JSON. + [string] + --help Show help [boolean] + +For more information, see https://cloud.google.com/healthcare/docs diff --git a/healthcare/fhir/fhir_resources.js b/healthcare/fhir/fhir_resources.js new file mode 100644 index 0000000000..2013ba3725 --- /dev/null +++ b/healthcare/fhir/fhir_resources.js @@ -0,0 +1,435 @@ +/** + * Copyright 2018, Google, LLC + * Licensed under the Apache License, Version 2.0 (the `License`); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an `AS IS` BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const { GoogleToken } = require('gtoken'); +const request = require('request-promise'); + +const BASE_URL = 'https://healthcare.googleapis.com/v1alpha'; + +// [START healthcare_get_token] +function getToken (serviceAccountJson, cb) { + const gtoken = new GoogleToken({ + keyFile: `${serviceAccountJson}`, + scope: ['https://www.googleapis.com/auth/cloud-platform'] // or space-delimited string of scopes + }); + + gtoken.getToken(function (err, token) { + if (err) { + console.log('ERROR: ', err); + return; + } + cb(token); + }); +} +// [END healthcare_get_token] + +// [START healthcare_create_fhir_resource] +function createResource (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcePath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}`; + + const postData = { + 'resourceType': resourceType + }; + + const options = { + url: resourcePath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/fhir+json; charset=utf-8' + }, + body: postData, + json: true, + method: 'POST' + }; + + request(options) + .then(resource => { + console.log(`Created resource ${resourceType} with ID ${resource.id}.`); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_create_fhir_resource] + +// [START healthcare_update_fhir_resource] +function updateResource (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType, resourceId) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + // const resourceId = 'd64a85ae-da1b-4a10-0eb8-cfaf55bdbe3f'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcePath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}/${resourceId}`; + + const patientData = { + 'resourceType': resourceType, + 'id': resourceId, + 'active': true + }; + + const options = { + url: resourcePath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/fhir+json; charset=utf-8' + }, + body: patientData, + json: true, + method: 'PUT' + }; + + request(options) + .then(() => { + console.log(`Updated ${resourceType} with ID ${resourceId}`); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_update_fhir_resource] + +// [START healthcare_patch_fhir_resource] +function patchResource (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType, resourceId) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + // const resourceId = 'd64a85ae-da1b-4a10-0eb8-cfaf55bdbe3f'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcePath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}/${resourceId}`; + + const patchOperations = [{ 'op': 'replace', 'path': '/active', 'value': false }]; + + const options = { + url: resourcePath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json-patch+json' + }, + body: patchOperations, + json: true, + method: 'PATCH' + }; + + request(options) + .then(() => { + console.log(`Patched ${resourceType} with ID ${resourceId}`); + }) + .catch(err => { + console.log('ERROR:', err.message); + }); +} +// [END healthcare_patch_fhir_resource] + +// [START healthcare_delete_fhir_resource] +function deleteResource (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType, resourceId) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + // const resourceId = 'd64a85ae-da1b-4a10-0eb8-cfaf55bdbe3f'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcePath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}/${resourceId}`; + + const options = { + url: resourcePath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/fhir+json; charset=utf-8' + }, + json: true, + method: 'DELETE' + }; + + request(options) + .then(() => { + console.log(`Deleted ${resourceType} with ID ${resourceId}.`); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_delete_fhir_resource] + +// [START healthcare_get_fhir_resource] +function getResource (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType, resourceId) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + // const resourceId = 'd64a85ae-da1b-4a10-0eb8-cfaf55bdbe3f'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcePath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}/${resourceId}`; + + const options = { + url: resourcePath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/fhir+json; charset=utf-8' + }, + json: true + }; + + request(options) + .then(results => { + console.log(`Got ${resourceType} resource:\n${JSON.stringify(results, null, 2)}`); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_get_fhir_resource] + +// [START healthcare_search_fhir_resources_get] +function searchResourcesGet (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcesPath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}`; + + const options = { + url: resourcesPath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/fhir+json; charset=utf-8' + }, + json: true + }; + + request(options) + .then(results => { + console.log(JSON.stringify(results, null, 2)); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_search_fhir_resources_get] + +// [START healthcare_search_fhir_resources_post] +function searchResourcesPost (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceType) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceType = 'Patient'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const resourcesPath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/${resourceType}/_search`; + + const options = { + url: resourcesPath, + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/fhir+json; charset=utf-8' + }, + json: true, + method: 'POST' + }; + + request(options) + .then(results => { + console.log(JSON.stringify(results, null, 2)); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_search_fhir_resources_post] + +// [START healthcare_fhir_get_patient_everything] +function getPatientEverything (token, projectId, cloudRegion, datasetId, fhirStoreId, resourceId) { + // Token retrieved in callback + // getToken(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const resourceId = 'd64a85ae-da1b-4a10-0eb8-cfaf55bdbe3f'; + const parentName = `${BASE_URL}/projects/${projectId}/locations/${cloudRegion}`; + + const fhirStorePath = `${parentName}/datasets/${datasetId}/fhirStores/${fhirStoreId}/resources/Patient/${resourceId}/$everything`; + + const options = { + url: fhirStorePath, + headers: { + 'authorization': `Bearer ${token}` + }, + json: true + }; + + request(options) + .then(results => { + console.log(`Got all resources in patient ${resourceId} compartment:`); + console.log(results); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_fhir_get_patient_everything] + +require(`yargs`) // eslint-disable-line + .demand(1) + .options({ + cloudRegion: { + alias: 'c', + default: 'us-central1', + requiresArg: true, + type: 'string' + }, + projectId: { + alias: 'p', + default: process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT, + description: 'The Project ID to use. Defaults to the value of the GCLOUD_PROJECT or GOOGLE_CLOUD_PROJECT environment variables.', + requiresArg: true, + type: 'string' + }, + serviceAccount: { + alias: 's', + default: process.env.GOOGLE_APPLICATION_CREDENTIALS, + description: 'The path to your service credentials JSON.', + requiresArg: true, + type: 'string' + } + }) + .command( + `createResource `, + `Creates a new resource in a FHIR store.`, + {}, + (opts) => { + const cb = function (token) { + createResource(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `updateResource `, + `Updates an existing resource in a FHIR store.`, + {}, + (opts) => { + const cb = function (token) { + updateResource(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType, opts.resourceId); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `patchResource `, + `Patches an existing resource in a FHIR store.`, + {}, + (opts) => { + const cb = function (token) { + patchResource(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType, opts.resourceId); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `deleteResource `, + `Deletes a FHIR resource or returns NOT_FOUND if it doesn't exist.`, + {}, + (opts) => { + const cb = function (token) { + deleteResource(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType, opts.resourceId); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `getResource `, + `Gets a FHIR resource.`, + {}, + (opts) => { + const cb = function (token) { + getResource(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType, opts.resourceId); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `searchResourcesGet `, + `Searches resources in the given FHIR store using the searchResources GET method.`, + {}, + (opts) => { + const cb = function (token) { + searchResourcesGet(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `searchResourcesPost `, + `Searches resources in the given FHIR store using the _search POST method.`, + {}, + (opts) => { + const cb = function (token) { + searchResourcesPost(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceType); + }; + getToken(opts.serviceAccount, cb); + } + ) + .command( + `getPatientEverything `, + `Gets all the resources in the patient compartment.`, + {}, + (opts) => { + const cb = function (token) { + getPatientEverything(token, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.resourceId); + }; + getToken(opts.serviceAccount, cb); + } + ) + .wrap(120) + .recommendCommands() + .epilogue(`For more information, see https://cloud.google.com/healthcare/docs`) + .help() + .strict() + .argv; diff --git a/healthcare/fhir/fhir_stores.js b/healthcare/fhir/fhir_stores.js new file mode 100644 index 0000000000..8a173ce293 --- /dev/null +++ b/healthcare/fhir/fhir_stores.js @@ -0,0 +1,290 @@ +/** + * Copyright 2018, Google, LLC + * Licensed under the Apache License, Version 2.0 (the `License`); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an `AS IS` BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const {google} = require('googleapis'); + +// [START healthcare_create_fhir_store] +function createFhirStore (client, projectId, cloudRegion, datasetId, fhirStoreId) { + // Client retrieved in callback + // getClient(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + const parentName = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}`; + + const request = {parent: parentName, fhirStoreId: fhirStoreId}; + + client.projects.locations.datasets.fhirStores.create(request) + .then(() => { + console.log(`Created FHIR store: ${fhirStoreId}`); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_create_fhir_store] + +// [START healthcare_delete_fhir_store] +function deleteFhirStore (client, projectId, cloudRegion, datasetId, fhirStoreId) { + // Client retrieved in callback + // getClient(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + const fhirStoreName = + `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`; + + const request = {name: fhirStoreName}; + + client.projects.locations.datasets.fhirStores.delete(request) + .then(() => { + console.log(`Deleted FHIR store: ${fhirStoreId}`); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_delete_fhir_store] + +// [START healthcare_get_fhir_store] +function getFhirStore (client, projectId, cloudRegion, datasetId, fhirStoreId) { + // Client retrieved in callback + // getClient(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + const fhirStoreName = + `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`; + + const request = {name: fhirStoreName}; + + client.projects.locations.datasets.fhirStores.get(request) + .then(results => { + console.log('Got FHIR store:\n', results['data']); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_get_fhir_store] + +// [START healthcare_list_fhir_stores] +function listFhirStores (client, projectId, cloudRegion, datasetId) { + // Client retrieved in callback + // getClient(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + const parentName = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}`; + + const request = {parent: parentName}; + + client.projects.locations.datasets.fhirStores.list(request) + .then(results => { + console.log('FHIR stores:\n', results['data']['fhirStores']); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_list_fhir_stores] + +// [START healthcare_patch_fhir_store] +function patchFhirStore (client, projectId, cloudRegion, datasetId, fhirStoreId, pubsubTopic) { + // Client retrieved in callback + // getClient(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + // const pubsubTopic = 'my-topic' + const fhirStoreName = + `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`; + + const request = { + name: fhirStoreName, + updateMask: 'notificationConfig', + resource: { 'notificationConfig': { pubsubTopic: `projects/${projectId}/locations/${cloudRegion}/topics/${pubsubTopic}` } } + }; + + client.projects.locations.datasets.fhirStores.patch(request) + .then(results => { + console.log( + 'Patched FHIR store with Cloud Pub/Sub topic', results['data']['notificationConfig']['pubsubTopic']); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_patch_fhir_store] + +// [START healthcare_get_fhir_store_metadata] +function getMetadata (client, projectId, cloudRegion, datasetId, fhirStoreId) { + // Client retrieved in callback + // getClient(serviceAccountJson, function(cb) {...}); + // const cloudRegion = 'us-central1'; + // const projectId = 'adjective-noun-123'; + // const datasetId = 'my-dataset'; + // const fhirStoreId = 'my-fhir-store'; + const fhirStoreName = + `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`; + + const request = {name: fhirStoreName}; + + client.projects.locations.datasets.fhirStores.getMetadata(request) + .then(results => { + console.log(`Capabilities statement for FHIR store ${fhirStoreId}:`); + console.log(results); + }) + .catch(err => { + console.error(err); + }); +} +// [END healthcare_get_fhir_store_metadata] + +// Returns an authorized API client by discovering the Healthcare API with +// the provided API key. +// [START healthcare_get_client] +function getClient (apiKey, serviceAccountJson, cb) { + const API_VERSION = 'v1alpha'; + const DISCOVERY_API = 'https://healthcare.googleapis.com/$discovery/rest'; + + google.auth + .getClient({scopes: ['https://www.googleapis.com/auth/cloud-platform']}) + .then(authClient => { + const discoveryUrl = `${DISCOVERY_API}?labels=CHC_ALPHA&version=${ + API_VERSION}&key=${apiKey}`; + + google.options({auth: authClient}); + + google.discoverAPI(discoveryUrl) + .then((client) => { + cb(client); + }) + .catch((err) => { + console.error(err); + }); + }); +} +// [END healthcare_get_client] + +require(`yargs`) // eslint-disable-line + .demand(1) + .options({ + apiKey: { + alias: 'a', + default: process.env.API_KEY, + description: 'The API key used for discovering the API.', + requiresArg: true, + type: 'string' + }, + cloudRegion: { + alias: 'c', + default: 'us-central1', + requiresArg: true, + type: 'string' + }, + projectId: { + alias: 'p', + default: process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT, + description: 'The Project ID to use. Defaults to the value of the GCLOUD_PROJECT or GOOGLE_CLOUD_PROJECT environment variables.', + requiresArg: true, + type: 'string' + }, + serviceAccount: { + alias: 's', + default: process.env.GOOGLE_APPLICATION_CREDENTIALS, + description: 'The path to your service credentials JSON.', + requiresArg: true, + type: 'string' + } + }) + .command( + `createFhirStore `, + `Creates a new FHIR store within the parent dataset.`, + {}, + (opts) => { + const cb = function (client) { + createFhirStore(client, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId); + }; + getClient(opts.apiKey, opts.serviceAccount, cb); + } + ) + .command( + `deleteFhirStore `, + `Deletes the FHIR store and removes all resources that are contained within it.`, + {}, + (opts) => { + const cb = function (client) { + deleteFhirStore(client, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId); + }; + getClient(opts.apiKey, opts.serviceAccount, cb); + } + ) + .command( + `getFhirStore `, + `Gets the specified FHIR store or returns NOT_FOUND if it doesn't exist.`, + {}, + (opts) => { + const cb = function (client) { + getFhirStore(client, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId); + }; + getClient(opts.apiKey, opts.serviceAccount, cb); + } + ) + .command( + `listFhirStores `, + `Lists the FHIR stores in the given dataset.`, + {}, + (opts) => { + const cb = function (client) { + listFhirStores(client, opts.projectId, opts.cloudRegion, opts.datasetId); + }; + getClient(opts.apiKey, opts.serviceAccount, cb); + } + ) + .command( + `patchFhirStore `, + `Updates the FHIR store.`, + {}, + (opts) => { + const cb = function (client) { + patchFhirStore(client, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId, opts.pubsubTopic); + }; + getClient(opts.apiKey, opts.serviceAccount, cb); + } + ) + .command( + `getMetadata `, + `Gets the capabilities statement for a FHIR store.`, + {}, + (opts) => { + const cb = function (client) { + getMetadata(client, opts.projectId, opts.cloudRegion, opts.datasetId, opts.fhirStoreId); + }; + getClient(opts.apiKey, opts.serviceAccount, cb); + } + ) + .wrap(120) + .recommendCommands() + .epilogue(`For more information, see https://cloud.google.com/healthcare/docs`) + .help() + .strict() + .argv; diff --git a/healthcare/fhir/package.json b/healthcare/fhir/package.json new file mode 100644 index 0000000000..605240d7a6 --- /dev/null +++ b/healthcare/fhir/package.json @@ -0,0 +1,38 @@ +{ + "name": "nodejs-docs-samples-healthcare", + "version": "0.0.1", + "private": true, + "license": "Apache-2.0", + "author": "Google LLC", + "repository": "GoogleCloudPlatform/nodejs-docs-samples", + "engines": { + "node": ">=6.0.0" + }, + "scripts": { + "test": "ava -T 1m --verbose system-test/*.test.js" + }, + "devDependencies": { + "@google-cloud/nodejs-repo-tools": "^2.3.1", + "ava": "^0.25.0" + }, + "dependencies": { + "googleapis": "^32.0.0", + "uuid": "^3.3.2", + "yargs": "^12.0.1", + "gtoken": "^2.3.0", + "request": "^2.87.0", + "request-promise": "^4.2.2" + }, + "cloud-repo-tools": { + "requiresKeyFile": true, + "requiresProjectId": true, + "test": { + "build": { + "requiredEnvVars": [ + "API_KEY", + "GCLOUD_PROJECT" + ] + } + } + } +} diff --git a/healthcare/fhir/system-test/fhir_resources.test.js b/healthcare/fhir/system-test/fhir_resources.test.js new file mode 100644 index 0000000000..90c233657f --- /dev/null +++ b/healthcare/fhir/system-test/fhir_resources.test.js @@ -0,0 +1,92 @@ +/** + * Copyright 2018, Google, LLC + * Licensed under the Apache License, Version 2.0 (the `License`); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an `AS IS` BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const path = require(`path`); +const test = require(`ava`); +const tools = require(`@google-cloud/nodejs-repo-tools`); +const uuid = require(`uuid`); + +const cmdDataset = `node datasets.js`; +const cmdFhirStores = `node fhir_stores.js`; +const cmd = 'node fhir_resources.js'; +const cwd = path.join(__dirname, '..'); +const cwdDatasets = path.join(__dirname, `../../datasets`); +const datasetId = `nodejs-docs-samples-test-${uuid.v4()}`.replace(/-/gi, '_'); +const fhirStoreId = + `nodejs-docs-samples-test-fhir-store${uuid.v4()}`.replace(/-/gi, '_'); +const resourceType = 'Patient'; +let resourceId; + +test.before(tools.checkCredentials); +test.before(async () => { + return tools.runAsync(`${cmdDataset} createDataset ${datasetId}`, cwdDatasets) + .then((results) => { + console.log(results); + return results; + }); +}); +test.after.always(async () => { + try { + await tools.runAsync(`${cmdDataset} deleteDataset ${datasetId}`, cwdDatasets); + } catch (err) { + } // Ignore error +}); + +test.serial(`should create a FHIR resource`, async (t) => { + await tools.runAsync(`${cmdFhirStores} createFhirStore ${datasetId} ${fhirStoreId}`, cwd); + const output = await tools.runAsync( + `${cmd} createResource ${datasetId} ${fhirStoreId} ${resourceType}`, cwd); + const createdMessage = + new RegExp(`Created resource ${resourceType} with ID (.*).`); + t.regex(output, createdMessage); + resourceId = createdMessage.exec(output)[1]; +}); + +test.serial(`should get a FHIR resource`, async (t) => { + const output = await tools.runAsync( + `${cmd} getResource ${datasetId} ${fhirStoreId} ${resourceType} ${ + resourceId}`, + cwd); + t.regex(output, new RegExp(`Got ${resourceType} resource`)); +}); + +test.serial(`should update a FHIR resource`, async (t) => { + const output = await tools.runAsync( + `${cmd} updateResource ${datasetId} ${fhirStoreId} ${resourceType} ${ + resourceId}`, + cwd); + t.is(output, `Updated ${resourceType} with ID ${resourceId}`); +}); + +test.serial(`should patch a FHIR resource`, async (t) => { + const output = await tools.runAsync( + `${cmd} patchResource ${datasetId} ${fhirStoreId} ${resourceType} ${ + resourceId}`, + cwd); + t.is(output, `Patched ${resourceType} with ID ${resourceId}`); +}); + +test.serial(`should delete a FHIR resource`, async (t) => { + const output = await tools.runAsync( + `${cmd} deleteResource ${datasetId} ${fhirStoreId} ${resourceType} ${ + resourceId}`, + cwd); + t.is(output, `Deleted ${resourceType} with ID ${resourceId}.`); + + // Clean up + await tools.runAsync(`${cmdFhirStores} deleteFhirStore ${datasetId} ${fhirStoreId}`, cwd); +}); diff --git a/healthcare/fhir/system-test/fhir_stores.test.js b/healthcare/fhir/system-test/fhir_stores.test.js new file mode 100644 index 0000000000..2194d87f8d --- /dev/null +++ b/healthcare/fhir/system-test/fhir_stores.test.js @@ -0,0 +1,82 @@ +/** + * Copyright 2018, Google, LLC + * Licensed under the Apache License, Version 2.0 (the `License`); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an `AS IS` BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const path = require(`path`); +const test = require(`ava`); +const tools = require(`@google-cloud/nodejs-repo-tools`); +const uuid = require(`uuid`); + +const cmdDataset = `node datasets.js`; +const cmd = `node fhir_stores.js`; +const cwdDatasets = path.join(__dirname, `../../datasets`); +const cwd = path.join(__dirname, `..`); +const datasetId = `nodejs-docs-samples-test-${uuid.v4()}`.replace(/-/gi, '_'); +const fhirStoreId = + `nodejs-docs-samples-test-fhir-store${uuid.v4()}`.replace(/-/gi, '_'); +const pubsubTopic = + `nodejs-docs-samples-test-pubsub${uuid.v4()}`.replace(/-/gi, '_'); + +test.before(tools.checkCredentials); +test.before(async () => { + return tools.runAsync(`${cmdDataset} createDataset ${datasetId}`, cwdDatasets) + .then((results) => { + console.log(results); + return results; + }); +}); +test.after.always(async () => { + try { + await tools.runAsync(`${cmdDataset} deleteDataset ${datasetId}`, cwdDatasets); + } catch (err) { + } // Ignore error +}); + +test.serial(`should create a FHIR store`, async t => { + const output = await tools.runAsync( + `${cmd} createFhirStore ${datasetId} ${fhirStoreId}`, cwd); + t.regex(output, /Created FHIR store/); +}); + +test.serial(`should get a FHIR store`, async t => { + const output = await tools.runAsync( + `${cmd} getFhirStore ${datasetId} ${fhirStoreId}`, cwd); + t.regex(output, /Got FHIR store/); +}); + +test.serial(`should list FHIR stores`, async t => { + const output = + await tools.runAsync(`${cmd} listFhirStores ${datasetId}`, cwd); + t.regex(output, /FHIR stores/); +}); + +test.serial(`should patch a FHIR store`, async t => { + const output = await tools.runAsync( + `${cmd} patchFhirStore ${datasetId} ${fhirStoreId} ${pubsubTopic}`, cwd); + t.regex(output, /Patched FHIR store/); +}); + +test.serial(`should get FHIR store metadata`, async t => { + const output = await tools.runAsync( + `${cmd} getMetadata ${datasetId} ${fhirStoreId}`, cwd); + t.regex(output, /Capabilities statement for FHIR store/); +}); + +test(`should delete a FHIR store`, async t => { + const output = await tools.runAsync( + `${cmd} deleteFhirStore ${datasetId} ${fhirStoreId}`, cwd); + t.regex(output, /Deleted FHIR store/); +});