TSK-842: Fix resume recognition functionality (#2736)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-03-15 23:36:50 +07:00 committed by GitHub
parent fff4debc49
commit 3979c1acb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 95 additions and 51 deletions

View File

@ -89,7 +89,8 @@ services:
- ACCOUNTS_URL=http://localhost:3000 - ACCOUNTS_URL=http://localhost:3000
- REKONI_URL=http://localhost:4004 - REKONI_URL=http://localhost:4004
- COLLABORATOR_URL=ws://localhost:3078 - COLLABORATOR_URL=ws://localhost:3078
- FRONT_URL=http://front:8080 - GMAIL_URL=http://localhost:8088
- TELEGRAM_URL=http://localhost:8086
- UPLOAD_URL=/files - UPLOAD_URL=/files
- TRANSACTOR_URL=ws://localhost:3333 - TRANSACTOR_URL=ws://localhost:3333
- ELASTIC_URL=http://elastic:9200 - ELASTIC_URL=http://elastic:9200

View File

@ -3,7 +3,7 @@ LOGIN_ENDPOINT=ws://localhost:3333
TELEGRAM_URL=http://localhost:8086 TELEGRAM_URL=http://localhost:8086
GMAIL_URL=http://localhost:8088 GMAIL_URL=http://localhost:8088
FRONT_URL=http://front:8080 FRONT_URL=http://localhost:8080
REKONI_URL=http://localhost:4004 REKONI_URL=http://localhost:4004

View File

@ -1,4 +0,0 @@
TELEGRAM_URL = https://telegram.hc.engineering
GMAIL_URL = https://gmail.hc.engineering
REKONI_URL = https://rekoni.hc.engineering

View File

@ -2,5 +2,8 @@
"ACCOUNTS_URL":"/account", "ACCOUNTS_URL":"/account",
"COLLABORATOR_URL": "ws://localhost:3078", "COLLABORATOR_URL": "ws://localhost:3078",
"UPLOAD_URL":"/files", "UPLOAD_URL":"/files",
"MODEL_VERSION": null "MODEL_VERSION": null,
"TELEGRAM_URL": "http://localhost:8086",
"GMAIL_URL": "http://localhost:8088",
"REKONI_URL": "http://localhost:4004"
} }

View File

@ -80,8 +80,18 @@ import { textEditorId } from '@hcengineering/text-editor'
import { setMetadata } from '@hcengineering/platform' import { setMetadata } from '@hcengineering/platform'
interface Config {
ACCOUNTS_URL: string
UPLOAD_URL: string
MODEL_VERSION: string
COLLABORATOR_URL: string
REKONI_URL: string
TELEGRAM_URL: string
GMAIL_URL: string
}
export async function configurePlatform() { export async function configurePlatform() {
const config = await (await fetch('/config.json')).json() const config: Config = await (await fetch('/config.json')).json()
console.log('loading configuration', config) console.log('loading configuration', config)
setMetadata(login.metadata.AccountsUrl, config.ACCOUNTS_URL) setMetadata(login.metadata.AccountsUrl, config.ACCOUNTS_URL)
setMetadata(login.metadata.UploadUrl, config.UPLOAD_URL) setMetadata(login.metadata.UploadUrl, config.UPLOAD_URL)
@ -92,12 +102,11 @@ export async function configurePlatform() {
console.log('Minimal Model version requirement', config.MODEL_VERSION) console.log('Minimal Model version requirement', config.MODEL_VERSION)
setMetadata(presentation.metadata.RequiredVersion, config.MODEL_VERSION) setMetadata(presentation.metadata.RequiredVersion, config.MODEL_VERSION)
} }
setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086') setMetadata(login.metadata.TelegramUrl, config.TELEGRAM_URL ?? 'http://localhost:8086')
setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087') setMetadata(login.metadata.GmailUrl, config.GMAIL_URL ?? 'http://localhost:8087')
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT) setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT)
setMetadata(login.metadata.FrontUrl, process.env.FRONT_URL)
setMetadata(rekoni.metadata.RekoniUrl, process.env.REKONI_URL) setMetadata(rekoni.metadata.RekoniUrl, config.REKONI_URL)
setMetadata(uiPlugin.metadata.DefaultApplication, login.component.LoginApp) setMetadata(uiPlugin.metadata.DefaultApplication, login.component.LoginApp)

View File

@ -24,23 +24,24 @@ export * from './types'
/** /**
* @public * @public
*/ */
export async function recognizeDocument (token: string, url: string, contentType: string): Promise<ReconiDocument> { export async function recognizeDocument (token: string, file: File): Promise<ReconiDocument> {
const rekoniUrl = getMetadata(plugin.metadata.RekoniUrl) const rekoniUrl = getMetadata(plugin.metadata.RekoniUrl)
if (rekoniUrl === undefined) { if (rekoniUrl === undefined) {
// We could try use recognition service to find some document properties. // We could try use recognition service to find some document properties.
throw new PlatformError(unknownError('recognition framework is not configured')) throw new PlatformError(unknownError('recognition framework is not configured'))
} }
const data = new FormData()
data.append('file', file)
data.append('type', file.type)
data.append('name', file.name)
return (await ( return (await (
await fetch(concatLink(rekoniUrl, '/recognize'), { await fetch(concatLink(rekoniUrl, '/recognize'), {
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: 'Bearer ' + token, Authorization: 'Bearer ' + token
'Content-Type': 'application/json'
}, },
body: JSON.stringify({ body: data
contentType,
fileUrl: url
})
}) })
).json()) as ReconiDocument ).json()) as ReconiDocument
} }

View File

@ -37,7 +37,6 @@
createQuery, createQuery,
EditableAvatar, EditableAvatar,
getClient, getClient,
getFileUrl,
getUserDraft, getUserDraft,
KeyedAttribute, KeyedAttribute,
MessageBox, MessageBox,
@ -348,13 +347,11 @@
} }
} }
async function recognize (contentType: string): Promise<void> { async function recognize (file: File): Promise<void> {
const token = getMetadata(login.metadata.LoginToken) ?? '' const token = getMetadata(login.metadata.LoginToken) ?? ''
const frontUrl = getMetadata(login.metadata.FrontUrl) ?? ''
const fileUrl = frontUrl + getFileUrl(resume.uuid)
try { try {
const doc = await recognizeDocument(token, fileUrl, contentType) const doc = await recognizeDocument(token, file)
if (isUndef(object.title) && doc.title !== undefined) { if (isUndef(object.title) && doc.title !== undefined) {
object.title = doc.title object.title = doc.title
@ -462,7 +459,7 @@
resume.type = file.type resume.type = file.type
resume.lastModified = file.lastModified resume.lastModified = file.lastModified
await recognize(file.type) await recognize(file)
} catch (err: any) { } catch (err: any) {
setPlatformStatus(unknownError(err)) setPlatformStatus(unknownError(err))
} finally { } finally {

View File

@ -35,6 +35,7 @@
icon={recruit.icon.CreateCandidate} icon={recruit.icon.CreateCandidate}
label={draftExists ? recruit.string.ResumeDraft : recruit.string.CreateTalent} label={draftExists ? recruit.string.ResumeDraft : recruit.string.CreateTalent}
justify={'left'} justify={'left'}
kind={'primary'}
width={'100%'} width={'100%'}
on:click={newCandidate} on:click={newCandidate}
> >

View File

@ -69,7 +69,6 @@
</div> </div>
</Button> </Button>
</div> </div>
<Button icon={tracker.icon.Magnifier} on:click={async () => {}} />
</div> </div>
<style lang="scss"> <style lang="scss">

View File

@ -68,7 +68,6 @@ export async function configurePlatform() {
setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086') setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086')
setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087') setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087')
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT) setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT)
setMetadata(login.metadata.FrontUrl, process.env.FRONT_URL)
setMetadata(uiPlugin.metadata.DefaultApplication, workbench.component.WorkbenchApp) setMetadata(uiPlugin.metadata.DefaultApplication, workbench.component.WorkbenchApp)
setMetadata(workbench.metadata.ExcludedApplications, [contact.app.Contacts]) setMetadata(workbench.metadata.ExcludedApplications, [contact.app.Contacts])

View File

@ -28,8 +28,6 @@ spec:
value: /files value: /files
- name: TRANSACTOR_URL - name: TRANSACTOR_URL
value: wss://transactor.hc.engineering/ value: wss://transactor.hc.engineering/
- name: FRONT_URL
value: https://front.hc.engineering/
- name: GMAIL_URL - name: GMAIL_URL
value: gmail.hc.engineering value: gmail.hc.engineering
- name: ELASTIC_URL - name: ELASTIC_URL

View File

@ -77,6 +77,24 @@ if (collaboratorUrl === undefined) {
process.exit(1) process.exit(1)
} }
const gmailUrl = process.env.GMAIL_URL
if (gmailUrl === undefined) {
console.error('please provide gmail url')
process.exit(1)
}
const telegramUrl = process.env.TELEGRAM_URL
if (telegramUrl === undefined) {
console.error('please provide telegram url')
process.exit(1)
}
const rekoniUrl = process.env.REKONI_URL
if (rekoniUrl === undefined) {
console.error('please provide rekoni url')
process.exit(1)
}
const modelVersion = process.env.MODEL_VERSION const modelVersion = process.env.MODEL_VERSION
if (modelVersion === undefined) { if (modelVersion === undefined) {
console.error('please provide model version requirement') console.error('please provide model version requirement')
@ -91,7 +109,18 @@ if (serverSecret === undefined) {
setMetadata(serverToken.metadata.Secret, serverSecret) setMetadata(serverToken.metadata.Secret, serverSecret)
const config = { transactorEndpoint, elasticUrl, minio, accountsUrl, uploadUrl, modelVersion, collaboratorUrl } const config = {
transactorEndpoint,
elasticUrl,
minio,
accountsUrl,
uploadUrl,
modelVersion,
collaboratorUrl,
gmailUrl,
telegramUrl,
rekoniUrl
}
console.log('Starting Front service with', config) console.log('Starting Front service with', config)
const shutdown = start(config, SERVER_PORT) const shutdown = start(config, SERVER_PORT)

View File

@ -137,6 +137,9 @@ export function start (
uploadUrl: string uploadUrl: string
modelVersion: string modelVersion: string
collaboratorUrl: string collaboratorUrl: string
rekoniUrl: string
telegramUrl: string
gmailUrl: string
}, },
port: number port: number
): () => void { ): () => void {
@ -168,7 +171,10 @@ export function start (
ACCOUNTS_URL: config.accountsUrl, ACCOUNTS_URL: config.accountsUrl,
UPLOAD_URL: config.uploadUrl, UPLOAD_URL: config.uploadUrl,
MODEL_VERSION: config.modelVersion, MODEL_VERSION: config.modelVersion,
COLLABORATOR_URL: config.collaboratorUrl COLLABORATOR_URL: config.collaboratorUrl,
REKONI_URL: config.rekoniUrl,
TELEGRAM_URL: config.telegramUrl,
GMAIL_URL: config.gmailUrl
}) })
}) })

View File

@ -36,6 +36,12 @@ export function disableLogging (): void {
LOGGING_ENABLED = false LOGGING_ENABLED = false
} }
function timeoutPromise (time: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
interface Workspace { interface Workspace {
id: string id: string
pipeline: Promise<Pipeline> pipeline: Promise<Pipeline>
@ -203,20 +209,22 @@ class SessionManager {
const workspaceId = workspace.id const workspaceId = workspace.id
if (LOGGING_ENABLED) console.log('no sessions for workspace', wsid, workspaceId) if (LOGGING_ENABLED) console.log('no sessions for workspace', wsid, workspaceId)
async function waitAndClose (workspace: Workspace): Promise<void> { const waitAndClose = async (workspace: Workspace): Promise<void> => {
const pipeline = await workspace.pipeline try {
await pipeline.close() const pl = await workspace.pipeline
} await Promise.race([pl, timeoutPromise(60000)])
workspace.closing = waitAndClose(workspace).then(() => { await Promise.race([pl.close(), timeoutPromise(60000)])
if (this.workspaces.get(wsid)?.id === workspaceId) { if (this.workspaces.get(wsid)?.id === workspaceId) {
this.workspaces.delete(wsid) this.workspaces.delete(wsid)
} }
console.log('Closed workspace', workspaceId) console.log('Closed workspace', workspaceId)
}) } catch (err: any) {
workspace.closing.catch((err) => {
this.workspaces.delete(wsid) this.workspaces.delete(wsid)
console.error(err) console.error(err)
}) }
}
workspace.closing = waitAndClose(workspace)
await workspace.closing await workspace.closing
} }
} }
@ -259,12 +267,7 @@ class SessionManager {
console.error(err) console.error(err)
} }
} }
await Promise.race([ await Promise.race([closePipeline(), timeoutPromise(15000)])
closePipeline(),
new Promise((resolve) => {
setTimeout(resolve, 15000)
})
])
console.log(workspace.id, 'Workspace closed...') console.log(workspace.id, 'Workspace closed...')
} }

View File

@ -84,6 +84,9 @@ services:
- UPLOAD_URL=/files - UPLOAD_URL=/files
- TRANSACTOR_URL=ws://localhost:3334 - TRANSACTOR_URL=ws://localhost:3334
- ELASTIC_URL=http://elastic:9200 - ELASTIC_URL=http://elastic:9200
- GMAIL_URL=http://localhost:8088
- TELEGRAM_URL=http://localhost:8086
- REKONI_URL=http://rekoni:4005
- MINIO_ENDPOINT=minio - MINIO_ENDPOINT=minio
- MINIO_ACCESS_KEY=minioadmin - MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin - MINIO_SECRET_KEY=minioadmin
@ -112,7 +115,7 @@ services:
image: hardcoreeng/rekoni-service image: hardcoreeng/rekoni-service
restart: on-failure restart: on-failure
ports: ports:
- 4004:4005 - 4005:4004
deploy: deploy:
resources: resources:
limits: limits:

View File

@ -3,7 +3,6 @@
docker-compose -p sanity kill docker-compose -p sanity kill
docker-compose -p sanity down --volumes docker-compose -p sanity down --volumes
docker-compose -p sanity up -d --force-recreate --renew-anon-volumes docker-compose -p sanity up -d --force-recreate --renew-anon-volumes
./setup-elastic.sh 9201
# Creae workspace record in accounts # Creae workspace record in accounts
./tool.sh create-workspace sanity-ws -o SanityTest ./tool.sh create-workspace sanity-ws -o SanityTest