azure-kusto-ingest 2.2.3 → 3.2.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/.eslintignore +5 -0
- package/.eslintrc.js +247 -0
- package/.mocharc.json +2 -2
- package/.prettierignore +8 -0
- package/.prettierrc.json +5 -0
- package/README.md +64 -62
- package/example.js +20 -30
- package/index.d.ts +24 -2
- package/index.js +46 -6
- package/index.js.map +1 -1
- package/package.json +70 -55
- package/source/abstractKustoClient.d.ts +8 -7
- package/source/abstractKustoClient.js +20 -16
- package/source/abstractKustoClient.js.map +1 -1
- package/source/columnMappings.d.ts +114 -0
- package/source/columnMappings.js +241 -0
- package/source/columnMappings.js.map +1 -0
- package/source/descriptors.d.ts +4 -3
- package/source/descriptors.js +16 -6
- package/source/descriptors.js.map +1 -1
- package/source/errors.d.ts +3 -0
- package/source/errors.js +13 -0
- package/source/errors.js.map +1 -0
- package/source/ingestClient.d.ts +6 -7
- package/source/ingestClient.js +10 -14
- package/source/ingestClient.js.map +1 -1
- package/source/ingestionBlobInfo.js +12 -9
- package/source/ingestionBlobInfo.js.map +1 -1
- package/source/ingestionProperties.d.ts +104 -40
- package/source/ingestionProperties.js +180 -84
- package/source/ingestionProperties.js.map +1 -1
- package/source/managedStreamingIngestClient.d.ts +36 -0
- package/source/managedStreamingIngestClient.js +107 -0
- package/source/managedStreamingIngestClient.js.map +1 -0
- package/source/resourceManager.d.ts +1 -1
- package/source/resourceManager.js +14 -16
- package/source/resourceManager.js.map +1 -1
- package/source/retry.d.ts +10 -0
- package/source/retry.js +44 -0
- package/source/retry.js.map +1 -0
- package/source/status.js +6 -17
- package/source/status.js.map +1 -1
- package/source/statusQ.js +7 -6
- package/source/statusQ.js.map +1 -1
- package/source/streamUtils.d.ts +6 -0
- package/source/streamUtils.js +61 -0
- package/source/streamUtils.js.map +1 -0
- package/source/streamingIngestClient.d.ts +5 -6
- package/source/streamingIngestClient.js +8 -19
- package/source/streamingIngestClient.js.map +1 -1
- package/tsconfig.json +16 -16
- package/tsconfig.tsbuildinfo +1 -1
- package/index.ts +0 -48
- package/tslint.json +0 -18
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/*
|
|
2
|
+
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
|
|
3
|
+
https://github.com/typescript-eslint/tslint-to-eslint-config
|
|
4
|
+
|
|
5
|
+
It represents the closest reasonable ESLint configuration to this
|
|
6
|
+
project's original TSLint configuration.
|
|
7
|
+
|
|
8
|
+
We recommend eventually switching this configuration to extend from
|
|
9
|
+
the recommended rulesets in typescript-eslint.
|
|
10
|
+
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
|
|
11
|
+
|
|
12
|
+
Happy linting! 💖
|
|
13
|
+
*/
|
|
14
|
+
module.exports = {
|
|
15
|
+
"env": {
|
|
16
|
+
"browser": true,
|
|
17
|
+
"es6": true,
|
|
18
|
+
"node": true
|
|
19
|
+
},
|
|
20
|
+
"extends": [
|
|
21
|
+
"eslint:recommended",
|
|
22
|
+
"plugin:@typescript-eslint/recommended",
|
|
23
|
+
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
|
24
|
+
"prettier"
|
|
25
|
+
],
|
|
26
|
+
"ignorePatterns": [
|
|
27
|
+
"node_modules",
|
|
28
|
+
"**/*.d.ts",
|
|
29
|
+
"**/*.js"
|
|
30
|
+
],
|
|
31
|
+
"parser": "@typescript-eslint/parser",
|
|
32
|
+
"parserOptions": {
|
|
33
|
+
"project": "tsconfig.json",
|
|
34
|
+
"sourceType": "module"
|
|
35
|
+
},
|
|
36
|
+
"plugins": [
|
|
37
|
+
"eslint-plugin-jsdoc",
|
|
38
|
+
"eslint-plugin-prefer-arrow",
|
|
39
|
+
"@typescript-eslint",
|
|
40
|
+
"header"
|
|
41
|
+
],
|
|
42
|
+
"rules": {
|
|
43
|
+
"@typescript-eslint/adjacent-overload-signatures": "error",
|
|
44
|
+
"@typescript-eslint/array-type": [
|
|
45
|
+
"error",
|
|
46
|
+
{
|
|
47
|
+
"default": "array"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"@typescript-eslint/ban-ts-comment": "error",
|
|
51
|
+
"@typescript-eslint/ban-types": [
|
|
52
|
+
"error",
|
|
53
|
+
{
|
|
54
|
+
"types": {
|
|
55
|
+
"Object": {
|
|
56
|
+
"message": "Avoid using the `Object` type. Did you mean `object`?"
|
|
57
|
+
},
|
|
58
|
+
"Function": {
|
|
59
|
+
"message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."
|
|
60
|
+
},
|
|
61
|
+
"Boolean": {
|
|
62
|
+
"message": "Avoid using the `Boolean` type. Did you mean `boolean`?"
|
|
63
|
+
},
|
|
64
|
+
"Number": {
|
|
65
|
+
"message": "Avoid using the `Number` type. Did you mean `number`?"
|
|
66
|
+
},
|
|
67
|
+
"String": {
|
|
68
|
+
"message": "Avoid using the `String` type. Did you mean `string`?"
|
|
69
|
+
},
|
|
70
|
+
"Symbol": {
|
|
71
|
+
"message": "Avoid using the `Symbol` type. Did you mean `symbol`?"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"@typescript-eslint/consistent-type-assertions": "error",
|
|
77
|
+
"@typescript-eslint/dot-notation": "error",
|
|
78
|
+
"@typescript-eslint/no-array-constructor": "error",
|
|
79
|
+
"@typescript-eslint/no-empty-interface": "error",
|
|
80
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
81
|
+
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
|
82
|
+
"@typescript-eslint/no-extra-semi": "error",
|
|
83
|
+
"@typescript-eslint/no-loss-of-precision": "error",
|
|
84
|
+
"@typescript-eslint/no-misused-new": "error",
|
|
85
|
+
"@typescript-eslint/no-namespace": "error",
|
|
86
|
+
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
|
87
|
+
"@typescript-eslint/no-parameter-properties": "off",
|
|
88
|
+
"@typescript-eslint/no-shadow": [
|
|
89
|
+
"error",
|
|
90
|
+
{
|
|
91
|
+
"hoist": "all"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"@typescript-eslint/no-this-alias": "error",
|
|
95
|
+
"@typescript-eslint/no-unnecessary-type-constraint": "error",
|
|
96
|
+
"@typescript-eslint/no-unused-expressions": "error",
|
|
97
|
+
"@typescript-eslint/no-unused-vars": "warn",
|
|
98
|
+
"@typescript-eslint/no-use-before-define": "off",
|
|
99
|
+
"@typescript-eslint/no-var-requires": "error",
|
|
100
|
+
"@typescript-eslint/prefer-as-const": "error",
|
|
101
|
+
"@typescript-eslint/prefer-for-of": "error",
|
|
102
|
+
"@typescript-eslint/prefer-function-type": "error",
|
|
103
|
+
"@typescript-eslint/prefer-namespace-keyword": "error",
|
|
104
|
+
"@typescript-eslint/triple-slash-reference": [
|
|
105
|
+
"error",
|
|
106
|
+
{
|
|
107
|
+
"path": "always",
|
|
108
|
+
"types": "prefer-import",
|
|
109
|
+
"lib": "always"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"@typescript-eslint/unified-signatures": "error",
|
|
113
|
+
"complexity": "off",
|
|
114
|
+
"constructor-super": "error",
|
|
115
|
+
"dot-notation": "error",
|
|
116
|
+
"eqeqeq": [
|
|
117
|
+
"error",
|
|
118
|
+
"smart"
|
|
119
|
+
],
|
|
120
|
+
"for-direction": "error",
|
|
121
|
+
"getter-return": "error",
|
|
122
|
+
"guard-for-in": "error",
|
|
123
|
+
"id-denylist": [
|
|
124
|
+
"error",
|
|
125
|
+
"any",
|
|
126
|
+
"Number",
|
|
127
|
+
"number",
|
|
128
|
+
"String",
|
|
129
|
+
"string",
|
|
130
|
+
"Boolean",
|
|
131
|
+
"boolean",
|
|
132
|
+
"Undefined",
|
|
133
|
+
"undefined"
|
|
134
|
+
],
|
|
135
|
+
"id-match": "error",
|
|
136
|
+
"jsdoc/check-alignment": "error",
|
|
137
|
+
"jsdoc/check-indentation": "error",
|
|
138
|
+
"jsdoc/newline-after-description": "error",
|
|
139
|
+
"max-classes-per-file": [
|
|
140
|
+
"error",
|
|
141
|
+
1
|
|
142
|
+
],
|
|
143
|
+
"new-parens": "error",
|
|
144
|
+
"no-array-constructor": "off",
|
|
145
|
+
"no-async-promise-executor": "error",
|
|
146
|
+
"no-bitwise": "error",
|
|
147
|
+
"no-caller": "error",
|
|
148
|
+
"no-case-declarations": "error",
|
|
149
|
+
"no-class-assign": "error",
|
|
150
|
+
"no-compare-neg-zero": "error",
|
|
151
|
+
"no-cond-assign": "error",
|
|
152
|
+
"no-console": "error",
|
|
153
|
+
"no-const-assign": "error",
|
|
154
|
+
"no-control-regex": "error",
|
|
155
|
+
"no-debugger": "error",
|
|
156
|
+
"no-delete-var": "error",
|
|
157
|
+
"no-dupe-args": "error",
|
|
158
|
+
"no-dupe-class-members": "error",
|
|
159
|
+
"no-dupe-else-if": "error",
|
|
160
|
+
"no-dupe-keys": "error",
|
|
161
|
+
"no-duplicate-case": "error",
|
|
162
|
+
"no-empty": "error",
|
|
163
|
+
"no-empty-character-class": "error",
|
|
164
|
+
"no-empty-pattern": "error",
|
|
165
|
+
"no-eval": "error",
|
|
166
|
+
"no-ex-assign": "error",
|
|
167
|
+
"no-extra-boolean-cast": "error",
|
|
168
|
+
"no-extra-semi": "off",
|
|
169
|
+
"no-fallthrough": "off",
|
|
170
|
+
"no-func-assign": "error",
|
|
171
|
+
"no-global-assign": "error",
|
|
172
|
+
"no-import-assign": "error",
|
|
173
|
+
"no-inner-declarations": "error",
|
|
174
|
+
"no-invalid-regexp": "error",
|
|
175
|
+
"no-invalid-this": "off",
|
|
176
|
+
"no-irregular-whitespace": "error",
|
|
177
|
+
"no-loss-of-precision": "off",
|
|
178
|
+
"no-misleading-character-class": "error",
|
|
179
|
+
"no-mixed-spaces-and-tabs": "error",
|
|
180
|
+
"no-new-symbol": "error",
|
|
181
|
+
"no-new-wrappers": "error",
|
|
182
|
+
"no-nonoctal-decimal-escape": "error",
|
|
183
|
+
"no-obj-calls": "error",
|
|
184
|
+
"no-octal": "error",
|
|
185
|
+
"no-prototype-builtins": "error",
|
|
186
|
+
"no-redeclare": "error",
|
|
187
|
+
"no-regex-spaces": "error",
|
|
188
|
+
"no-self-assign": "error",
|
|
189
|
+
"no-setter-return": "error",
|
|
190
|
+
"no-shadow-restricted-names": "error",
|
|
191
|
+
"no-sparse-arrays": "error",
|
|
192
|
+
"no-this-before-super": "error",
|
|
193
|
+
"no-throw-literal": "error",
|
|
194
|
+
"no-trailing-spaces": "error",
|
|
195
|
+
"no-undef-init": "error",
|
|
196
|
+
"no-unexpected-multiline": "error",
|
|
197
|
+
"no-unreachable": "error",
|
|
198
|
+
"no-unsafe-finally": "error",
|
|
199
|
+
"no-unsafe-negation": "error",
|
|
200
|
+
"no-unsafe-optional-chaining": "error",
|
|
201
|
+
"no-unused-expressions": "error",
|
|
202
|
+
"no-unused-labels": "error",
|
|
203
|
+
"no-unused-vars": "off",
|
|
204
|
+
"no-use-before-define": "off",
|
|
205
|
+
"no-useless-backreference": "error",
|
|
206
|
+
"no-useless-catch": "error",
|
|
207
|
+
"no-useless-escape": "error",
|
|
208
|
+
"no-var": "error",
|
|
209
|
+
"no-with": "error",
|
|
210
|
+
"object-shorthand": "error",
|
|
211
|
+
"one-var": [
|
|
212
|
+
"error",
|
|
213
|
+
"never"
|
|
214
|
+
],
|
|
215
|
+
"prefer-arrow/prefer-arrow-functions": "error",
|
|
216
|
+
"prefer-const": "error",
|
|
217
|
+
"radix": "error",
|
|
218
|
+
"require-yield": "error",
|
|
219
|
+
"spaced-comment": [
|
|
220
|
+
"error",
|
|
221
|
+
"always",
|
|
222
|
+
{
|
|
223
|
+
"markers": [
|
|
224
|
+
"/"
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
"use-isnan": "error",
|
|
229
|
+
"valid-typeof": "off",
|
|
230
|
+
|
|
231
|
+
// Rules that were added manually
|
|
232
|
+
|
|
233
|
+
"header/header": ["error", "line", " Copyright (c) Microsoft Corporation.\n Licensed under the MIT License."],
|
|
234
|
+
|
|
235
|
+
// Disabled rules to avoid too many changes, consider re-enabling in the future
|
|
236
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
237
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
238
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
239
|
+
"@typescript-eslint/restrict-template-expressions": "off",
|
|
240
|
+
"@typescript-eslint/no-empty-function": "off",
|
|
241
|
+
"@typescript-eslint/no-inferrable-types": "off",
|
|
242
|
+
"no-undef":"off",
|
|
243
|
+
"@typescript-eslint/no-non-null-assertion":"off",
|
|
244
|
+
"@typescript-eslint/no-unnecessary-type-assertion":"off",
|
|
245
|
+
"no-constant-condition": "off",
|
|
246
|
+
}
|
|
247
|
+
};
|
package/.mocharc.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
}
|
|
2
|
+
"enable-source-maps": true
|
|
3
|
+
}
|
package/.prettierignore
ADDED
package/.prettierrc.json
ADDED
package/README.md
CHANGED
|
@@ -6,41 +6,35 @@
|
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
|
-
```javascript
|
|
9
|
+
```javascript
|
|
10
10
|
const IngestClient = require("azure-kusto-ingest").IngestClient;
|
|
11
11
|
const IngestionProps = require("azure-kusto-ingest").IngestionProperties;
|
|
12
12
|
const KustoConnectionStringBuilder = require("azure-kusto-data").KustoConnectionStringBuilder;
|
|
13
|
-
const { DataFormat, JsonColumnMapping } = require("azure-kusto-ingest")
|
|
13
|
+
const { DataFormat, JsonColumnMapping } = require("azure-kusto-ingest");
|
|
14
14
|
|
|
15
15
|
const kcsb = KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(`https://ingest-${cluster}.kusto.windows.net`, appId, appKey, authorityId);
|
|
16
16
|
|
|
17
|
-
const ingestionProps = new IngestionProps(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
17
|
+
const ingestionProps = new IngestionProps({
|
|
18
|
+
database: "Database",
|
|
19
|
+
table: "Table",
|
|
20
|
+
format: DataFormat.JSON,
|
|
21
|
+
ingestionMapping: [
|
|
22
|
+
new JsonColumnMapping("TargetColumn1", "$.sourceProp1"),
|
|
23
|
+
new JsonColumnMapping("TargetColumn2", "$.sourceProp2"),
|
|
24
|
+
new JsonColumnMapping("TargetColumn3", "$.sourceProp3"),
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const ingestClient = new IngestClient(kcsb, ingestionProps);
|
|
29
29
|
|
|
30
|
-
const ingestClient = new IngestClient(
|
|
31
|
-
kcsb,
|
|
32
|
-
ingestionProps
|
|
33
|
-
);
|
|
34
|
-
|
|
35
30
|
console.log("Ingest from file");
|
|
36
31
|
|
|
37
32
|
Ingest();
|
|
38
33
|
|
|
39
34
|
async function Ingest() {
|
|
40
|
-
try{
|
|
35
|
+
try {
|
|
41
36
|
await ingestClient.ingestFromFile("file.json", null);
|
|
42
|
-
}
|
|
43
|
-
catch(err){
|
|
37
|
+
} catch (err) {
|
|
44
38
|
console.log(err);
|
|
45
39
|
}
|
|
46
40
|
console.log("Wait for ingestion status...");
|
|
@@ -49,36 +43,52 @@ async function Ingest() {
|
|
|
49
43
|
```
|
|
50
44
|
|
|
51
45
|
## Authentication
|
|
46
|
+
|
|
52
47
|
There are several authentication methods
|
|
53
48
|
|
|
54
49
|
### AAD App
|
|
50
|
+
|
|
55
51
|
The are two ways to authenticate is to use app id and key
|
|
56
52
|
|
|
57
53
|
1. Using app key
|
|
54
|
+
|
|
58
55
|
```javascript
|
|
59
|
-
const kcsb = KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(
|
|
56
|
+
const kcsb = KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(
|
|
57
|
+
`https://ingest-${clusterName}.kusto.windows.net`,
|
|
58
|
+
"appid",
|
|
59
|
+
"appkey",
|
|
60
|
+
"authorityId"
|
|
61
|
+
);
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
1. Using a certificate:
|
|
63
65
|
|
|
64
66
|
```javascript
|
|
65
|
-
const kcsb = KustoConnectionStringBuilder.withAadApplicationCertificateAuthentication(
|
|
67
|
+
const kcsb = KustoConnectionStringBuilder.withAadApplicationCertificateAuthentication(
|
|
68
|
+
`https://ingest-${clusterName}.kusto.windows.net`,
|
|
69
|
+
"appid",
|
|
70
|
+
"certificate",
|
|
71
|
+
"thumbprint",
|
|
72
|
+
"authorityId"
|
|
73
|
+
);
|
|
66
74
|
```
|
|
67
75
|
|
|
68
|
-
|
|
69
76
|
### Username/Password
|
|
77
|
+
|
|
70
78
|
```javascript
|
|
71
|
-
KustoConnectionStringBuilder.withAadUserPasswordAuthentication(`https://${clusterName}.kusto.windows.net`,
|
|
79
|
+
KustoConnectionStringBuilder.withAadUserPasswordAuthentication(`https://${clusterName}.kusto.windows.net`, "username", "password");
|
|
72
80
|
```
|
|
73
81
|
|
|
74
|
-
Authority is optional
|
|
82
|
+
Authority is optional _when it can be inferred from the domain_ ('user@microsoft.com' would make the authority 'microsoft.com').
|
|
75
83
|
In any case it is possible to pass the authority id
|
|
84
|
+
|
|
76
85
|
```javascript
|
|
77
|
-
KustoConnectionStringBuilder.withAadUserPasswordAuthentication(`https://ingest-${clusterName}.kusto.windows.net`,
|
|
86
|
+
KustoConnectionStringBuilder.withAadUserPasswordAuthentication(`https://ingest-${clusterName}.kusto.windows.net`, "username", "password", "authorityId");
|
|
78
87
|
```
|
|
79
88
|
|
|
80
89
|
### Device
|
|
81
|
-
|
|
90
|
+
|
|
91
|
+
Using this method will write a token to the console, which can be used to authenticate at https://login.microsoftonline.com/common/oauth2/deviceauth and will allow temporary access.
|
|
82
92
|
|
|
83
93
|
**<!>It is not ment for production purposes<!>**
|
|
84
94
|
|
|
@@ -101,6 +111,7 @@ A Quick Overview is available at https://docs.microsoft.com/en-us/azure/data-exp
|
|
|
101
111
|
Notice ingestion is done against the ingestion endpoint, which usually include `ingest-` prefix on the cluster name.
|
|
102
112
|
|
|
103
113
|
### Ingestion Properties
|
|
114
|
+
|
|
104
115
|
Ingestion Props are instructions for Kusto on how to process the data.
|
|
105
116
|
|
|
106
117
|
The easiest way to provide ingestion properties is to set them on the ingestion client like in the sample above.
|
|
@@ -109,26 +120,22 @@ It is also possible to pass them on each ingestion (will merge them with default
|
|
|
109
120
|
Example props:
|
|
110
121
|
|
|
111
122
|
```javascript
|
|
112
|
-
const ingestionProps = new IngestionProps(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
new JsonColumnMapping("TargetColumn1", "$.sourceProp1"),
|
|
118
|
-
new JsonColumnMapping("TargetColumn2", "$.sourceProp2"),
|
|
119
|
-
new JsonColumnMapping("TargetColumn3", "$.sourceProp3")
|
|
120
|
-
]
|
|
121
|
-
);
|
|
123
|
+
const ingestionProps = new IngestionProps("Database", "Table", DataFormat.JSON, [
|
|
124
|
+
new JsonColumnMapping("TargetColumn1", "$.sourceProp1"),
|
|
125
|
+
new JsonColumnMapping("TargetColumn2", "$.sourceProp2"),
|
|
126
|
+
new JsonColumnMapping("TargetColumn3", "$.sourceProp3"),
|
|
127
|
+
]);
|
|
122
128
|
```
|
|
123
129
|
|
|
124
130
|
### Ingestion Sources
|
|
131
|
+
|
|
125
132
|
There are several methods of ingesting data into Kusto (Azure Data Explorer) using this library
|
|
126
133
|
|
|
127
134
|
#### From Stream
|
|
128
135
|
|
|
129
136
|
This is useful for cases you already have streams available (http respinse, file stream, etc..)
|
|
130
137
|
|
|
131
|
-
|
|
138
|
+
````javascript
|
|
132
139
|
try{
|
|
133
140
|
await ingestClient.ingestFromStream(readable, null);
|
|
134
141
|
}
|
|
@@ -150,19 +157,17 @@ try{
|
|
|
150
157
|
catch(err){
|
|
151
158
|
console.log(err);
|
|
152
159
|
}
|
|
153
|
-
|
|
160
|
+
````
|
|
154
161
|
|
|
155
162
|
#### From Azure Storage Blob
|
|
156
163
|
|
|
157
164
|
Probably the easiest way would be to provide a uri (with [SAS](https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1)).
|
|
158
165
|
|
|
159
166
|
```javascript
|
|
160
|
-
|
|
161
167
|
let blob = new BlobDescriptor(blobUri, size);
|
|
162
|
-
try{
|
|
168
|
+
try {
|
|
163
169
|
await ingestClient.ingestFromBlob(blob, null);
|
|
164
|
-
}
|
|
165
|
-
catch(err){
|
|
170
|
+
} catch (err) {
|
|
166
171
|
console.log(err);
|
|
167
172
|
}
|
|
168
173
|
```
|
|
@@ -179,38 +184,36 @@ For Example:
|
|
|
179
184
|
const IngestClient = require("azure-kusto-ingest").IngestClient;
|
|
180
185
|
const IngestStatusQueues = require("azure-kusto-ingest").IngestStatusQueues;
|
|
181
186
|
const IngestionProps = require("azure-kusto-ingest").IngestionProperties;
|
|
182
|
-
const { ReportLevel, ReportMethod } = require("azure-kusto-ingest")
|
|
187
|
+
const { ReportLevel, ReportMethod } = require("azure-kusto-ingest");
|
|
183
188
|
const KustoConnectionStringBuilder = require("azure-kusto-data").KustoConnectionStringBuilder;
|
|
184
|
-
const { DataFormat, JsonColumnMapping } = require("azure-kusto-ingest")
|
|
189
|
+
const { DataFormat, JsonColumnMapping } = require("azure-kusto-ingest");
|
|
185
190
|
const fs = require("fs");
|
|
186
191
|
|
|
187
|
-
|
|
188
192
|
const ingestClient = new IngestClient(
|
|
189
193
|
KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(`https://ingest-${clusterName}.kusto.windows.net`, appId, appKey, authorityId),
|
|
190
194
|
new IngestionProps(
|
|
191
195
|
"db",
|
|
192
196
|
"table",
|
|
193
197
|
DataFormat.JSON,
|
|
194
|
-
[
|
|
195
|
-
|
|
196
|
-
new JsonColumnMapping("Type", "$.type"),
|
|
197
|
-
new JsonColumnMapping("Value", "$.type"),
|
|
198
|
-
],
|
|
198
|
+
[new JsonColumnMapping("Id", "$.id"), new JsonColumnMapping("Type", "$.type"), new JsonColumnMapping("Value", "$.type")],
|
|
199
|
+
null,
|
|
199
200
|
null,
|
|
200
201
|
null,
|
|
201
202
|
null,
|
|
202
203
|
null,
|
|
203
204
|
null,
|
|
204
|
-
null,
|
|
205
205
|
ReportLevel.FailuresAndSuccesses,
|
|
206
|
-
ReportMethod.Queue
|
|
206
|
+
ReportMethod.Queue
|
|
207
|
+
)
|
|
207
208
|
);
|
|
208
209
|
|
|
209
210
|
const statusQueues = new IngestStatusQueues(ingestClient);
|
|
210
211
|
|
|
211
212
|
async function waitForStatus() {
|
|
212
|
-
while (await statusQueues.failure.isEmpty() && await statusQueues.success.isEmpty()) {
|
|
213
|
-
await new Promise((resolve) => {
|
|
213
|
+
while ((await statusQueues.failure.isEmpty()) && (await statusQueues.success.isEmpty())) {
|
|
214
|
+
await new Promise((resolve) => {
|
|
215
|
+
setTimeout(resolve, 1000);
|
|
216
|
+
});
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
const successes = statusQueues.success.pop();
|
|
@@ -218,20 +221,19 @@ async function waitForStatus() {
|
|
|
218
221
|
console.log(JSON.stringify(success));
|
|
219
222
|
}
|
|
220
223
|
|
|
221
|
-
const failures = statusQueues.failure.pop()
|
|
224
|
+
const failures = statusQueues.failure.pop();
|
|
222
225
|
for (let failure of failures) {
|
|
223
226
|
console.log(JSON.stringify(failure));
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
|
|
227
230
|
async function ingestFromFile() {
|
|
228
|
-
try{
|
|
231
|
+
try {
|
|
229
232
|
await ingestClient.ingestFromFile("file.json", null);
|
|
230
|
-
}
|
|
231
|
-
catch(err){
|
|
233
|
+
} catch (err) {
|
|
232
234
|
console.log(err);
|
|
233
235
|
}
|
|
234
236
|
console.log("Wait for ingestion status...");
|
|
235
237
|
await waitForStatus();
|
|
236
238
|
}
|
|
237
|
-
|
|
239
|
+
```
|
package/example.js
CHANGED
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
const IngestClient = require("azure-kusto-ingest").IngestClient;
|
|
5
5
|
const IngestStatusQueues = require("azure-kusto-ingest").IngestStatusQueues;
|
|
6
6
|
const IngestionProps = require("azure-kusto-ingest").IngestionProperties;
|
|
7
|
-
const { ReportLevel, ReportMethod } = require("azure-kusto-ingest").IngestionPropertiesEnums;
|
|
8
7
|
const KustoConnectionStringBuilder = require("azure-kusto-data").KustoConnectionStringBuilder;
|
|
9
|
-
const { DataFormat, JsonColumnMapping,
|
|
8
|
+
const { DataFormat, JsonColumnMapping, IngestionMappingKind, CompressionType, ReportLevel, ReportMethod } = require("azure-kusto-ingest");
|
|
10
9
|
const { BlobDescriptor, StreamDescriptor } = require("azure-kusto-ingest").IngestionDescriptors;
|
|
11
10
|
const StreamingIngestClient = require("azure-kusto-ingest").StreamingIngestClient;
|
|
12
|
-
const fs = require(
|
|
11
|
+
const fs = require("fs");
|
|
13
12
|
|
|
14
13
|
const clusterName = null;
|
|
15
14
|
const appId = null;
|
|
@@ -23,18 +22,15 @@ const props = new IngestionProps({
|
|
|
23
22
|
ingestionMapping: [
|
|
24
23
|
new JsonColumnMapping("TargetColumn1", "$.sourceProp1"),
|
|
25
24
|
new JsonColumnMapping("TargetColumn2", "$.sourceProp2"),
|
|
26
|
-
new JsonColumnMapping("TargetColumn3", "$.sourceProp3")
|
|
25
|
+
new JsonColumnMapping("TargetColumn3", "$.sourceProp3"),
|
|
27
26
|
],
|
|
28
|
-
ingestionMappingType:
|
|
27
|
+
ingestionMappingType: IngestionMappingKind.JSON,
|
|
29
28
|
reportLevel: ReportLevel.FailuresAndSuccesses,
|
|
30
|
-
reportMethod: ReportMethod.Queue
|
|
31
|
-
|
|
29
|
+
reportMethod: ReportMethod.Queue,
|
|
32
30
|
});
|
|
33
31
|
|
|
34
32
|
const ingestClient = new IngestClient(
|
|
35
|
-
KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(
|
|
36
|
-
`https://ingest-${clusterName}.kusto.windows.net`, appId, appKey, authorityId
|
|
37
|
-
),
|
|
33
|
+
KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(`https://ingest-${clusterName}.kusto.windows.net`, appId, appKey, authorityId),
|
|
38
34
|
props
|
|
39
35
|
);
|
|
40
36
|
|
|
@@ -42,19 +38,17 @@ const statusQueues = new IngestStatusQueues(ingestClient);
|
|
|
42
38
|
|
|
43
39
|
startIngestion();
|
|
44
40
|
|
|
45
|
-
// Streaming ingest client
|
|
41
|
+
// Streaming ingest client
|
|
46
42
|
const props2 = new IngestionProps({
|
|
47
43
|
database: "Database",
|
|
48
44
|
table: "Table",
|
|
49
45
|
format: DataFormat.JSON,
|
|
50
|
-
ingestionMappingReference: "Pre-
|
|
46
|
+
ingestionMappingReference: "Pre-defined mapping name",
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
// Init with engine endpoint
|
|
54
50
|
const streamingIngestClient = new StreamingIngestClient(
|
|
55
|
-
KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(
|
|
56
|
-
`https://${clusterName}.kusto.windows.net`, appId, appKey, authorityId
|
|
57
|
-
),
|
|
51
|
+
KustoConnectionStringBuilder.withAadApplicationKeyAuthentication(`https://${clusterName}.kusto.windows.net`, appId, appKey, authorityId),
|
|
58
52
|
props2
|
|
59
53
|
);
|
|
60
54
|
|
|
@@ -67,8 +61,7 @@ async function startIngestion() {
|
|
|
67
61
|
console.log("Ingestion done?");
|
|
68
62
|
|
|
69
63
|
await waitForStatus();
|
|
70
|
-
}
|
|
71
|
-
catch (err) {
|
|
64
|
+
} catch (err) {
|
|
72
65
|
console.log(err);
|
|
73
66
|
}
|
|
74
67
|
|
|
@@ -77,14 +70,13 @@ async function startIngestion() {
|
|
|
77
70
|
console.log("Ingestion done?");
|
|
78
71
|
|
|
79
72
|
await waitForStatus();
|
|
80
|
-
}
|
|
81
|
-
catch (err) {
|
|
73
|
+
} catch (err) {
|
|
82
74
|
console.log(err);
|
|
83
75
|
}
|
|
84
76
|
}
|
|
85
77
|
|
|
86
78
|
async function waitForStatus(numberOFIngestions = 1) {
|
|
87
|
-
while (await statusQueues.failure.isEmpty() && await statusQueues.success.isEmpty()) {
|
|
79
|
+
while ((await statusQueues.failure.isEmpty()) && (await statusQueues.success.isEmpty())) {
|
|
88
80
|
console.log("Waiting for status...");
|
|
89
81
|
await sleep(1000);
|
|
90
82
|
}
|
|
@@ -100,27 +92,26 @@ async function waitForStatus(numberOFIngestions = 1) {
|
|
|
100
92
|
}
|
|
101
93
|
|
|
102
94
|
function sleep(ms) {
|
|
103
|
-
return new Promise((resolve) => {
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
setTimeout(resolve, ms);
|
|
97
|
+
});
|
|
104
98
|
}
|
|
105
99
|
|
|
106
100
|
async function startStreamingIngestion() {
|
|
107
|
-
|
|
108
101
|
// Ingest from file with either file path or FileDescriptor
|
|
109
102
|
try {
|
|
110
103
|
await streamingIngestClient.ingestFromFile("file.json", props2);
|
|
111
104
|
console.log("Ingestion done");
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
105
|
+
} catch (err) {
|
|
114
106
|
console.log(err);
|
|
115
107
|
}
|
|
116
108
|
|
|
117
109
|
// Ingest from stream with either ReadStream or StreamDescriptor
|
|
118
110
|
let stream = fs.createReadStream("file.json");
|
|
119
111
|
try {
|
|
120
|
-
await streamingIngestClient.ingestFromStream(
|
|
112
|
+
await streamingIngestClient.ingestFromStream(stream, props2);
|
|
121
113
|
console.log("Ingestion done");
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
114
|
+
} catch (err) {
|
|
124
115
|
console.log(err);
|
|
125
116
|
}
|
|
126
117
|
|
|
@@ -130,8 +121,7 @@ async function startStreamingIngestion() {
|
|
|
130
121
|
try {
|
|
131
122
|
await streamingIngestClient.ingestFromStream(streamDescriptor, props2);
|
|
132
123
|
console.log("Ingestion done");
|
|
133
|
-
}
|
|
134
|
-
catch (err) {
|
|
124
|
+
} catch (err) {
|
|
135
125
|
console.log(err);
|
|
136
126
|
}
|
|
137
|
-
}
|
|
127
|
+
}
|