Local docker compose (#332)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2021-11-22 18:17:10 +07:00 committed by GitHub
parent 1e16743721
commit ef0c3e8c91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 456 additions and 136 deletions

22
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug server",
"type": "node",
"request": "launch",
"args": ["src/__start.ts"],
"env": {
"ELASTIC_URL": "http://localhost:9200",
"MONGO_URL": "mongodb://localhost:27017"
},
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
"sourceMaps": true,
"cwd": "${workspaceRoot}/server/server",
"protocol": "inspector"
}
]
}

View File

@ -12,8 +12,40 @@ You need Microsoft's [rush](https://rushjs.io) to install application. Install [
cd dev/prod
rushx dev
```
Then go to http://localhost:8080/login:component:LoginApp and use following credentials to login into the system:
* login: rosamund@hc.engineering
* pass: 1111
* workspace: trx40
- login: rosamund@hc.engineering
- pass: 1111
- workspace: trx40
To connect to running local server `dev-server` command should be used instead.
## Build and run inside docker
It is possible to setup all environment required with local docker containers.
Supported both amd64 and armv8 containers.
```bash
rush build # Will build all required packages.
rush bundle # Will prepare bundles.
rush docker:build # Will build docker containers for all applications.
cd ./dev/
docker-compose up -d --force-recreate # Will setup all containers
# we a few seconds delay, to be sure elastic is up and running.
./deploy/setup-es-attachment-pipeline.sh # Setup elastic search plugin configuration.
```
By default docker volumes `dev_db` `dev_elastic` `dev_files` will be created for mongo/elastic/minio instances.
Before we could start we need to create workspace/account and associate it with workspace.
```bash
cd ./dev/tools
rushx run-local create-workspace ws1 -o DevWorkspace # Create workspace
rushx run-local create-account user1 -p 1234 -f John -l Appleseed # Create account
rushx run-local assign-workspace user1 ws1 # Assign worksapce to user
```
Following URL http://localhost:8081/login:component:LoginApp will lead us to app.

View File

@ -207,6 +207,27 @@
"ignoreDependencyOrder": false,
"ignoreMissingScript": true
},
{
"commandKind": "bulk",
"name": "docker:build",
"summary": "docker:build",
"description": "Build and make docker containers",
"enableParallelism": true,
"incremental": true,
"ignoreDependencyOrder": false,
"ignoreMissingScript": true
},
{
"commandKind": "bulk",
"name": "bundle",
"summary": "bundle",
"description": "Build bundles",
"enableParallelism": true,
"incremental": true,
"ignoreDependencyOrder": false,
"ignoreMissingScript": true
},
],
/**

View File

@ -101,6 +101,7 @@ specifiers:
'@types/ws': ^7.4.7
autoprefixer: ^10.2.6
commander: ^8.1.0
compression-webpack-plugin: ~9.0.0
cors: ^2.8.5
cross-env: ^7.0.3
css-loader: ^5.2.1
@ -241,6 +242,7 @@ dependencies:
'@types/ws': 7.4.7
autoprefixer: 10.3.7_postcss@8.3.9
commander: 8.2.0
compression-webpack-plugin: 9.0.1_webpack@5.57.1
cors: 2.8.5
cross-env: 7.0.3
css-loader: 5.2.7_webpack@5.57.1
@ -2226,6 +2228,15 @@ packages:
ajv: 6.12.6
dev: false
/ajv-formats/2.1.1:
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
peerDependenciesMeta:
ajv:
optional: true
dependencies:
ajv: 8.8.1
dev: false
/ajv-keywords/3.5.2_ajv@6.12.6:
resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
peerDependencies:
@ -2234,6 +2245,15 @@ packages:
ajv: 6.12.6
dev: false
/ajv-keywords/5.0.0_ajv@8.8.1:
resolution: {integrity: sha512-ULd1QMjRoH6JDNUQIfDLrlE+OgZlFaxyYCjzt58uNuUQtKXt8/U+vK/8Ql0gyn/C5mqZzUWtKMqr/4YquvTrWA==}
peerDependencies:
ajv: ^8.0.0
dependencies:
ajv: 8.8.1
fast-deep-equal: 3.1.3
dev: false
/ajv/6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
dependencies:
@ -2252,6 +2272,15 @@ packages:
uri-js: 4.4.1
dev: false
/ajv/8.8.1:
resolution: {integrity: sha512-6CiMNDrzv0ZR916u2T+iRunnD60uWmNn8SkdB44/6stVORUg0aAkWO7PkOhpCmjmW8f2I/G/xnowD66fxGyQJg==}
dependencies:
fast-deep-equal: 3.1.3
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
uri-js: 4.4.1
dev: false
/ansi-colors/3.2.4:
resolution: {integrity: sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==}
engines: {node: '>=6'}
@ -3013,6 +3042,17 @@ packages:
mime-db: 1.50.0
dev: false
/compression-webpack-plugin/9.0.1_webpack@5.57.1:
resolution: {integrity: sha512-vqlhZIPSyCpy6eaYWy8iPhteLWpARKotRiN5B/jr7lLowJv1GVc98Snn1Dcxe0+SKbfydLu7qZcnNuP+AyG19Q==}
engines: {node: '>= 12.13.0'}
peerDependencies:
webpack: ^5.1.0
dependencies:
schema-utils: 4.0.0
serialize-javascript: 6.0.0
webpack: 5.57.1_webpack-cli@4.8.0
dev: false
/compression/1.7.4:
resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
engines: {node: '>= 0.8.0'}
@ -7674,6 +7714,16 @@ packages:
ajv-keywords: 3.5.2_ajv@6.12.6
dev: false
/schema-utils/4.0.0:
resolution: {integrity: sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==}
engines: {node: '>= 12.13.0'}
dependencies:
'@types/json-schema': 7.0.9
ajv: 8.8.1
ajv-formats: 2.1.1
ajv-keywords: 5.0.0_ajv@8.8.1
dev: false
/secure-json-parse/2.4.0:
resolution: {integrity: sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==}
dev: false
@ -9832,7 +9882,7 @@ packages:
dev: false
file:projects/front.tgz_typescript@4.4.3:
resolution: {integrity: sha512-qKmnx2yFt1hFJRZWJNaPPbb+p/Q0lnyA6u9AAgeqDbOjmWjp48NxqX6jIbiEyQi56IDHViE3w4/NQb0c/mp/rA==, tarball: file:projects/front.tgz}
resolution: {integrity: sha512-8DxO3cOzfmEfVPsjIfOfA0mT3OrRDlBCuobV2mlj5+NzofW4yjJicsGlU8jCZ/fG2CMqfpWK5Hdino0LTX+T7g==, tarball: file:projects/front.tgz}
id: file:projects/front.tgz
name: '@rush-temp/front'
version: 0.0.0
@ -9844,20 +9894,21 @@ packages:
'@types/minio': 7.0.10
'@types/node': 16.10.3
'@types/uuid': 8.3.1
'@typescript-eslint/eslint-plugin': 4.33.0_eslint@7.32.0+typescript@4.4.3
'@typescript-eslint/eslint-plugin': 5.4.0_87dbf04088b125598d0271706532eaf3
'@typescript-eslint/parser': 5.4.0_eslint@7.32.0+typescript@4.4.3
cors: 2.8.5
esbuild: 0.12.29
eslint: 7.32.0
eslint-config-standard-with-typescript: 21.0.1_05a8ea1454e6ca4c9f98b94b8f3abf9c
eslint-plugin-import: 2.25.3_eslint@7.32.0
eslint-plugin-node: 11.1.0_eslint@7.32.0
eslint-plugin-promise: 4.3.1
eslint-plugin-promise: 5.1.1_eslint@7.32.0
express: 4.17.1
express-fileupload: 1.2.1
jwt-simple: 0.5.6
minio: 7.0.19
uuid: 8.3.2
transitivePeerDependencies:
- '@typescript-eslint/parser'
- supports-color
- typescript
dev: false
@ -9999,7 +10050,7 @@ packages:
dev: false
file:projects/model-demo.tgz_typescript@4.4.3:
resolution: {integrity: sha512-yo76yELzjfVH7a4Ba62J3M4cYP9yN/Xbe+O1jpwgVqRyqUHpowMrykgvrMDh9meuEsSsJ3NNFrClan9TEaY17A==, tarball: file:projects/model-demo.tgz}
resolution: {integrity: sha512-vXuP1gNtnqOBsOcxF7YtmkX2JFGlRRRxlCt7Jf/uLkAdU2h87nhkoRdllrvkGXPCqJYae47xLvpEpIxpgj6OBQ==, tarball: file:projects/model-demo.tgz}
id: file:projects/model-demo.tgz
name: '@rush-temp/model-demo'
version: 0.0.0
@ -10330,13 +10381,14 @@ packages:
dev: false
file:projects/prod.tgz_sass@1.42.1+typescript@4.4.3:
resolution: {integrity: sha512-BNsiZcy9EorJrRU+a1vLrsdXIWfjlSOKDzxwvsiORGg+DJhyBuWRPMl1ngR/JuiDMPIThzTp3DHhmcKDPvQfVw==, tarball: file:projects/prod.tgz}
resolution: {integrity: sha512-x7H3hwhd/DGstkIJ2QG1AJMUyFKeP//3BVCL24c8w4Z1xMD+fnfsg5pf3V1c/LkHk/e3D3YyPTqBOAt5+u1mJQ==, tarball: file:projects/prod.tgz}
id: file:projects/prod.tgz
name: '@rush-temp/prod'
version: 0.0.0
dependencies:
'@types/node': 14.17.21
autoprefixer: 10.3.7_postcss@8.3.9
compression-webpack-plugin: 9.0.1_webpack@5.57.1
cross-env: 7.0.3
css-loader: 5.2.7_webpack@5.57.1
dotenv-webpack: 7.0.3_webpack@5.57.1

73
dev/docker-compose.yaml Normal file
View File

@ -0,0 +1,73 @@
services:
mongodb:
image: mongo
container_name: mongodb
environment:
- PUID=1000
- PGID=1000
volumes:
- db:/data/db
ports:
- 27017:27017
restart: unless-stopped
minio:
image: 'minio/minio'
command: server /data --address ":9000" --console-address ":9001"
ports:
- 9000:9000
volumes:
- files:/data
elastic:
image: 'elasticsearch:7.14.0'
command: |
/bin/sh -c "./bin/elasticsearch-plugin list | grep -q ingest-attachment || yes | ./bin/elasticsearch-plugin install --silent ingest-attachment;
/usr/local/bin/docker-entrypoint.sh eswrapper"
volumes:
- elastic:/usr/share/elasticsearch/data
ports:
- 9200:9200
environment:
- ELASTICSEARCH_PORT_NUMBER=9200
- BITNAMI_DEBUG=true
- discovery.type=single-node
account:
image: anticrm/account
links:
- mongodb
ports:
- 3000:3000
environment:
- MONGO_URL=mongodb://mongodb:27017
- TRANSACTOR_URL=ws://localhost:3333
front:
image: anticrm/front
links:
- mongodb
- minio
- elastic
- server
- upload
ports:
- 8081:8080
environment:
- ACCOUNTS_URL=http://localhost:3000
- UPLOAD_URL=/files
- TRANSACTOR_URL=ws://localhost:3333
- ELASTIC_URL=http://elastic:9200
- MINIO_ENDPOINT=minio
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
transactor:
image: anticrm/transactor
links:
- mongodb
- elastic
ports:
- 3333:3333
environment:
- ELASTIC_URL=http://elastic:9200
- MONGO_URL=mongodb://mongodb:27017
volumes:
db:
files:
elastic:

View File

@ -1,7 +1,5 @@
CLIENT_TYPE=dev
ACCOUNTS_URL=/account
UPLOAD_URL=/upload
LOGIN_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InJvc2FtdW5kQGhjLmVuZ2luZWVyaW5nIiwid29ya3NwYWNlIjoidHJ4NDAifQ.dYsCF2VRbuc-zmRt0yLAww1_--xtX4P1EqPFREEzCjQ
# LOGIN_ENDPOINT=ws://localhost:3333
LOGIN_ENDPOINT=wss://transactor.hc.engineering/
LOGIN_ENDPOINT=ws://localhost:3333
LOGIN_TOKEN_DEV=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InJvc2FtdW5kQGhjLmVuZ2luZWVyaW5nIiwid29ya3NwYWNlIjoidHJ4NDAifQ.dYsCF2VRbuc-zmRt0yLAww1_--xtX4P1EqPFREEzCjQ
LOGIN_ENDPOINT_DEV=wss://transactor.hc.engineering/

View File

@ -1,5 +0,0 @@
#ACCOUNTS_URL=https://ftwm71rwag.execute-api.us-west-2.amazonaws.com/stage/
ACCOUNTS_URL=https://account.hc.engineering/
UPLOAD_URL=/files

1
dev/prod/config.json Normal file
View File

@ -0,0 +1 @@
{"ACCOUNTS_URL":"http://localhost:3000","UPLOAD_URL":"/files"}

View File

@ -3,11 +3,11 @@
"version": "1.0.1",
"license": "EPL-2.0",
"scripts": {
"build": "cross-env NODE_ENV=production webpack --stats-error-details && echo 'done'",
"build": "cross-env NODE_ENV=development webpack --stats-error-details && echo 'done'",
"analyze": "cross-env NODE_ENV=production webpack --json > stats.json",
"show": "webpack-bundle-analyzer stats.json dist",
"dev": "cross-env webpack serve --content-base public",
"dev-server": "cross-env CLIENT=server webpack serve --content-base public",
"dev": "cross-env CLIENT_TYPE=dev webpack serve --content-base public",
"dev-server": "cross-env CLIENT_TYPE=dev-server webpack serve --content-base public",
"start": "cross-env NODE_ENV=production webpack serve --content-base public",
"preformat-svelte": "prettier -w src/**/*.svelte",
"lint": "eslint --max-warnings=0 src",
@ -33,7 +33,8 @@
"autoprefixer": "^10.2.6",
"postcss": "^8.3.4",
"postcss-loader": "^6.1.0",
"postcss-load-config": "^3.1.0"
"postcss-load-config": "^3.1.0",
"compression-webpack-plugin": "~9.0.0"
},
"dependencies": {
"@anticrm/platform": "~0.6.5",

View File

@ -0,0 +1,4 @@
{
"ACCOUNTS_URL":"/account",
"UPLOAD_URL":"/files"
}

View File

@ -12,6 +12,7 @@
</head>
<body style="margin: 0; overflow: hidden;">
<script src='/vendors.js'></script>
<script src='/bundle.js'></script>
</body>

View File

@ -14,41 +14,9 @@
// limitations under the License.
//
// import { setMetadata } from '@anticrm/platform'
import { createApp } from '@anticrm/ui'
// import login from '@anticrm/login'
// import pluginCore from '@anticrm/plugin-core'
// import meetingPlugin from '@anticrm/meeting'
import { configurePlatform } from './platform'
configurePlatform()
// const accountsUrl = process.env.APP_ACCOUNTS_URL
// const appHost = process.env.APP_WSHOST
// const appPort = process.env.APP_WSPORT
// const appToken = process.env.APP_TOKEN
// const meetingHost = process.env.MEETING_WSHOST
// const meetingPort = process.env.MEETING_WSPORT
// setMetadata(login.metadata.AccountsUrl, accountsUrl)
// setMetadata(pluginCore.metadata.ClientUrl, `${appHost}:${appPort}/${appToken}`)
// setMetadata(meetingPlugin.metadata.ClientUrl, `${meetingHost}:${meetingPort}`)
// platform.setMetadata(core.metadata.WSHost, host)
// platform.setMetadata(core.metadata.WSPort, port)
// const loginInfo = currentAccount()
// if (loginInfo) {
// platform.setMetadata(core.metadata.WhoAmI, loginInfo.email)
// platform.setMetadata(core.metadata.Token, loginInfo.token)
// }
// async function boot (): Promise<void> {
// uiService.createApp(document.body)
// }
// boot().catch(err => {
// new ErrorPage({ target: document.body, props: { error: err.message } })
// })
createApp(document.body)

View File

@ -38,20 +38,30 @@ import '@anticrm/recruit-assets'
import '@anticrm/activity-assets'
import { setMetadata } from '@anticrm/platform'
export function configurePlatform() {
setMetadata(login.metadata.AccountsUrl, process.env.ACCOUNTS_URL)
setMetadata(login.metadata.UploadUrl, process.env.UPLOAD_URL)
setMetadata(login.metadata.OverrideLoginToken, process.env.LOGIN_TOKEN)
export function configurePlatform() {
fetch('/config.json').then(config => {
config.json().then(value => {
console.log('loading configuration', value)
setMetadata(login.metadata.AccountsUrl, value.ACCOUNTS_URL)
setMetadata(login.metadata.UploadUrl, value.UPLOAD_URL)
})
})
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT)
if (process.env.CLIENT_TYPE === 'dev') {
setMetadata(login.metadata.OverrideLoginToken, process.env.LOGIN_TOKEN_DEV)
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT_DEV)
console.log('Use DEV server')
addLocation(clientId, () => import(/* webpackChunkName: "client-dev" */ '@anticrm/dev-client-resources'))
addLocation(serverChunterId, () => import(/* webpackChunkName: "server-chunter" */ '@anticrm/dev-server-chunter-resources'))
addLocation(serverRecruitId, () => import(/* webpackChunkName: "server-recruit" */ '@anticrm/server-recruit-resources'))
addLocation(serverViewId, () => import(/* webpackChunkName: "server-view" */ '@anticrm/server-view-resources'))
} else {
if (process.env.CLIENT_TYPE === 'dev-server') {
console.log('Use Endpoint override:', process.env.LOGIN_ENDPOINT)
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT)
}
console.log('Use server')
addLocation(clientId, () => import(/* webpackChunkName: "client" */ '@anticrm/client-resources'))
}

View File

@ -17,9 +17,12 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const Dotenv = require('dotenv-webpack')
const path = require('path')
const autoprefixer = require('autoprefixer')
const CompressionPlugin = require('compression-webpack-plugin')
const DefinePlugin = require('webpack').DefinePlugin
const mode = process.env.NODE_ENV || 'development'
const prod = mode === 'production'
const devServer = (process.env.CLIENT_TYPE ?? '') === 'dev-server'
module.exports = {
entry: {
@ -42,6 +45,22 @@ module.exports = {
chunkFilename: '[name].[id].js',
publicPath: '/'
},
optimization: {
minimize: prod,
usedExports: prod,
splitChunks: {
chunks: 'all',
maxAsyncRequests: 5,
maxInitialRequests: 3,
cacheGroups: {
vendors: {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: 20
}
}
}
},
module: {
rules: [
{
@ -149,10 +168,14 @@ module.exports = {
},
mode,
plugins: [
...(prod ? [new CompressionPlugin()] : []),
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new Dotenv({path: prod ? '.env-prod' : '.env'})
new Dotenv({path: prod ? '.env-prod' : '.env'}),
new DefinePlugin({
'process.env.CLIENT_TYPE': JSON.stringify(process.env.CLIENT_TYPE)
})
],
devtool: prod ? false : 'source-map',
devServer: {
@ -160,7 +183,19 @@ module.exports = {
historyApiFallback: {
disableDotRule: true
},
proxy: {
proxy: devServer ? {
'/account': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: { '^/account': '' },
logLevel: 'debug'
},
'/files': {
target: 'http://localhost:8081',
changeOrigin: true,
logLevel: 'debug'
},
} : {
'/account': {
// target: 'https://ftwm71rwag.execute-api.us-west-2.amazonaws.com/stage/',
target: 'https://account.hc.engineering/',
@ -168,12 +203,12 @@ module.exports = {
pathRewrite: { '^/account': '' },
logLevel: 'debug'
},
'/upload': {
'/files': {
// target: 'https://anticrm-upload.herokuapp.com/',
// target: 'http://localhost:3000/',
// target: 'http://localhost:3000/',
target: 'https://front.hc.engineering/files',
changeOrigin: true,
pathRewrite: { '^/upload': '' },
pathRewrite: { '^/files': '' },
logLevel: 'debug'
},
}

View File

@ -9,9 +9,10 @@
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"start": "ts-node src/index.ts",
"bundle": "esbuild src/index.ts --bundle --minify --platform=node > bundle.js",
"bundle": "esbuild src/index.ts --bundle --minify --platform=node > bundle.js",
"docker:build": "docker build -t anticrm/tool .",
"docker:push": "docker push anticrm/tool"
"docker:push": "docker push anticrm/tool",
"run-local": "MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=minioadmin MONGO_URL=mongodb://localhost:27017 TRANSACTOR_URL=ws:/localhost:3333 MINIO_ENDPOINT=localhost ts-node ./src/index.ts"
},
"devDependencies": {
"@anticrm/platform-rig":"~0.6.0",

View File

@ -14,15 +14,13 @@
// limitations under the License.
//
import { ACCOUNT_DB, methods } from '@anticrm/account'
import platform, { Response, Request, serialize, Status, Severity } from '@anticrm/platform'
import { MongoClient, Db } from 'mongodb'
import Koa from 'koa'
import Router from 'koa-router'
import bodyParser from 'koa-bodyparser'
import accountPlugin, { ACCOUNT_DB, methods } from '@anticrm/account'
import platform, { Request, Response, serialize, setMetadata, Severity, Status } from '@anticrm/platform'
import cors from '@koa/cors'
import Koa from 'koa'
import bodyParser from 'koa-bodyparser'
import Router from 'koa-router'
import { Db, MongoClient } from 'mongodb'
const dbUri = process.env.MONGO_URL
if (dbUri === undefined) {
@ -30,6 +28,14 @@ if (dbUri === undefined) {
process.exit(1)
}
const transactorUri = process.env.TRANSACTOR_URL
if (dbUri === undefined) {
console.log('Please provide transactor url')
process.exit(1)
}
setMetadata(accountPlugin.metadata.Endpoint, transactorUri)
let client: MongoClient
const app = new Koa()
@ -60,6 +66,13 @@ app.use(cors())
app.use(bodyParser())
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000, () => {
const server = app.listen(3000, () => {
console.log('server started on port 3000')
})
const close = (): void => {
server.close()
}
process.on('SIGINT', close)
process.on('SIGTERM', close)
process.on('exit', close)

View File

@ -14,18 +14,14 @@
// limitations under the License.
//
import type { Plugin, StatusCode, Request, Response } from '@anticrm/platform'
import { PlatformError, Severity, Status, plugin, unknownStatus } from '@anticrm/platform'
import { Binary, Db, ObjectId } from 'mongodb'
import { getMetadata, Metadata, Plugin, Request, Response, StatusCode, PlatformError, plugin, Severity, Status, unknownStatus } from '@anticrm/platform'
import { pbkdf2Sync, randomBytes } from 'crypto'
import { encode } from 'jwt-simple'
import { Binary, Db, ObjectId } from 'mongodb'
const WORKSPACE_COLLECTION = 'workspace'
const ACCOUNT_COLLECTION = 'account'
const endpoint = 'wss://transactor.hc.engineering/'
const secret = 'secret'
/**
* @public
*/
@ -40,6 +36,10 @@ export const accountId = 'account' as Plugin
* @public
*/
const accountPlugin = plugin(accountId, {
metadata: {
Endpoint: '' as Metadata<string>,
Secret: '' as Metadata<string>
},
status: {
AccountNotFound: '' as StatusCode<{account: string}>,
WorkspaceNotFound: '' as StatusCode<{workspace: string}>,
@ -50,6 +50,14 @@ const accountPlugin = plugin(accountId, {
}
})
const getSecret = (): string => {
return getMetadata(accountPlugin.metadata.Secret) ?? 'secret'
}
const getEndpoint = (): string => {
return getMetadata(accountPlugin.metadata.Endpoint) ?? 'wss://transactor.hc.engineering/'
}
/**
* @public
*/
@ -132,7 +140,7 @@ async function getAccountInfo (db: Db, email: string, password: string): Promise
}
function generateToken (email: string, workspace: string): string {
return encode({ email, workspace }, secret)
return encode({ email, workspace }, getSecret())
}
/**
@ -153,7 +161,7 @@ export async function login (db: Db, email: string, password: string, workspace:
for (const w of workspaces) {
if (w.equals(workspaceInfo._id)) {
const result = {
endpoint,
endpoint: getEndpoint(),
email,
token: generateToken(email, workspace)
}

View File

@ -22,7 +22,7 @@ if (url === undefined) {
process.exit(1)
}
const client = new Client({ node: 'http://45.32.149.163:9200/' })
const client = new Client({ node: url })
client.ingest.putPipeline({
id: 'anticrm-pipeline',

View File

@ -66,38 +66,51 @@ class ElasticAdapter implements FullTextAdapter {
async index (doc: IndexedDoc): Promise<TxResult> {
console.log('eastic: index', doc)
if (doc.data === undefined) {
const resp = await this.client.index({
index: this.db,
id: doc.id,
type: '_doc',
body: doc
})
console.log('resp', resp)
console.log('error', (resp.meta as any)?.body?.error)
try {
const resp = await this.client.index({
index: this.db,
id: doc.id,
type: '_doc',
body: doc
})
console.log('resp', resp)
console.log('error', (resp.meta as any)?.body?.error)
} catch (err: any) {
console.log('elastic-exception', err)
}
} else {
console.log('attachment pipeline')
const resp = await this.client.index({
index: this.db,
id: doc.id,
type: '_doc',
pipeline: 'attachment',
body: doc
})
console.log('resp', resp)
console.log('error', (resp.meta as any)?.body?.error)
try {
const resp = await this.client.index({
index: this.db,
id: doc.id,
type: '_doc',
pipeline: 'attachment',
body: doc
})
console.log('resp', resp)
console.log('error', (resp.meta as any)?.body?.error)
} catch (err: any) {
console.log('elastic-exception', err)
}
}
return {}
}
async update (id: Ref<Doc>, update: Record<string, any>): Promise<TxResult> {
const resp = await this.client.update({
index: this.db,
id,
body: {
doc: update
}
})
console.log('update', resp)
try {
const resp = await this.client.update({
index: this.db,
id,
body: {
doc: update
}
})
console.log('update', resp)
} catch (err: any) {
console.log('elastic-exception', err)
}
return {}
}
}

View File

@ -20,6 +20,10 @@ spec:
- containerPort: 8080
imagePullPolicy: Always
env:
- name: ACCOUNTS_URL
value: https://account.hc.engineering/
- name: UPLOAD_URL
value: /files
- name: TRANSACTOR_URL
value: ws://transactor/
- name: ELASTIC_URL

View File

@ -8,7 +8,7 @@
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"bundle": "esbuild src/__start.ts --bundle --minify --platform=node > bundle.js & rm -rf ./dist && cp -r ../../dev/prod/dist . && cp -r ../../dev/prod/public/* ./dist/",
"bundle": "esbuild src/__start.ts --bundle --minify --platform=node > bundle.js & rm -rf ./dist && cp -r ../../dev/prod/dist . && cp -r ../../dev/prod/public/* ./dist/ && rm ./dist/config.json",
"docker:build": "docker build -t anticrm/front .",
"docker:push": "docker push anticrm/front"
},
@ -16,11 +16,13 @@
"@anticrm/platform-rig":"~0.6.0",
"@types/heft-jest":"^1.0.2",
"@types/node": "^16.4.10",
"@typescript-eslint/eslint-plugin":"4",
"eslint-plugin-import":"2",
"eslint-plugin-promise":"4",
"eslint-plugin-node":"11",
"eslint":"^7.32.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"eslint-config-standard-with-typescript": "^21.0.1",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.1",
"eslint": "^7.32.0",
"@types/express":"^4.17.13",
"@types/express-fileupload":"^1.1.7",
"@types/uuid":"^8.3.1",

9
server/front/run.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
export ACCOUNTS_URL=http://localhost:3333
export TRANSACTOR_URL=ws://localhost:3333
export ELASTIC_URL=http://elastic:9200
export MINIO_ENDPOINT=minio
export MINIO_ACCESS_KEY=minioadmin
export MINIO_SECRET_KEY=minioadmin
node ./bundle.js

View File

@ -17,8 +17,8 @@
import { start } from './app'
import { Client } from 'minio'
const url = process.env.TRANSACTOR_URL
if (url === undefined) {
const transactorEndpoint = process.env.TRANSACTOR_URL
if (transactorEndpoint === undefined) {
console.error('please provide transactor url')
process.exit(1)
}
@ -55,4 +55,18 @@ const minio = new Client({
secretKey: minioSecretKey
})
start(url, elasticUrl, minio, 8080)
const accountsUrl = process.env.ACCOUNTS_URL
if (accountsUrl === undefined) {
console.error('please provide accounts url')
process.exit(1)
}
const uploadUrl = process.env.UPLOAD_URL
if (uploadUrl === undefined) {
console.error('please provide upload url')
process.exit(1)
}
const config = { transactorEndpoint, elasticUrl, minio, accountsUrl, uploadUrl }
console.log('Starting Front service with', config)
start(config, 8080)

View File

@ -79,12 +79,24 @@ async function minioUpload (minio: Client, workspace: string, file: UploadedFile
* @public
* @param port -
*/
export function start (transactorEndpoint: string, elasticUrl: string, minio: Client, port: number): void {
export function start (config: { transactorEndpoint: string, elasticUrl: string, minio: Client, accountsUrl: string, uploadUrl: string }, port: number): void {
const app = express()
app.use(cors())
app.use(fileUpload())
// eslint-disable-next-line @typescript-eslint/no-misused-promises
app.get('/config.json', async (req, res) => {
res.status(200)
res.set('Cache-Control', 'no-cache')
res.json(
{
ACCOUNTS_URL: config.accountsUrl,
UPLOAD_URL: config.uploadUrl
}
)
})
const dist = resolve(__dirname, 'dist')
console.log('serving static files from', dist)
app.use(express.static(dist, { maxAge: '10m' }))
@ -96,8 +108,8 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
const payload = decode(token, 'secret', false) as Token
const uuid = req.query.file as string
const stat = await minio.statObject(payload.workspace, uuid)
minio.getObject(payload.workspace, uuid, function (err, dataStream) {
const stat = await config.minio.statObject(payload.workspace, uuid)
config.minio.getObject(payload.workspace, uuid, function (err, dataStream) {
if (err !== null) {
return console.log(err)
}
@ -143,7 +155,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
const token = authHeader.split(' ')[1]
const payload = decode(token ?? '', 'secret', false) as Token
// const fileId = await awsUpload(file as UploadedFile)
const uuid = await minioUpload(minio, payload.workspace, file)
const uuid = await minioUpload(config.minio, payload.workspace, file)
console.log('uploaded uuid', uuid)
const name = req.query.name as string
@ -162,7 +174,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
// fileId
// )
const elastic = await createElasticAdapter(elasticUrl, payload.workspace)
const elastic = await createElasticAdapter(config.elasticUrl, payload.workspace)
const indexedDoc: IndexedDoc = {
id: generateId() + '/attachments/' + name,
@ -224,7 +236,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
}).on('end', function () {
const buffer = Buffer.concat(data)
// eslint-disable-next-line @typescript-eslint/no-misused-promises
minio.putObject(payload.workspace, id, buffer, 0, meta, async (err, objInfo) => {
config.minio.putObject(payload.workspace, id, buffer, 0, meta, async (err, objInfo) => {
if (err !== null) {
console.log('minio putObject error', err)
res.status(500).send(err)
@ -233,7 +245,7 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
if (attachedTo !== undefined) {
const space = req.query.space as Ref<Space>
const elastic = await createElasticAdapter(elasticUrl, payload.workspace)
const elastic = await createElasticAdapter(config.elasticUrl, payload.workspace)
const indexedDoc: IndexedDoc = {
id: generateId() + '/attachments/' + 'Profile.pdf',

View File

@ -30,5 +30,12 @@ app.get('*', function (request, response) {
response.sendFile(join(dist, 'index.html'))
})
app.listen(port)
const server = app.listen(port)
console.log(`server started on port ${port}`)
const close = (): void => {
server.close()
}
process.on('SIGINT', close)
process.on('SIGTERM', close)
process.on('exit', close)

View File

@ -29,4 +29,14 @@ if (elasticUrl === undefined) {
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
start(url, elasticUrl, 3333)
const shutdown = start(url, elasticUrl, 3333)
const close = (): void => {
console.error(new Error().stack)
console.log('Shutdown request accepted')
shutdown()
process.exit(0)
}
process.on('SIGINT', close)
process.on('SIGTERM', close)
process.on('exit', close)

View File

@ -39,12 +39,12 @@ async function createNullAdapter (hierarchy: Hierarchy, url: string, db: string,
/**
* @public
*/
export async function start (dbUrl: string, fullTextUrl: string, port: number, host?: string): Promise<void> {
export function start (dbUrl: string, fullTextUrl: string, port: number, host?: string): () => void {
addLocation(serverChunterId, () => import('@anticrm/server-chunter-resources'))
addLocation(serverRecruitId, () => import('@anticrm/server-recruit-resources'))
addLocation(serverViewId, () => import('@anticrm/server-view-resources'))
startJsonRpc((workspace: string) => {
return startJsonRpc((workspace: string) => {
const conf: DbConfiguration = {
domains: {
[DOMAIN_TX]: 'MongoTx',

View File

@ -55,4 +55,12 @@ const minio = new Client({
secretKey: minioSecretKey
})
start(url, elasticUrl, minio, 3000)
const shutdown = start(url, elasticUrl, minio, 3000)
const close = (): void => {
shutdown()
process.exit(0)
}
process.on('SIGINT', close)
process.on('SIGTERM', close)
process.on('exit', close)

View File

@ -77,7 +77,7 @@ async function minioUpload (minio: Client, workspace: string, file: UploadedFile
* @public
* @param port -
*/
export function start (transactorEndpoint: string, elasticUrl: string, minio: Client, port: number): void {
export function start (transactorEndpoint: string, elasticUrl: string, minio: Client, port: number): () => void {
const app = express()
app.use(cors())
@ -177,5 +177,8 @@ export function start (transactorEndpoint: string, elasticUrl: string, minio: Cl
}
})
app.listen(port)
const server = app.listen(port)
return () => {
server.close()
}
}

View File

@ -115,7 +115,7 @@ async function handleRequest<S> (service: S, ws: WebSocket, msg: string): Promis
* @param port -
* @param host -
*/
export function start (storageFactory: (workspace: string) => Promise<ServerStorage>, port: number, host?: string): void {
export function start (storageFactory: (workspace: string) => Promise<ServerStorage>, port: number, host?: string): () => void {
console.log(`starting server on port ${port} ...`)
const sessions = new SessionManager()
@ -151,4 +151,7 @@ export function start (storageFactory: (workspace: string) => Promise<ServerStor
})
server.listen(port, host)
return () => {
server.close()
}
}