@toxplanet/pegasus-sdk 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/environment.acc.js +27 -0
- package/config/environment.dev.js +6 -1
- package/config/environment.prod.js +6 -1
- package/config/environment.qa.js +5 -0
- package/config/index.js +1 -1
- package/index.js +44 -37
- package/lib/chemicals.js +293 -229
- package/lib/connection.js +223 -223
- package/lib/documents.js +94 -47
- package/lib/elasticsearch.js +404 -0
- package/lib/search.js +336 -307
- package/lib/sync.js +43 -41
- package/lib/utils.js +49 -47
- package/package.json +48 -25
- package/env.example +0 -21
- package/index.d.ts +0 -252
- package/tests/chemicals.js +0 -165
- package/tests/search.js +0 -138
package/lib/connection.js
CHANGED
|
@@ -1,223 +1,223 @@
|
|
|
1
|
-
const { Pool } = require('pg');
|
|
2
|
-
const { Client } = require('@opensearch-project/opensearch');
|
|
3
|
-
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');
|
|
4
|
-
const { AwsSigv4Signer } = require('@opensearch-project/opensearch/aws');
|
|
5
|
-
const { fromNodeProviderChain } = require('@aws-sdk/credential-providers');
|
|
6
|
-
const { loadConfig } = require('../config');
|
|
7
|
-
const { logInfo, logError } = require('@toxplanet/tphelper/logging');
|
|
8
|
-
|
|
9
|
-
class PegasusConnection {
|
|
10
|
-
constructor(config = {}) {
|
|
11
|
-
const envConfig = loadConfig(config.environment);
|
|
12
|
-
|
|
13
|
-
this.config = { ...envConfig, ...config };
|
|
14
|
-
this.environment = this.config.environment;
|
|
15
|
-
this.region = this.config.region;
|
|
16
|
-
this.secretName = this.config.secretName;
|
|
17
|
-
this.openSearchEndpoint = this.config.openSearchEndpoint;
|
|
18
|
-
this.openSearchIndex = this.config.openSearchIndex;
|
|
19
|
-
this.databaseHost = this.config.database?.host;
|
|
20
|
-
this.databaseName = this.config.database?.name;
|
|
21
|
-
|
|
22
|
-
this.pgPool = null;
|
|
23
|
-
this.osClient = null;
|
|
24
|
-
this.secretsClient = null;
|
|
25
|
-
this.cachedSecret = null;
|
|
26
|
-
this.isConnected = false;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async getSecret() {
|
|
30
|
-
if (this.cachedSecret) {
|
|
31
|
-
return this.cachedSecret;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (!this.secretsClient) {
|
|
35
|
-
this.secretsClient = new SecretsManagerClient({ region: this.region });
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const command = new GetSecretValueCommand({ SecretId: this.secretName });
|
|
39
|
-
const response = await this.secretsClient.send(command);
|
|
40
|
-
|
|
41
|
-
if (response.SecretString) {
|
|
42
|
-
this.cachedSecret = JSON.parse(response.SecretString);
|
|
43
|
-
return this.cachedSecret;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
throw new Error(`Secret ${this.secretName} does not contain SecretString`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async connect() {
|
|
50
|
-
if (this.isConnected) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const secret = await this.getSecret();
|
|
55
|
-
|
|
56
|
-
const poolConfig = {
|
|
57
|
-
host: this.databaseHost,
|
|
58
|
-
port: 5432,
|
|
59
|
-
database: this.databaseName,
|
|
60
|
-
user: secret.username,
|
|
61
|
-
password: secret.password,
|
|
62
|
-
max: this.config.postgres.maxConnections,
|
|
63
|
-
min: this.config.postgres.minConnections,
|
|
64
|
-
idleTimeoutMillis: this.config.postgres.idleTimeoutMillis,
|
|
65
|
-
connectionTimeoutMillis: this.config.postgres.connectionTimeoutMillis,
|
|
66
|
-
allowExitOnIdle: true,
|
|
67
|
-
ssl: this.config.postgres.ssl,
|
|
68
|
-
statement_timeout: this.config.postgres.statementTimeout,
|
|
69
|
-
query_timeout: this.config.postgres.queryTimeout
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
this.pgPool = new Pool(poolConfig);
|
|
73
|
-
|
|
74
|
-
this.pgPool.on('error', (err) => {
|
|
75
|
-
logError('pegasus-sdk', 'PegasusConnection', 'pgPool.error', err);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
this.pgPool.on('connect', () => {
|
|
79
|
-
logInfo('pegasus-sdk', 'PostgreSQL client connected');
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
this.pgPool.on('remove', () => {
|
|
83
|
-
logInfo('pegasus-sdk', 'PostgreSQL client removed from pool');
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
if (this.openSearchEndpoint) {
|
|
87
|
-
this.osClient = new Client({
|
|
88
|
-
...AwsSigv4Signer({
|
|
89
|
-
region: this.region,
|
|
90
|
-
service: 'aoss',
|
|
91
|
-
getCredentials: () => {
|
|
92
|
-
const credentialsProvider = fromNodeProviderChain();
|
|
93
|
-
return credentialsProvider();
|
|
94
|
-
}
|
|
95
|
-
}),
|
|
96
|
-
node: this.openSearchEndpoint
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
this.isConnected = true;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async disconnect() {
|
|
104
|
-
if (!this.isConnected) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (this.pgPool) {
|
|
109
|
-
await this.pgPool.end();
|
|
110
|
-
this.pgPool = null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
this.osClient = null;
|
|
114
|
-
this.isConnected = false;
|
|
115
|
-
this.cachedSecret = null;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
getPostgresClient() {
|
|
119
|
-
if (!this.pgPool) {
|
|
120
|
-
throw new Error('PostgreSQL connection not established. Call connect() first.');
|
|
121
|
-
}
|
|
122
|
-
return this.pgPool;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
getOpenSearchClient() {
|
|
126
|
-
if (!this.osClient) {
|
|
127
|
-
throw new Error('OpenSearch connection not established. Call connect() first or provide openSearchEndpoint.');
|
|
128
|
-
}
|
|
129
|
-
return this.osClient;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
getOpenSearchIndex() {
|
|
133
|
-
return this.openSearchIndex || 'chemicals';
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async testConnection() {
|
|
137
|
-
try {
|
|
138
|
-
if (this.pgPool) {
|
|
139
|
-
const client = await this.pgPool.connect();
|
|
140
|
-
const result = await client.query('SELECT NOW() as current_time, version() as pg_version');
|
|
141
|
-
client.release();
|
|
142
|
-
|
|
143
|
-
const pgStatus = {
|
|
144
|
-
connected: true,
|
|
145
|
-
timestamp: result.rows[0].current_time,
|
|
146
|
-
version: result.rows[0].pg_version,
|
|
147
|
-
poolSize: this.pgPool.totalCount,
|
|
148
|
-
idleConnections: this.pgPool.idleCount,
|
|
149
|
-
waitingRequests: this.pgPool.waitingCount
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
let osStatus = null;
|
|
153
|
-
if (this.osClient) {
|
|
154
|
-
try {
|
|
155
|
-
const indexName = this.getOpenSearchIndex();
|
|
156
|
-
const testSearch = await this.osClient.search({
|
|
157
|
-
index: indexName,
|
|
158
|
-
body: {
|
|
159
|
-
size: 1,
|
|
160
|
-
query: {
|
|
161
|
-
match: { chemical_name: 'benzene' }
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
osStatus = {
|
|
166
|
-
connected: true,
|
|
167
|
-
resultsFound: testSearch.body.hits.total.value || 0
|
|
168
|
-
};
|
|
169
|
-
} catch (osError) {
|
|
170
|
-
osStatus = {
|
|
171
|
-
connected: false,
|
|
172
|
-
error: osError.message
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
postgres: pgStatus,
|
|
179
|
-
opensearch: osStatus,
|
|
180
|
-
environment: this.environment,
|
|
181
|
-
region: this.region
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
throw new Error('No active connections');
|
|
186
|
-
} catch (error) {
|
|
187
|
-
return {
|
|
188
|
-
postgres: { connected: false, error: error.message },
|
|
189
|
-
opensearch: null,
|
|
190
|
-
environment: this.environment,
|
|
191
|
-
region: this.region
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async query(sql, params) {
|
|
197
|
-
const pool = this.getPostgresClient();
|
|
198
|
-
return pool.query(sql, params);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async getClient() {
|
|
202
|
-
const pool = this.getPostgresClient();
|
|
203
|
-
return pool.connect();
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async transaction(callback) {
|
|
207
|
-
const client = await this.getClient();
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
await client.query('BEGIN');
|
|
211
|
-
const result = await callback(client);
|
|
212
|
-
await client.query('COMMIT');
|
|
213
|
-
return result;
|
|
214
|
-
} catch (error) {
|
|
215
|
-
await client.query('ROLLBACK');
|
|
216
|
-
throw error;
|
|
217
|
-
} finally {
|
|
218
|
-
client.release();
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
module.exports = PegasusConnection;
|
|
1
|
+
const { Pool } = require('pg');
|
|
2
|
+
const { Client } = require('@opensearch-project/opensearch');
|
|
3
|
+
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');
|
|
4
|
+
const { AwsSigv4Signer } = require('@opensearch-project/opensearch/aws');
|
|
5
|
+
const { fromNodeProviderChain } = require('@aws-sdk/credential-providers');
|
|
6
|
+
const { loadConfig } = require('../config');
|
|
7
|
+
const { logInfo, logError } = require('@toxplanet/tphelper/logging');
|
|
8
|
+
|
|
9
|
+
class PegasusConnection {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
const envConfig = loadConfig(config.environment);
|
|
12
|
+
|
|
13
|
+
this.config = { ...envConfig, ...config };
|
|
14
|
+
this.environment = this.config.environment;
|
|
15
|
+
this.region = this.config.region;
|
|
16
|
+
this.secretName = this.config.secretName;
|
|
17
|
+
this.openSearchEndpoint = this.config.openSearchEndpoint;
|
|
18
|
+
this.openSearchIndex = this.config.openSearchIndex;
|
|
19
|
+
this.databaseHost = this.config.database?.host;
|
|
20
|
+
this.databaseName = this.config.database?.name;
|
|
21
|
+
|
|
22
|
+
this.pgPool = null;
|
|
23
|
+
this.osClient = null;
|
|
24
|
+
this.secretsClient = null;
|
|
25
|
+
this.cachedSecret = null;
|
|
26
|
+
this.isConnected = false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async getSecret() {
|
|
30
|
+
if (this.cachedSecret) {
|
|
31
|
+
return this.cachedSecret;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!this.secretsClient) {
|
|
35
|
+
this.secretsClient = new SecretsManagerClient({ region: this.region });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const command = new GetSecretValueCommand({ SecretId: this.secretName });
|
|
39
|
+
const response = await this.secretsClient.send(command);
|
|
40
|
+
|
|
41
|
+
if (response.SecretString) {
|
|
42
|
+
this.cachedSecret = JSON.parse(response.SecretString);
|
|
43
|
+
return this.cachedSecret;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw new Error(`Secret ${this.secretName} does not contain SecretString`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async connect() {
|
|
50
|
+
if (this.isConnected) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const secret = await this.getSecret();
|
|
55
|
+
|
|
56
|
+
const poolConfig = {
|
|
57
|
+
host: this.databaseHost,
|
|
58
|
+
port: 5432,
|
|
59
|
+
database: this.databaseName,
|
|
60
|
+
user: secret.username,
|
|
61
|
+
password: secret.password,
|
|
62
|
+
max: this.config.postgres.maxConnections,
|
|
63
|
+
min: this.config.postgres.minConnections,
|
|
64
|
+
idleTimeoutMillis: this.config.postgres.idleTimeoutMillis,
|
|
65
|
+
connectionTimeoutMillis: this.config.postgres.connectionTimeoutMillis,
|
|
66
|
+
allowExitOnIdle: true,
|
|
67
|
+
ssl: this.config.postgres.ssl,
|
|
68
|
+
statement_timeout: this.config.postgres.statementTimeout,
|
|
69
|
+
query_timeout: this.config.postgres.queryTimeout
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
this.pgPool = new Pool(poolConfig);
|
|
73
|
+
|
|
74
|
+
this.pgPool.on('error', (err) => {
|
|
75
|
+
logError('pegasus-sdk', 'PegasusConnection', 'pgPool.error', err);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
this.pgPool.on('connect', () => {
|
|
79
|
+
logInfo('pegasus-sdk', 'PostgreSQL client connected');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
this.pgPool.on('remove', () => {
|
|
83
|
+
logInfo('pegasus-sdk', 'PostgreSQL client removed from pool');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (this.openSearchEndpoint) {
|
|
87
|
+
this.osClient = new Client({
|
|
88
|
+
...AwsSigv4Signer({
|
|
89
|
+
region: this.region,
|
|
90
|
+
service: 'aoss',
|
|
91
|
+
getCredentials: () => {
|
|
92
|
+
const credentialsProvider = fromNodeProviderChain();
|
|
93
|
+
return credentialsProvider();
|
|
94
|
+
}
|
|
95
|
+
}),
|
|
96
|
+
node: this.openSearchEndpoint
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.isConnected = true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async disconnect() {
|
|
104
|
+
if (!this.isConnected) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (this.pgPool) {
|
|
109
|
+
await this.pgPool.end();
|
|
110
|
+
this.pgPool = null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.osClient = null;
|
|
114
|
+
this.isConnected = false;
|
|
115
|
+
this.cachedSecret = null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getPostgresClient() {
|
|
119
|
+
if (!this.pgPool) {
|
|
120
|
+
throw new Error('PostgreSQL connection not established. Call connect() first.');
|
|
121
|
+
}
|
|
122
|
+
return this.pgPool;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getOpenSearchClient() {
|
|
126
|
+
if (!this.osClient) {
|
|
127
|
+
throw new Error('OpenSearch connection not established. Call connect() first or provide openSearchEndpoint.');
|
|
128
|
+
}
|
|
129
|
+
return this.osClient;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getOpenSearchIndex() {
|
|
133
|
+
return this.openSearchIndex || 'chemicals';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async testConnection() {
|
|
137
|
+
try {
|
|
138
|
+
if (this.pgPool) {
|
|
139
|
+
const client = await this.pgPool.connect();
|
|
140
|
+
const result = await client.query('SELECT NOW() as current_time, version() as pg_version');
|
|
141
|
+
client.release();
|
|
142
|
+
|
|
143
|
+
const pgStatus = {
|
|
144
|
+
connected: true,
|
|
145
|
+
timestamp: result.rows[0].current_time,
|
|
146
|
+
version: result.rows[0].pg_version,
|
|
147
|
+
poolSize: this.pgPool.totalCount,
|
|
148
|
+
idleConnections: this.pgPool.idleCount,
|
|
149
|
+
waitingRequests: this.pgPool.waitingCount
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
let osStatus = null;
|
|
153
|
+
if (this.osClient) {
|
|
154
|
+
try {
|
|
155
|
+
const indexName = this.getOpenSearchIndex();
|
|
156
|
+
const testSearch = await this.osClient.search({
|
|
157
|
+
index: indexName,
|
|
158
|
+
body: {
|
|
159
|
+
size: 1,
|
|
160
|
+
query: {
|
|
161
|
+
match: { chemical_name: 'benzene' }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
osStatus = {
|
|
166
|
+
connected: true,
|
|
167
|
+
resultsFound: testSearch.body.hits.total.value || 0
|
|
168
|
+
};
|
|
169
|
+
} catch (osError) {
|
|
170
|
+
osStatus = {
|
|
171
|
+
connected: false,
|
|
172
|
+
error: osError.message
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
postgres: pgStatus,
|
|
179
|
+
opensearch: osStatus,
|
|
180
|
+
environment: this.environment,
|
|
181
|
+
region: this.region
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
throw new Error('No active connections');
|
|
186
|
+
} catch (error) {
|
|
187
|
+
return {
|
|
188
|
+
postgres: { connected: false, error: error.message },
|
|
189
|
+
opensearch: null,
|
|
190
|
+
environment: this.environment,
|
|
191
|
+
region: this.region
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async query(sql, params) {
|
|
197
|
+
const pool = this.getPostgresClient();
|
|
198
|
+
return pool.query(sql, params);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async getClient() {
|
|
202
|
+
const pool = this.getPostgresClient();
|
|
203
|
+
return pool.connect();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async transaction(callback) {
|
|
207
|
+
const client = await this.getClient();
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
await client.query('BEGIN');
|
|
211
|
+
const result = await callback(client);
|
|
212
|
+
await client.query('COMMIT');
|
|
213
|
+
return result;
|
|
214
|
+
} catch (error) {
|
|
215
|
+
await client.query('ROLLBACK');
|
|
216
|
+
throw error;
|
|
217
|
+
} finally {
|
|
218
|
+
client.release();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = PegasusConnection;
|
package/lib/documents.js
CHANGED
|
@@ -1,47 +1,94 @@
|
|
|
1
|
-
class DocumentsService {
|
|
2
|
-
constructor(connection) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
async
|
|
7
|
-
|
|
8
|
-
async
|
|
9
|
-
|
|
10
|
-
async
|
|
11
|
-
|
|
12
|
-
async
|
|
13
|
-
|
|
14
|
-
async
|
|
15
|
-
|
|
16
|
-
async
|
|
17
|
-
|
|
18
|
-
async
|
|
19
|
-
|
|
20
|
-
async
|
|
21
|
-
|
|
22
|
-
async
|
|
23
|
-
|
|
24
|
-
async
|
|
25
|
-
|
|
26
|
-
async
|
|
27
|
-
|
|
28
|
-
async
|
|
29
|
-
|
|
30
|
-
async
|
|
31
|
-
|
|
32
|
-
async
|
|
33
|
-
|
|
34
|
-
async
|
|
35
|
-
|
|
36
|
-
async
|
|
37
|
-
|
|
38
|
-
async
|
|
39
|
-
|
|
40
|
-
async
|
|
41
|
-
|
|
42
|
-
async
|
|
43
|
-
|
|
44
|
-
async
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
1
|
+
class DocumentsService {
|
|
2
|
+
constructor(connection) {
|
|
3
|
+
this.connection = connection;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async createDocument(documentPath, casNumbers) {}
|
|
7
|
+
|
|
8
|
+
async bulkCreateDocuments(documents) {}
|
|
9
|
+
|
|
10
|
+
async updateDocument(documentId, updates) {}
|
|
11
|
+
|
|
12
|
+
async deleteDocument(documentId) {}
|
|
13
|
+
|
|
14
|
+
async deleteDocumentByPath(documentPath) {}
|
|
15
|
+
|
|
16
|
+
async getDocumentById(documentId) {}
|
|
17
|
+
|
|
18
|
+
async getDocumentByPath(documentPath) {}
|
|
19
|
+
|
|
20
|
+
async getDocumentsByCAS(casNumber) {}
|
|
21
|
+
|
|
22
|
+
async getCASByDocument(documentId) {}
|
|
23
|
+
|
|
24
|
+
async getCASByDocumentPath(documentPath) {}
|
|
25
|
+
|
|
26
|
+
async addCASToDocument(documentId, casNumber) {}
|
|
27
|
+
|
|
28
|
+
async addCASToDocumentBatch(documentId, casNumbers) {}
|
|
29
|
+
|
|
30
|
+
async removeCASFromDocument(documentId, casNumber) {}
|
|
31
|
+
|
|
32
|
+
async findDocumentsWithMultipleCAS(casNumbers, requireAll) {}
|
|
33
|
+
|
|
34
|
+
async countDocuments() {}
|
|
35
|
+
|
|
36
|
+
async countDocumentsByCAS(casNumber) {}
|
|
37
|
+
|
|
38
|
+
async countUniqueCAS() {}
|
|
39
|
+
|
|
40
|
+
async getTopCASByDocumentCount(limit) {}
|
|
41
|
+
|
|
42
|
+
async extractTextFromPDF(pdfBuffer) {}
|
|
43
|
+
|
|
44
|
+
async extractCASFromText(text) {}
|
|
45
|
+
|
|
46
|
+
async processDocument(documentPath, documentData) {}
|
|
47
|
+
|
|
48
|
+
registerElasticsearchHandlers(elasticsearchService) {
|
|
49
|
+
const indexPatterns = this.connection.config.indexRoutes?.documents || ['documents*'];
|
|
50
|
+
|
|
51
|
+
indexPatterns.forEach(pattern => {
|
|
52
|
+
elasticsearchService.registerIndexRoute(pattern, {
|
|
53
|
+
index: async (params) => {
|
|
54
|
+
const document = params.body;
|
|
55
|
+
return await this.createDocument(document.document_path, document.cas_numbers || []);
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
bulk: async (params) => {
|
|
59
|
+
const operations = params.body || params.operations;
|
|
60
|
+
const documents = [];
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < operations.length; i += 2) {
|
|
63
|
+
const action = operations[i];
|
|
64
|
+
const document = operations[i + 1];
|
|
65
|
+
|
|
66
|
+
if (action.index || action.create) {
|
|
67
|
+
documents.push(document);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return await this.bulkCreateDocuments(documents);
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
get: async (params) => {
|
|
75
|
+
return await this.getDocumentById(params.id);
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
update: async (params) => {
|
|
79
|
+
return await this.updateDocument(params.id, params.body);
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
delete: async (params) => {
|
|
83
|
+
return await this.deleteDocument(params.id);
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
count: async (params) => {
|
|
87
|
+
return await this.countDocuments();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = DocumentsService;
|