-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Address larger tech debt/TODOs #8
Changes from all commits
64f37b8
534f98c
48d4fb7
6ce27ec
75f8e77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
export const ENGINES_PAGE_SIZE = 10; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,38 +7,54 @@ | |
import fetch from 'node-fetch'; | ||
import { schema } from '@kbn/config-schema'; | ||
|
||
export function registerEnginesRoute({ router, config }) { | ||
import { ENGINES_PAGE_SIZE } from '../../../common/constants'; | ||
|
||
export function registerEnginesRoute({ router, config, log }) { | ||
router.get( | ||
{ | ||
path: '/api/app_search/engines', | ||
validate: { | ||
query: schema.object({ | ||
type: schema.string(), | ||
type: schema.oneOf([schema.literal('indexed'), schema.literal('meta')]), | ||
pageIndex: schema.number(), | ||
}), | ||
}, | ||
}, | ||
async (context, request, response) => { | ||
const appSearchUrl = config.host; | ||
const { type, pageIndex } = request.query; | ||
|
||
const url = `${appSearchUrl}/as/engines/collection?type=${type}&page[current]=${pageIndex}&page[size]=10`; | ||
const enginesResponse = await fetch(url, { | ||
headers: { Authorization: request.headers.authorization }, | ||
}); | ||
|
||
if (enginesResponse.url.endsWith('/login')) { | ||
return response.ok({ | ||
body: { message: 'no-as-account' }, | ||
headers: { 'content-type': 'application/json' }, | ||
try { | ||
const appSearchUrl = config.host; | ||
const { type, pageIndex } = request.query; | ||
|
||
const url = `${appSearchUrl}/as/engines/collection?type=${type}&page[current]=${pageIndex}&page[size]=${ENGINES_PAGE_SIZE}`; | ||
const enginesResponse = await fetch(url, { | ||
headers: { Authorization: request.headers.authorization }, | ||
}); | ||
} | ||
|
||
const engines = await enginesResponse.json(); | ||
return response.ok({ | ||
body: engines, | ||
headers: { 'content-type': 'application/json' }, | ||
}); | ||
if (enginesResponse.url.endsWith('/login')) { | ||
log.info('No corresponding App Search account found'); | ||
// Note: Can't use response.unauthorized, Kibana will auto-log out the user | ||
return response.forbidden({ body: 'no-as-account' }); | ||
} | ||
|
||
const engines = await enginesResponse.json(); | ||
const hasValidData = | ||
Array.isArray(engines?.results) && typeof engines?.meta?.page?.total_results === 'number'; | ||
|
||
if (hasValidData) { | ||
return response.ok({ | ||
body: engines, | ||
headers: { 'content-type': 'application/json' }, | ||
}); | ||
} else { | ||
// Either a completely incorrect Enterprise Search host URL was configured, or App Search is returning bad data | ||
throw new Error(`Invalid data received from App Search: ${JSON.stringify(engines)}`); | ||
} | ||
} catch (e) { | ||
log.error(`Cannot connect to App Search: ${e.toString()}`); | ||
if (e instanceof Error) log.debug(e.stack); | ||
|
||
return response.notFound({ body: 'cannot-connect' }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we distinguish here between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can - I can't think of anything super useful to show the user in that case though 🤔 I think the assumption that malformed data from App Search = 'This isn't App Search' is a relatively safe one in terms of end-user-experience, as we can't show them anything but an error message in that case anyway. Definitely open to other thoughts or suggestions however! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point -- not much we can show the user. The more adventurous user or support engineer can still glean valuable lower-level detail by poking into the stack trace that we're logging to the console. 👍 |
||
} | ||
} | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's surprising to me that the
url
prop here would end with/login
in case of an invalid account. Does App Search redirect to/login
here when an invalid auth header is provided? Calling the API directly would return a401
status code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this is on App Search's end - I believe our Ruby logic is to default to the /login page no matter what if we encounter any invalid auth (even when hitting API endpoints).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear I don't 100% agree with it (as someone who prefers a very RESTful API/separate your front-end & back-end POV :), but I also would have no idea how to change it, so probably out of scope for now.