Skip to content

Commit

Permalink
EDD-49 adds clientId to metrics logger (#33)
Browse files Browse the repository at this point in the history
* EDD-49 adds clientId to metrics logger

* EDD-49 clientId now only applies to download initiation metrics

* EDD-49 version bump
  • Loading branch information
daniel-zamora committed Dec 13, 2023
1 parent 694690a commit 68f8118
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 6 deletions.
3 changes: 2 additions & 1 deletion docs/USE_EDD.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ In order to have your web application launch the Earthdata Download application,
This link will start a new download in Earthdata Download.

```text
earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgranule_links%3Fid%3D42%26flattenLinks%3Dtrue%26linkTypes%3Ddata&downloadId=shortName_versionId&token=Bearer mock-token
earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgranule_links%3Fid%3D42%26flattenLinks%3Dtrue%26linkTypes%3Ddata&downloadId=shortName_versionId&clientId=eed-edsc-dev-serverless-client&token=Bearer mock-token
```

#### Query Parameters
Expand All @@ -42,6 +42,7 @@ earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgran
| | authUrl | false | This is a URL where Earthdata Download can send the user to login with Earthdata Login. After logging in the user needs to be redirected to the Authentication callback. See [this document](EDL_AUTH.md) for more information on Earthdata Login authentication. |
| | eulaRedirectUrl | false | This is a URL that Earthdata Download will use as a redirect after the user is sent to Earthdata Login to accept a EULA. See [this document](EULA_CALLBACK.md) for more information on the EULA acceptance workflow. |
| | token | false | A token to be passed in the `getLinks` request. Value will be added to the `Authorization` header. |
| | clientId | false | The clientId for the application initiating the download. |

### Authentication callback

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "earthdata-download",
"version": "0.1.1",
"version": "0.1.2",
"description": "Earthdata Download is a cross-platform download manager designed to improve how users download Earth Science data. It accepts lists of files from applications like Earthdata Search (https://search.earthdata.nasa.gov/) and enables clients to offer users a streamlined experience when downloading files from their browser.",
"repository": "nasa/earthdata-download",
"homepage": "https://github.com/nasa/earthdata-download#readme",
Expand Down
77 changes: 76 additions & 1 deletion src/main/eventHandlers/__tests__/openUrl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import openUrl from '../openUrl'

import downloadStates from '../../../app/constants/downloadStates'

import metricsLogger from '../../utils/metricsLogger'
import startPendingDownloads from '../../utils/startPendingDownloads'
import startNextDownload from '../../utils/startNextDownload'

Expand All @@ -19,13 +20,64 @@ jest.mock('../../utils/startNextDownload', () => ({
default: jest.fn(() => {})
}))

jest.mock('../../utils/metricsLogger.ts', () => ({
__esModule: true,
default: jest.fn(() => {})
}))

beforeEach(() => {
MockDate.set('2023-05-01')
})

describe('openUrl', () => {
describe('when hostname is startDownload', () => {
test('calls startPendingDownloads when no update is available', async () => {
const appWindow = {}
const deepLink = 'earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgranule_links%3Fid%3D42%26flattenLinks%3Dtrue%26linkTypes%3Ddata&downloadId=shortName_versionId&clientId=eed-edsc-dev-serverless-client&token=Bearer mock-token'
const database = {
createDownload: jest.fn()
}

await openUrl({
appWindow,
currentDownloadItems: {},
database,
deepLink,
downloadIdContext: {},
downloadsWaitingForAuth: {},
updateAvailable: false
})

expect(database.createDownload).toHaveBeenCalledTimes(1)
expect(database.createDownload).toHaveBeenCalledWith(
'shortName_versionId-20230501_000000',
{
authUrl: null,
createdAt: 1682899200000,
eulaRedirectUrl: null,
getLinksToken: 'Bearer mock-token',
getLinksUrl: 'http://localhost:3000/granule_links?id=42&flattenLinks=true&linkTypes=data',
state: downloadStates.pending
}
)

expect(metricsLogger).toHaveBeenCalledTimes(1)
expect(metricsLogger).toHaveBeenCalledWith({
eventType: 'OpenUrl',
data: {
clientId: 'eed-edsc-dev-serverless-client',
downloadId: 'shortName_versionId'
}
})

expect(startPendingDownloads).toHaveBeenCalledTimes(1)
expect(startPendingDownloads).toHaveBeenCalledWith({
appWindow: {},
database
})
})

test('clientId is null', async () => {
const appWindow = {}
const deepLink = 'earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgranule_links%3Fid%3D42%26flattenLinks%3Dtrue%26linkTypes%3Ddata&downloadId=shortName_versionId&token=Bearer mock-token'
const database = {
Expand Down Expand Up @@ -55,6 +107,15 @@ describe('openUrl', () => {
}
)

expect(metricsLogger).toHaveBeenCalledTimes(1)
expect(metricsLogger).toHaveBeenCalledWith({
eventType: 'OpenUrl',
data: {
clientId: null,
downloadId: 'shortName_versionId'
}
})

expect(startPendingDownloads).toHaveBeenCalledTimes(1)
expect(startPendingDownloads).toHaveBeenCalledWith({
appWindow: {},
Expand All @@ -64,7 +125,7 @@ describe('openUrl', () => {

test('does not call startPendingDownloads when an update is available', async () => {
const appWindow = {}
const deepLink = 'earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgranule_links%3Fid%3D42%26flattenLinks%3Dtrue%26linkTypes%3Ddata&downloadId=shortName_versionId&token=Bearer mock-token'
const deepLink = 'earthdata-download://startDownload?getLinks=http%3A%2F%2Flocalhost%3A3000%2Fgranule_links%3Fid%3D42%26flattenLinks%3Dtrue%26linkTypes%3Ddata&downloadId=shortName_versionId&clientId=eed-edsc-dev-serverless-client&token=Bearer mock-token'
const database = {
createDownload: jest.fn()
}
Expand Down Expand Up @@ -92,6 +153,15 @@ describe('openUrl', () => {
}
)

expect(metricsLogger).toHaveBeenCalledTimes(1)
expect(metricsLogger).toHaveBeenCalledWith({
eventType: 'OpenUrl',
data: {
clientId: 'eed-edsc-dev-serverless-client',
downloadId: 'shortName_versionId'
}
})

expect(startPendingDownloads).toHaveBeenCalledTimes(0)
})

Expand All @@ -109,6 +179,7 @@ describe('openUrl', () => {
downloadsWaitingForAuth: {}
})

expect(metricsLogger).toHaveBeenCalledTimes(0)
expect(startPendingDownloads).toHaveBeenCalledTimes(0)
})
})
Expand Down Expand Up @@ -137,6 +208,8 @@ describe('openUrl', () => {
downloadsWaitingForAuth
})

expect(metricsLogger).toHaveBeenCalledTimes(0)

expect(database.setToken).toHaveBeenCalledTimes(1)
expect(database.setToken).toHaveBeenCalledWith('mock-token')

Expand Down Expand Up @@ -179,6 +252,8 @@ describe('openUrl', () => {
downloadsWaitingForEula
})

expect(metricsLogger).toHaveBeenCalledTimes(0)

expect(database.getFileWhere).toHaveBeenCalledTimes(1)
expect(database.getFileWhere).toHaveBeenCalledWith({ id: '1234' })

Expand Down
12 changes: 11 additions & 1 deletion src/main/eventHandlers/openUrl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// @ts-nocheck

import downloadIdForMetrics from '../utils/downloadIdForMetrics'
import metricsLogger from '../utils/metricsLogger'
import startNextDownload from '../utils/startNextDownload'
import startPendingDownloads from '../utils/startPendingDownloads'

Expand Down Expand Up @@ -39,6 +41,7 @@ const openUrl = async ({
const eulaRedirectUrl = searchParams.get('eulaRedirectUrl')
const getLinksToken = searchParams.get('token')
const getLinksUrl = searchParams.get('getLinks')
const clientId = searchParams.get('clientId')

const now = new Date()
.toISOString()
Expand All @@ -49,7 +52,6 @@ const openUrl = async ({
const downloadIdWithoutTimeFormatted = downloadIdWithoutTime.replace(/\s/g, '_')

const downloadId = `${downloadIdWithoutTimeFormatted}-${now}`

// Create a download in the database
await database.createDownload(downloadId, {
authUrl,
Expand All @@ -60,6 +62,14 @@ const openUrl = async ({
state: downloadStates.pending
})

metricsLogger({
eventType: 'OpenUrl',
data: {
clientId,
downloadId: downloadIdForMetrics(downloadId)
}
})

// If an app update is not available, start fetching links
// Check for false as value is initialized as undefined
if (updateAvailable === false) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/utils/__tests__/downloadIdForMetrics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import downloadIdForMetrics from '../downloadIdForMetrics'
describe('downloadIdForMetrics', () => {
test('should extract download ID when it matches the pattern', () => {
const inputDownloadId = 'downloadId-20231116_164945'
const expectedExtractedId = 'downloadId-20231116_164945'
const expectedExtractedId = 'downloadId'

const result = downloadIdForMetrics(inputDownloadId)

Expand Down
2 changes: 1 addition & 1 deletion src/main/utils/downloadIdForMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const downloadIdForMetrics = (downloadId) => {
const match = downloadIdString.match(regexPattern)

if (match) {
return match[0]
return match[1]
}

return downloadId
Expand Down

0 comments on commit 68f8118

Please sign in to comment.