Skip to content

Commit 18dbc6b

Browse files
angelcaamaliennae
andauthored
fix(healthcare): enforce json responseType and fix IAM payloads in FHIR samples (#4307)
* fix(healthcare): set responseType to JSON instead of Buffer * fix(healthcare): set responseType to JSON instead of Buffer * fix(healthcare): set responseType to JSON instead of Buffer * fix(healthcare): set responseType to JSON instead of Buffer * fix(healthcare): Fix test for delete resource * fix(healthcare): Fix response type * fix(healthcare): set responseType to JSON instead of Buffer * fix(healthcare): replace fixed sleep with polling for LRO and improve error logging * refactor(fhir): improve API response handling and fix test failures Configured fhirStore requests with responseType: 'json' for automatic parsing, resolving Node 20 ESM/Blob issues. Additionally, fixed the members array syntax in IAM policy payloads. * fix(fhir): add missing Content-Type header to POST request * fix(healthcare): remove mocha parallel execution to prevent npm install race conditions in CI * fix(healthcare): apply code review feedback --------- Co-authored-by: Jennifer Davis <sigje@google.com>
1 parent 25027b8 commit 18dbc6b

12 files changed

Lines changed: 102 additions & 44 deletions

healthcare/fhir/createFhirResource.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function main(
3030
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3131
}),
3232
headers: {'Content-Type': 'application/fhir+json'},
33+
responseType: 'json',
3334
});
3435

3536
async function createFhirResource() {

healthcare/fhir/deleteFhirResource.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const main = (
2929
auth: new google.auth.GoogleAuth({
3030
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3131
}),
32+
responseType: 'json',
3233
});
3334

3435
const deleteFhirResource = async () => {
@@ -46,10 +47,14 @@ const main = (
4647
// fails, the server returns a 200 OK HTTP status code. To check that the
4748
// resource was successfully deleted, search for or get the resource and
4849
// see if it exists.
49-
await healthcare.projects.locations.datasets.fhirStores.fhir.delete(
50-
request
51-
);
52-
console.log('Deleted FHIR resource');
50+
try {
51+
await healthcare.projects.locations.datasets.fhirStores.fhir.delete(
52+
request
53+
);
54+
console.log(`Deleted FHIR resource: ${resourceId}`);
55+
} catch (error) {
56+
console.error('Error deleting FHIR resource:', error.message || error);
57+
}
5358
};
5459

5560
deleteFhirResource();

healthcare/fhir/deleteFhirResourcePurge.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const main = (
2929
auth: new google.auth.GoogleAuth({
3030
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3131
}),
32+
responseType: 'json',
3233
});
3334

3435
const deleteFhirResourcePurge = async () => {
@@ -42,10 +43,14 @@ const main = (
4243
const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}/fhir/${resourceType}/${resourceId}`;
4344
const request = {name};
4445

45-
await healthcare.projects.locations.datasets.fhirStores.fhir.ResourcePurge(
46-
request
47-
);
48-
console.log('Deleted all historical versions of resource');
46+
try {
47+
await healthcare.projects.locations.datasets.fhirStores.fhir.ResourcePurge(
48+
request
49+
);
50+
console.log(`Purged all historical versions of resource: ${resourceId}`);
51+
} catch (error) {
52+
console.error('Error purging FHIR resource:', error.message || error);
53+
}
4954
};
5055

5156
deleteFhirResourcePurge();

healthcare/fhir/exportFhirResources.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const main = (
2828
auth: new google.auth.GoogleAuth({
2929
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3030
}),
31+
responseType: 'json',
3132
});
3233
const sleep = ms => {
3334
return new Promise(resolve => setTimeout(resolve, ms));
@@ -51,23 +52,33 @@ const main = (
5152
},
5253
};
5354

54-
const operation =
55-
await healthcare.projects.locations.datasets.fhirStores.export(request);
56-
const operationName = operation.data.name;
55+
try {
56+
const operation =
57+
await healthcare.projects.locations.datasets.fhirStores.export(request);
58+
const operationName = operation.data.name;
5759

58-
// Wait ten seconds for the LRO to finish
59-
await sleep(10000);
60+
let done = false;
61+
let operationStatus;
6062

61-
// Check the LRO's status
62-
const operationStatus =
63-
await healthcare.projects.locations.datasets.operations.get({
64-
name: operationName,
65-
});
63+
while (!done) {
64+
console.log('Waiting for operation to complete...');
65+
await sleep(5000);
6666

67-
if (typeof operationStatus.data.metadata.counter !== 'undefined') {
68-
console.log('Exported FHIR resources successfully');
69-
} else {
70-
console.log('Export failed');
67+
operationStatus =
68+
await healthcare.projects.locations.datasets.operations.get({
69+
name: operationName,
70+
});
71+
72+
done = operationStatus.data.done;
73+
}
74+
75+
if (operationStatus.data.error) {
76+
console.log('Export failed with error:', operationStatus.data.error);
77+
} else {
78+
console.log('Exported FHIR resources successfully');
79+
}
80+
} catch (error) {
81+
console.error('Error exporting FHIR resources:', error.message || error);
7182
}
7283
};
7384

healthcare/fhir/getFhirResourceHistory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const main = (
3030
auth: new google.auth.GoogleAuth({
3131
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3232
}),
33+
responseType: 'json',
3334
});
3435

3536
const getFhirResourceHistory = async () => {

healthcare/fhir/getFhirStoreIamPolicy.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const main = (
2727
auth: new google.auth.GoogleAuth({
2828
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
2929
}),
30+
responseType: 'json',
3031
});
3132

3233
const getFhirStoreIamPolicy = async () => {
@@ -38,14 +39,21 @@ const main = (
3839
const resource_ = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`;
3940
const request = {resource_};
4041

41-
const fhirStore =
42-
await healthcare.projects.locations.datasets.fhirStores.getIamPolicy(
43-
request
42+
try {
43+
const fhirStore =
44+
await healthcare.projects.locations.datasets.fhirStores.getIamPolicy(
45+
request
46+
);
47+
console.log(
48+
'Got FHIR store IAM policy:',
49+
JSON.stringify(fhirStore.data, null, 2)
4450
);
45-
console.log(
46-
'Got FHIR store IAM policy:',
47-
JSON.stringify(fhirStore.data, null, 2)
48-
);
51+
} catch (error) {
52+
console.error(
53+
'Error getting FHIR store IAM policy:',
54+
error.message || error
55+
);
56+
}
4957
};
5058

5159
getFhirStoreIamPolicy();

healthcare/fhir/listFhirResourceHistory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const main = (
2929
auth: new google.auth.GoogleAuth({
3030
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3131
}),
32+
responseType: 'json',
3233
});
3334

3435
const listFhirResourceHistory = async () => {

healthcare/fhir/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"node": ">=12.0.0"
1010
},
1111
"scripts": {
12-
"test": "c8 mocha -p -j 2 system-test/*.test.js --timeout=60000"
12+
"test": "c8 mocha system-test/*.test.js --timeout=60000"
1313
},
1414
"devDependencies": {
1515
"@google-cloud/pubsub": "^4.0.0",

healthcare/fhir/patchFhirStore.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const main = (
2828
auth: new google.auth.GoogleAuth({
2929
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
3030
}),
31+
responseType: 'json',
3132
});
3233

3334
const patchFhirStore = async () => {
@@ -50,10 +51,16 @@ const main = (
5051
},
5152
};
5253

53-
await healthcare.projects.locations.datasets.fhirStores.patch(request);
54-
console.log(
55-
`Patched FHIR store ${fhirStoreId} with Cloud Pub/Sub topic ${pubsubTopic}`
56-
);
54+
try {
55+
const response =
56+
await healthcare.projects.locations.datasets.fhirStores.patch(request);
57+
console.log(
58+
`Patched FHIR store ${fhirStoreId} with Cloud Pub/Sub topic ${pubsubTopic}`
59+
);
60+
console.log(JSON.stringify(response.data, null, 2));
61+
} catch (error) {
62+
console.error('Error patching FHIR store:', error.message || error);
63+
}
5764
};
5865

5966
patchFhirStore();

healthcare/fhir/searchFhirResourcesPost.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ const main = (
2828
const searchFhirResourcesPost = async () => {
2929
const auth = new GoogleAuth({
3030
scopes: 'https://www.googleapis.com/auth/cloud-platform',
31-
// Set application/fhir+json header because this is a POST request.
32-
headers: {'Content-Type': 'application/fhir+json'},
3331
});
3432
// TODO(developer): uncomment these lines before running the sample
3533
// const cloudRegion = 'us-central1';
@@ -44,11 +42,27 @@ const main = (
4442
// Patient with the last name "Smith", set resourceType to "Patient" and
4543
// specify the following params:
4644
// params = {'family:exact' : 'Smith'};
47-
const client = await auth.getClient();
48-
const response = await client.request({url, method: 'POST', params});
49-
const resources = response.data.entry;
50-
console.log(`Resources found: ${resources.length}`);
51-
console.log(JSON.stringify(resources, null, 2));
45+
46+
try {
47+
const client = await auth.getClient();
48+
const response = await client.request({
49+
url,
50+
method: 'POST',
51+
headers: {
52+
'Content-Type': 'application/fhir+json',
53+
},
54+
params,
55+
responseType: 'json',
56+
});
57+
const resources = response.data.entry || [];
58+
console.log('Resources found: ' + resources.length);
59+
console.log(JSON.stringify(resources, null, 2));
60+
} catch (error) {
61+
console.error(
62+
`Error searching ${resourceType} resources:`,
63+
error.response ? error.response.data : error.message
64+
);
65+
}
5266
};
5367

5468
searchFhirResourcesPost();

0 commit comments

Comments
 (0)