azure-kusto-ingest 4.0.5 → 5.0.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/README.md +15 -2
- package/{source → dist-esm/src}/abstractKustoClient.js +0 -0
- package/{source → dist-esm/src}/columnMappings.js +0 -0
- package/dist-esm/src/descriptors.js +64 -0
- package/{source → dist-esm/src}/errors.js +0 -0
- package/dist-esm/src/fileDescriptor.browser.js +44 -0
- package/dist-esm/src/fileDescriptor.js +81 -0
- package/{index.js → dist-esm/src/index.js} +12 -10
- package/dist-esm/src/ingestClient.browser.js +43 -0
- package/dist-esm/src/ingestClient.js +45 -0
- package/dist-esm/src/ingestClientBase.js +47 -0
- package/{source → dist-esm/src}/ingestionBlobInfo.js +1 -5
- package/{source → dist-esm/src}/ingestionProperties.js +0 -0
- package/{source → dist-esm/src}/managedStreamingIngestClient.js +36 -38
- package/dist-esm/src/resourceManager.js +142 -0
- package/dist-esm/src/retry.js +37 -0
- package/{source → dist-esm/src}/status.js +0 -0
- package/dist-esm/src/statusQ.js +119 -0
- package/dist-esm/src/streamUtils.browser.js +22 -0
- package/{source → dist-esm/src}/streamUtils.js +24 -19
- package/dist-esm/src/streamingIngestClient.browser.js +42 -0
- package/dist-esm/src/streamingIngestClient.js +51 -0
- package/dist-esm/tsconfig.tsbuildinfo +1 -0
- package/package.json +35 -20
- package/{source → types/src}/abstractKustoClient.d.ts +4 -5
- package/{source → types/src}/columnMappings.d.ts +1 -0
- package/types/src/descriptors.d.ts +39 -0
- package/{source → types/src}/errors.d.ts +1 -0
- package/types/src/fileDescriptor.browser.d.ts +16 -0
- package/types/src/fileDescriptor.d.ts +29 -0
- package/{index.d.ts → types/src/index.d.ts} +13 -11
- package/types/src/ingestClient.browser.d.ts +19 -0
- package/types/src/ingestClient.d.ts +21 -0
- package/types/src/ingestClientBase.d.ts +14 -0
- package/{source → types/src}/ingestionBlobInfo.d.ts +2 -2
- package/{source → types/src}/ingestionProperties.d.ts +1 -0
- package/{source → types/src}/managedStreamingIngestClient.d.ts +12 -4
- package/{source → types/src}/resourceManager.d.ts +7 -5
- package/{source → types/src}/retry.d.ts +1 -0
- package/{source → types/src}/status.d.ts +1 -0
- package/{source → types/src}/statusQ.d.ts +1 -0
- package/types/src/streamUtils.browser.d.ts +7 -0
- package/types/src/streamUtils.d.ts +8 -0
- package/types/src/streamingIngestClient.browser.d.ts +21 -0
- package/types/src/streamingIngestClient.d.ts +23 -0
- package/example.js +0 -128
- package/source/descriptors.d.ts +0 -37
- package/source/descriptors.js +0 -125
- package/source/ingestClient.d.ts +0 -19
- package/source/ingestClient.js +0 -104
- package/source/resourceManager.js +0 -158
- package/source/retry.js +0 -48
- package/source/statusQ.js +0 -138
- package/source/streamUtils.d.ts +0 -6
- package/source/streamingIngestClient.d.ts +0 -15
- package/source/streamingIngestClient.js +0 -52
- package/tsconfig.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Microsoft Azure Kusto Ingest Library for
|
|
1
|
+
# Microsoft Azure Kusto Ingest Library for JavaScript
|
|
2
2
|
|
|
3
3
|
## Installation
|
|
4
4
|
|
|
@@ -68,7 +68,6 @@ const kcsb = KustoConnectionStringBuilder.withAadApplicationCertificateAuthentic
|
|
|
68
68
|
`https://ingest-${clusterName}.kusto.windows.net`,
|
|
69
69
|
"appid",
|
|
70
70
|
"certificate",
|
|
71
|
-
"thumbprint",
|
|
72
71
|
"authorityId"
|
|
73
72
|
);
|
|
74
73
|
```
|
|
@@ -237,3 +236,17 @@ async function ingestFromFile() {
|
|
|
237
236
|
await waitForStatus();
|
|
238
237
|
}
|
|
239
238
|
```
|
|
239
|
+
|
|
240
|
+
#### From Browser Blob object
|
|
241
|
+
|
|
242
|
+
A full browser example can be found [here](packages/azure-kusto-ingest/exampleBrowser.ts)
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
const file = new Blob([`{"Name":"Moshe", "Value":2}`], { type: "application/json" });
|
|
246
|
+
let desc = new FileDescriptor(blobUri, size);
|
|
247
|
+
try {
|
|
248
|
+
await ingestClient.ingestFromFile(desp, null);
|
|
249
|
+
} catch (err) {
|
|
250
|
+
console.log(err);
|
|
251
|
+
}
|
|
252
|
+
```
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.generateBlobName = exports.BlobDescriptor = exports.StreamDescriptor = exports.getSourceId = exports.CompressionType = void 0;
|
|
9
|
+
const uuid_1 = require("uuid");
|
|
10
|
+
const uuid_validate_1 = __importDefault(require("uuid-validate"));
|
|
11
|
+
var CompressionType;
|
|
12
|
+
(function (CompressionType) {
|
|
13
|
+
CompressionType["ZIP"] = ".zip";
|
|
14
|
+
CompressionType["GZIP"] = ".gz";
|
|
15
|
+
CompressionType["None"] = "";
|
|
16
|
+
})(CompressionType = exports.CompressionType || (exports.CompressionType = {}));
|
|
17
|
+
const getSourceId = (sourceId) => {
|
|
18
|
+
if (sourceId) {
|
|
19
|
+
if (!(0, uuid_validate_1.default)(sourceId, 4)) {
|
|
20
|
+
throw Error("sourceId is not a valid uuid/v4");
|
|
21
|
+
}
|
|
22
|
+
return sourceId;
|
|
23
|
+
}
|
|
24
|
+
return (0, uuid_1.v4)();
|
|
25
|
+
};
|
|
26
|
+
exports.getSourceId = getSourceId;
|
|
27
|
+
class StreamDescriptor {
|
|
28
|
+
/**
|
|
29
|
+
* Use Readable for Node.js and ArrayBuffer in browser
|
|
30
|
+
*/
|
|
31
|
+
constructor(stream, sourceId = null, compressionType = CompressionType.None) {
|
|
32
|
+
this.stream = stream;
|
|
33
|
+
this.size = null;
|
|
34
|
+
this.compressionType = compressionType;
|
|
35
|
+
this.sourceId = (0, exports.getSourceId)(sourceId);
|
|
36
|
+
}
|
|
37
|
+
merge(other) {
|
|
38
|
+
this.size = other.size;
|
|
39
|
+
this.compressionType = other.compressionType;
|
|
40
|
+
this.sourceId = other.sourceId;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
// Currently streams are not compressed by us
|
|
44
|
+
getCompressionSuffix() {
|
|
45
|
+
return this.compressionType ? `.${this.compressionType}` : "";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.StreamDescriptor = StreamDescriptor;
|
|
49
|
+
class BlobDescriptor {
|
|
50
|
+
constructor(path, size = null, sourceId = null) {
|
|
51
|
+
this.path = path;
|
|
52
|
+
this.size = size;
|
|
53
|
+
this.sourceId = (0, exports.getSourceId)(sourceId);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.BlobDescriptor = BlobDescriptor;
|
|
57
|
+
const generateBlobName = (desc, props) => {
|
|
58
|
+
const extension = desc instanceof StreamDescriptor ? null : `${desc.name ? "__" + desc.name : `${desc.extension ? "." + desc.extension : ""}`}`;
|
|
59
|
+
const formatSuffix = props.format ? `.${props.format}` : ".csv";
|
|
60
|
+
const compressionString = desc.getCompressionSuffix();
|
|
61
|
+
return `${props.database}__${props.table}__${desc.sourceId}${extension || formatSuffix}${compressionString}`;
|
|
62
|
+
};
|
|
63
|
+
exports.generateBlobName = generateBlobName;
|
|
64
|
+
//# sourceMappingURL=descriptors.js.map
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.FileDescriptor = void 0;
|
|
9
|
+
const pako_1 = __importDefault(require("pako"));
|
|
10
|
+
const descriptors_1 = require("./descriptors");
|
|
11
|
+
class FileDescriptor {
|
|
12
|
+
constructor(file, sourceId = null, size = null, compressionType = descriptors_1.CompressionType.None, extension, name) {
|
|
13
|
+
this.file = file;
|
|
14
|
+
this.sourceId = sourceId;
|
|
15
|
+
this.extension = extension;
|
|
16
|
+
this.name = name;
|
|
17
|
+
this.sourceId = (0, descriptors_1.getSourceId)(sourceId);
|
|
18
|
+
this.compressionType = compressionType;
|
|
19
|
+
this.size = size || file.size;
|
|
20
|
+
this.zipped = compressionType !== descriptors_1.CompressionType.None || this.extension === ".gz" || this.extension === ".zip";
|
|
21
|
+
}
|
|
22
|
+
async prepare() {
|
|
23
|
+
if (!this.zipped) {
|
|
24
|
+
try {
|
|
25
|
+
const gzipped = pako_1.default.gzip(await this.file.arrayBuffer());
|
|
26
|
+
return new Blob([gzipped]);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
// Ignore - return the file itself
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return this.file;
|
|
33
|
+
}
|
|
34
|
+
async cleanup() {
|
|
35
|
+
if (this.cleanupTmp) {
|
|
36
|
+
await this.cleanupTmp();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
getCompressionSuffix() {
|
|
40
|
+
return this.compressionType ? `.${this.compressionType}` : ".gz";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.FileDescriptor = FileDescriptor;
|
|
44
|
+
//# sourceMappingURL=fileDescriptor.browser.js.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.FileDescriptor = void 0;
|
|
9
|
+
const zlib_1 = __importDefault(require("zlib"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const tmp_promise_1 = require("tmp-promise");
|
|
13
|
+
const util_1 = require("util");
|
|
14
|
+
const descriptors_1 = require("./descriptors");
|
|
15
|
+
/**
|
|
16
|
+
* Describes a file to be ingested. Use string to describe a local path in Node.JS and Blob object in browsers
|
|
17
|
+
*/
|
|
18
|
+
class FileDescriptor {
|
|
19
|
+
constructor(
|
|
20
|
+
/**
|
|
21
|
+
* Use string in Node.JS and Blob in browser
|
|
22
|
+
*/
|
|
23
|
+
file, sourceId = null, size = null, compressionType = descriptors_1.CompressionType.None, extension, // Extracted from file name by default
|
|
24
|
+
name // Extracted from file name by default
|
|
25
|
+
) {
|
|
26
|
+
this.file = file;
|
|
27
|
+
this.extension = extension;
|
|
28
|
+
this.name = name;
|
|
29
|
+
this.sourceId = (0, descriptors_1.getSourceId)(sourceId);
|
|
30
|
+
this.compressionType = compressionType;
|
|
31
|
+
this.name = name ? name : path_1.default.basename(this.file);
|
|
32
|
+
this.extension = extension ? extension : path_1.default.extname(this.file).toLowerCase();
|
|
33
|
+
this.size = size;
|
|
34
|
+
this.zipped = compressionType !== descriptors_1.CompressionType.None || this.extension === ".gz" || this.extension === ".zip";
|
|
35
|
+
}
|
|
36
|
+
async _gzip() {
|
|
37
|
+
const { path, cleanup } = await (0, tmp_promise_1.file)({ postfix: ".gz", keep: false });
|
|
38
|
+
this.cleanupTmp = cleanup;
|
|
39
|
+
const zipper = zlib_1.default.createGzip();
|
|
40
|
+
const input = fs_1.default.createReadStream(this.file, { autoClose: true });
|
|
41
|
+
const output = fs_1.default.createWriteStream(path);
|
|
42
|
+
await new Promise((resolve, reject) => {
|
|
43
|
+
input
|
|
44
|
+
.pipe(zipper)
|
|
45
|
+
.pipe(output)
|
|
46
|
+
.on("error", (err) => {
|
|
47
|
+
reject(err);
|
|
48
|
+
});
|
|
49
|
+
output.once("close", () => {
|
|
50
|
+
resolve(null);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
return path;
|
|
54
|
+
}
|
|
55
|
+
async prepare() {
|
|
56
|
+
if (this.zipped) {
|
|
57
|
+
const estimatedCompressionModifier = 11;
|
|
58
|
+
await this._calculateSize(estimatedCompressionModifier);
|
|
59
|
+
return this.file;
|
|
60
|
+
}
|
|
61
|
+
const path = await this._gzip();
|
|
62
|
+
await this._calculateSize();
|
|
63
|
+
return path;
|
|
64
|
+
}
|
|
65
|
+
async _calculateSize(modifier = 1) {
|
|
66
|
+
if (this.size == null || this.size <= 0) {
|
|
67
|
+
const asyncStat = (0, util_1.promisify)(fs_1.default.stat);
|
|
68
|
+
this.size = (await asyncStat(this.file)).size * modifier;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async cleanup() {
|
|
72
|
+
if (this.cleanupTmp) {
|
|
73
|
+
await this.cleanupTmp();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
getCompressionSuffix() {
|
|
77
|
+
return this.compressionType ? `.${this.compressionType}` : ".gz";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.FileDescriptor = FileDescriptor;
|
|
81
|
+
//# sourceMappingURL=fileDescriptor.js.map
|
|
@@ -6,11 +6,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
6
6
|
};
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.IngestionPropertiesValidationError = exports.IngestionPropertiesEnums = exports.ColumnMapping = exports.FieldTransformation = exports.ConstantTransformation = exports.SStreamColumnMapping = exports.ApacheAvroColumnMapping = exports.CompressionType = exports.IngestionMappingKind = exports.DataFormat = exports.ValidationOptions = exports.ValidationImplications = exports.ReportMethod = exports.ReportLevel = exports.ValidationPolicy = exports.W3CLogFileMapping = exports.OrcColumnMapping = exports.ParquetColumnMapping = exports.AvroColumnMapping = exports.CsvColumnMapping = exports.JsonColumnMapping = exports.IngestionDescriptors = exports.IngestionProperties = exports.IngestStatusQueues = exports.ManagedStreamingIngestClient = exports.StreamingIngestClient = exports.IngestClient = void 0;
|
|
9
|
-
const ingestClient_1 = __importDefault(require("./
|
|
10
|
-
const streamingIngestClient_1 = __importDefault(require("./
|
|
11
|
-
const managedStreamingIngestClient_1 = __importDefault(require("./
|
|
12
|
-
const status_1 = __importDefault(require("./
|
|
13
|
-
const ingestionProperties_1 = require("./
|
|
9
|
+
const ingestClient_1 = __importDefault(require("./ingestClient"));
|
|
10
|
+
const streamingIngestClient_1 = __importDefault(require("./streamingIngestClient"));
|
|
11
|
+
const managedStreamingIngestClient_1 = __importDefault(require("./managedStreamingIngestClient"));
|
|
12
|
+
const status_1 = __importDefault(require("./status"));
|
|
13
|
+
const ingestionProperties_1 = require("./ingestionProperties");
|
|
14
14
|
Object.defineProperty(exports, "DataFormat", { enumerable: true, get: function () { return ingestionProperties_1.DataFormat; } });
|
|
15
15
|
Object.defineProperty(exports, "IngestionMappingKind", { enumerable: true, get: function () { return ingestionProperties_1.IngestionMappingKind; } });
|
|
16
16
|
Object.defineProperty(exports, "ReportLevel", { enumerable: true, get: function () { return ingestionProperties_1.ReportLevel; } });
|
|
@@ -18,9 +18,10 @@ Object.defineProperty(exports, "ReportMethod", { enumerable: true, get: function
|
|
|
18
18
|
Object.defineProperty(exports, "ValidationImplications", { enumerable: true, get: function () { return ingestionProperties_1.ValidationImplications; } });
|
|
19
19
|
Object.defineProperty(exports, "ValidationOptions", { enumerable: true, get: function () { return ingestionProperties_1.ValidationOptions; } });
|
|
20
20
|
Object.defineProperty(exports, "ValidationPolicy", { enumerable: true, get: function () { return ingestionProperties_1.ValidationPolicy; } });
|
|
21
|
-
const descriptors_1 = require("./
|
|
21
|
+
const descriptors_1 = require("./descriptors");
|
|
22
22
|
Object.defineProperty(exports, "CompressionType", { enumerable: true, get: function () { return descriptors_1.CompressionType; } });
|
|
23
|
-
const
|
|
23
|
+
const fileDescriptor_1 = require("./fileDescriptor");
|
|
24
|
+
const columnMappings_1 = require("./columnMappings");
|
|
24
25
|
Object.defineProperty(exports, "ApacheAvroColumnMapping", { enumerable: true, get: function () { return columnMappings_1.ApacheAvroColumnMapping; } });
|
|
25
26
|
Object.defineProperty(exports, "AvroColumnMapping", { enumerable: true, get: function () { return columnMappings_1.AvroColumnMapping; } });
|
|
26
27
|
Object.defineProperty(exports, "ColumnMapping", { enumerable: true, get: function () { return columnMappings_1.ColumnMapping; } });
|
|
@@ -36,11 +37,11 @@ exports.IngestClient = ingestClient_1.default;
|
|
|
36
37
|
exports.StreamingIngestClient = streamingIngestClient_1.default;
|
|
37
38
|
exports.ManagedStreamingIngestClient = managedStreamingIngestClient_1.default;
|
|
38
39
|
exports.IngestStatusQueues = status_1.default;
|
|
39
|
-
var ingestionProperties_2 = require("./
|
|
40
|
+
var ingestionProperties_2 = require("./ingestionProperties");
|
|
40
41
|
Object.defineProperty(exports, "IngestionProperties", { enumerable: true, get: function () { return ingestionProperties_2.IngestionProperties; } });
|
|
41
42
|
exports.IngestionDescriptors = {
|
|
42
43
|
BlobDescriptor: descriptors_1.BlobDescriptor,
|
|
43
|
-
FileDescriptor:
|
|
44
|
+
FileDescriptor: fileDescriptor_1.FileDescriptor,
|
|
44
45
|
StreamDescriptor: descriptors_1.StreamDescriptor,
|
|
45
46
|
};
|
|
46
47
|
/**
|
|
@@ -71,6 +72,7 @@ exports.IngestionPropertiesEnums = {
|
|
|
71
72
|
FieldTransformation: columnMappings_1.FieldTransformation,
|
|
72
73
|
ColumnMapping: columnMappings_1.ColumnMapping,
|
|
73
74
|
};
|
|
74
|
-
var errors_1 = require("./
|
|
75
|
+
var errors_1 = require("./errors");
|
|
75
76
|
Object.defineProperty(exports, "IngestionPropertiesValidationError", { enumerable: true, get: function () { return errors_1.IngestionPropertiesValidationError; } });
|
|
77
|
+
// eslint-disable-next-line no-console
|
|
76
78
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.KustoIngestClient = void 0;
|
|
6
|
+
const descriptors_1 = require("./descriptors");
|
|
7
|
+
const fileDescriptor_browser_1 = require("./fileDescriptor.browser");
|
|
8
|
+
const ingestClientBase_1 = require("./ingestClientBase");
|
|
9
|
+
class KustoIngestClient extends ingestClientBase_1.KustoIngestClientBase {
|
|
10
|
+
constructor(kcsb, defaultProps) {
|
|
11
|
+
super(kcsb, defaultProps, true);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Use string for Node.js and Blob in browser
|
|
15
|
+
*/
|
|
16
|
+
async ingestFromFile(file, ingestionProperties) {
|
|
17
|
+
this.ensureOpen();
|
|
18
|
+
const descriptor = file instanceof fileDescriptor_browser_1.FileDescriptor ? file : new fileDescriptor_browser_1.FileDescriptor(file);
|
|
19
|
+
const blob = descriptor.file;
|
|
20
|
+
const props = this._getMergedProps(ingestionProperties);
|
|
21
|
+
const [fileToUpload, blockBlobClient] = await Promise.all([
|
|
22
|
+
descriptor.prepare(),
|
|
23
|
+
this.resourceManager.getBlockBlobClient((0, descriptors_1.generateBlobName)(descriptor, props)),
|
|
24
|
+
]);
|
|
25
|
+
await blockBlobClient.uploadData(fileToUpload);
|
|
26
|
+
return this.ingestFromBlob(new descriptors_1.BlobDescriptor(blockBlobClient.url, blob.size, descriptor.sourceId), props);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Use Readable for Node.js and ArrayBuffer in browser
|
|
30
|
+
*/
|
|
31
|
+
async ingestFromStream(stream, ingestionProperties) {
|
|
32
|
+
this.ensureOpen();
|
|
33
|
+
const props = this._getMergedProps(ingestionProperties);
|
|
34
|
+
const descriptor = stream instanceof descriptors_1.StreamDescriptor ? stream : new descriptors_1.StreamDescriptor(stream);
|
|
35
|
+
const blobName = (0, descriptors_1.generateBlobName)(descriptor, props);
|
|
36
|
+
const blockBlobClient = await this.resourceManager.getBlockBlobClient(blobName);
|
|
37
|
+
await blockBlobClient.uploadData(descriptor.stream);
|
|
38
|
+
return this.ingestFromBlob(new descriptors_1.BlobDescriptor(blockBlobClient.url), props); // descriptor.size?
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.KustoIngestClient = KustoIngestClient;
|
|
42
|
+
exports.default = KustoIngestClient;
|
|
43
|
+
//# sourceMappingURL=ingestClient.browser.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.KustoIngestClient = void 0;
|
|
6
|
+
const descriptors_1 = require("./descriptors");
|
|
7
|
+
const fileDescriptor_1 = require("./fileDescriptor");
|
|
8
|
+
const ingestClientBase_1 = require("./ingestClientBase");
|
|
9
|
+
class KustoIngestClient extends ingestClientBase_1.KustoIngestClientBase {
|
|
10
|
+
constructor(kcsb, defaultProps) {
|
|
11
|
+
super(kcsb, defaultProps);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Use string in Node.JS and Blob in browser
|
|
15
|
+
*/
|
|
16
|
+
async ingestFromFile(file, ingestionProperties) {
|
|
17
|
+
this.ensureOpen();
|
|
18
|
+
const props = this._getMergedProps(ingestionProperties);
|
|
19
|
+
const descriptor = file instanceof fileDescriptor_1.FileDescriptor ? file : new fileDescriptor_1.FileDescriptor(file);
|
|
20
|
+
try {
|
|
21
|
+
const blobName = (0, descriptors_1.generateBlobName)(descriptor, props);
|
|
22
|
+
const [fileToUpload, blockBlobClient] = await Promise.all([descriptor.prepare(), this.resourceManager.getBlockBlobClient(blobName)]);
|
|
23
|
+
await blockBlobClient.uploadFile(fileToUpload);
|
|
24
|
+
return this.ingestFromBlob(new descriptors_1.BlobDescriptor(blockBlobClient.url, descriptor.size, descriptor.sourceId), props);
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
await descriptor.cleanup();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Use Readable in Node.JS and ArrayBuffer in browser
|
|
32
|
+
*/
|
|
33
|
+
async ingestFromStream(stream, ingestionProperties) {
|
|
34
|
+
this.ensureOpen();
|
|
35
|
+
const props = this._getMergedProps(ingestionProperties);
|
|
36
|
+
const descriptor = stream instanceof descriptors_1.StreamDescriptor ? stream : new descriptors_1.StreamDescriptor(stream);
|
|
37
|
+
const blobName = (0, descriptors_1.generateBlobName)(descriptor, props);
|
|
38
|
+
const blockBlobClient = await this.resourceManager.getBlockBlobClient(blobName);
|
|
39
|
+
await blockBlobClient.uploadStream(descriptor.stream);
|
|
40
|
+
return this.ingestFromBlob(new descriptors_1.BlobDescriptor(blockBlobClient.url), props); // descriptor.size?
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.KustoIngestClient = KustoIngestClient;
|
|
44
|
+
exports.default = KustoIngestClient;
|
|
45
|
+
//# sourceMappingURL=ingestClient.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.KustoIngestClientBase = void 0;
|
|
9
|
+
const azure_kusto_data_1 = require("azure-kusto-data");
|
|
10
|
+
const descriptors_1 = require("./descriptors");
|
|
11
|
+
const resourceManager_1 = __importDefault(require("./resourceManager"));
|
|
12
|
+
const ingestionBlobInfo_1 = __importDefault(require("./ingestionBlobInfo"));
|
|
13
|
+
const storage_queue_1 = require("@azure/storage-queue");
|
|
14
|
+
const abstractKustoClient_1 = require("./abstractKustoClient");
|
|
15
|
+
class KustoIngestClientBase extends abstractKustoClient_1.AbstractKustoClient {
|
|
16
|
+
constructor(kcsb, defaultProps, isBrowser) {
|
|
17
|
+
super(defaultProps);
|
|
18
|
+
const kustoClient = new azure_kusto_data_1.Client(kcsb);
|
|
19
|
+
this.resourceManager = new resourceManager_1.default(kustoClient, isBrowser);
|
|
20
|
+
this.defaultDatabase = kustoClient.defaultDatabase;
|
|
21
|
+
}
|
|
22
|
+
async ingestFromBlob(blob, ingestionProperties) {
|
|
23
|
+
this.ensureOpen();
|
|
24
|
+
const props = this._getMergedProps(ingestionProperties);
|
|
25
|
+
const descriptor = blob instanceof descriptors_1.BlobDescriptor ? blob : new descriptors_1.BlobDescriptor(blob);
|
|
26
|
+
const queues = await this.resourceManager.getIngestionQueues();
|
|
27
|
+
if (queues == null) {
|
|
28
|
+
throw new Error("Failed to get queues");
|
|
29
|
+
}
|
|
30
|
+
const authorizationContext = await this.resourceManager.getAuthorizationContext();
|
|
31
|
+
const queueDetails = queues[Math.floor(Math.random() * queues.length)];
|
|
32
|
+
const queueClient = new storage_queue_1.QueueClient(queueDetails.uri);
|
|
33
|
+
const ingestionBlobInfo = new ingestionBlobInfo_1.default(descriptor, props, authorizationContext);
|
|
34
|
+
const ingestionBlobInfoJson = JSON.stringify(ingestionBlobInfo);
|
|
35
|
+
const encoded = Buffer.from(ingestionBlobInfoJson).toString("base64");
|
|
36
|
+
return queueClient.sendMessage(encoded);
|
|
37
|
+
}
|
|
38
|
+
close() {
|
|
39
|
+
if (!this._isClosed) {
|
|
40
|
+
this.resourceManager.close();
|
|
41
|
+
}
|
|
42
|
+
super.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.KustoIngestClientBase = KustoIngestClientBase;
|
|
46
|
+
exports.default = KustoIngestClientBase;
|
|
47
|
+
//# sourceMappingURL=ingestClientBase.js.map
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Copyright (c) Microsoft Corporation.
|
|
3
3
|
// Licensed under the MIT License.
|
|
4
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
-
};
|
|
7
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
5
|
exports.IngestionBlobInfo = void 0;
|
|
9
6
|
const uuid_1 = require("uuid");
|
|
10
|
-
const moment_1 = __importDefault(require("moment"));
|
|
11
7
|
class IngestionBlobInfo {
|
|
12
8
|
constructor(blobDescriptor, ingestionProperties, authContext = null) {
|
|
13
9
|
var _a, _b, _c, _d, _e;
|
|
@@ -20,7 +16,7 @@ class IngestionBlobInfo {
|
|
|
20
16
|
this.IgnoreSizeLimit = false;
|
|
21
17
|
this.ReportLevel = (_d = ingestionProperties.reportLevel) !== null && _d !== void 0 ? _d : null;
|
|
22
18
|
this.ReportMethod = (_e = ingestionProperties.reportMethod) !== null && _e !== void 0 ? _e : null;
|
|
23
|
-
this.SourceMessageCreationTime =
|
|
19
|
+
this.SourceMessageCreationTime = new Date();
|
|
24
20
|
this.Id = blobDescriptor.sourceId || (0, uuid_1.v4)();
|
|
25
21
|
const additionalProperties = ingestionProperties.additionalProperties || {};
|
|
26
22
|
additionalProperties.authorizationContext = authContext;
|
|
File without changes
|
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Copyright (c) Microsoft Corporation.
|
|
3
3
|
// Licensed under the MIT License.
|
|
4
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
7
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
8
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
-
});
|
|
12
|
-
};
|
|
13
4
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
5
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
6
|
};
|
|
16
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
8
|
const descriptors_1 = require("./descriptors");
|
|
9
|
+
const fileDescriptor_1 = require("./fileDescriptor");
|
|
18
10
|
const abstractKustoClient_1 = require("./abstractKustoClient");
|
|
19
11
|
const azure_kusto_data_1 = require("azure-kusto-data");
|
|
20
|
-
const streamUtils_1 = require("./streamUtils");
|
|
21
12
|
const streamingIngestClient_1 = __importDefault(require("./streamingIngestClient"));
|
|
13
|
+
const streamUtils_1 = require("./streamUtils");
|
|
22
14
|
const ingestClient_1 = __importDefault(require("./ingestClient"));
|
|
23
15
|
const stream_array_1 = __importDefault(require("stream-array"));
|
|
24
16
|
const retry_1 = require("./retry");
|
|
17
|
+
const core_util_1 = require("@azure/core-util");
|
|
25
18
|
const maxStreamSize = 1024 * 1024 * 4;
|
|
26
19
|
const attemptCount = 3;
|
|
27
20
|
const ingestPrefix = "https://ingest-";
|
|
@@ -71,38 +64,43 @@ class KustoManagedStreamingIngestClient extends abstractKustoClient_1.AbstractKu
|
|
|
71
64
|
}
|
|
72
65
|
this.defaultDatabase = this.streamingIngestClient.defaultDatabase;
|
|
73
66
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Use Readable for Node.js and ArrayBuffer in browser
|
|
69
|
+
*/
|
|
70
|
+
async ingestFromStream(stream, ingestionProperties) {
|
|
71
|
+
this.ensureOpen();
|
|
72
|
+
const props = this._getMergedProps(ingestionProperties);
|
|
73
|
+
const descriptor = stream instanceof descriptors_1.StreamDescriptor ? stream : new descriptors_1.StreamDescriptor(stream);
|
|
74
|
+
let result = core_util_1.isNode ? await (0, streamUtils_1.tryStreamToArray)(descriptor.stream, maxStreamSize) : descriptor.stream;
|
|
75
|
+
if ((core_util_1.isNode && result instanceof Buffer) || (!core_util_1.isNode && descriptor.stream.byteLength < maxStreamSize)) {
|
|
76
|
+
// If we get buffer that means it was less than the max size, so we can do streamingIngestion
|
|
77
|
+
const retry = new retry_1.ExponentialRetry(attemptCount, this.baseSleepTimeSecs, this.baseJitterSecs);
|
|
78
|
+
while (retry.shouldTry()) {
|
|
79
|
+
try {
|
|
80
|
+
const sourceId = `KNC.executeManagedStreamingIngest;${descriptor.sourceId};${retry.currentAttempt}`;
|
|
81
|
+
return core_util_1.isNode
|
|
82
|
+
? await this.streamingIngestClient.ingestFromStream(new descriptors_1.StreamDescriptor((0, stream_array_1.default)([result])).merge(descriptor), props, sourceId)
|
|
83
|
+
: await this.streamingIngestClient.ingestFromStream(descriptor, props, sourceId);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
const oneApiError = err;
|
|
87
|
+
if (oneApiError["@permanent"]) {
|
|
88
|
+
throw err;
|
|
94
89
|
}
|
|
90
|
+
await retry.backoff();
|
|
95
91
|
}
|
|
96
|
-
result = (0, stream_array_1.default)([result]);
|
|
97
92
|
}
|
|
98
|
-
|
|
99
|
-
}
|
|
93
|
+
result = core_util_1.isNode ? (0, stream_array_1.default)([result]) : descriptor.stream;
|
|
94
|
+
}
|
|
95
|
+
return await this.queuedIngestClient.ingestFromStream(new descriptors_1.StreamDescriptor(result).merge(descriptor), ingestionProperties);
|
|
100
96
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Use string for Node.js and Blob in browser
|
|
99
|
+
*/
|
|
100
|
+
async ingestFromFile(file, ingestionProperties) {
|
|
101
|
+
this.ensureOpen();
|
|
102
|
+
const stream = file instanceof fileDescriptor_1.FileDescriptor ? await (0, streamUtils_1.tryFileToBuffer)(file) : await (0, streamUtils_1.tryFileToBuffer)(new fileDescriptor_1.FileDescriptor(file));
|
|
103
|
+
return await this.ingestFromStream(stream, ingestionProperties);
|
|
106
104
|
}
|
|
107
105
|
close() {
|
|
108
106
|
if (!this._isClosed) {
|