Skip to content

Commit dc3dbef

Browse files
Added maester-implementation for getAttachment, maxContentLength fix (#46)
* Fixed bug with misspelling maxContentLength and maxBodyLenth of request config * added maester implementation for getAttachment
1 parent afdcde7 commit dc3dbef

File tree

6 files changed

+1333
-147
lines changed

6 files changed

+1333
-147
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 1.1.6 (July 29, 2021)
2+
* Now `getAttachment` from `AttachmentProcessor` may retrieve items from `Maester`
3+
14
## 1.1.5 (October 29, 2020)
25
* Allow the response handler to be overridden at a per request level.
36
* Bump dependencies.

README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# Description
1919
This library provides some of the most common component development functionality in a simple, reusable way.
2020

21-
To install, type
21+
To install, type
2222

2323
```
2424
npm install @elastic.io/component-commons-library
@@ -32,7 +32,7 @@ A number of REST Client classes are available to use and extend to create Client
3232
Each of the REST Clients extends from the `NoAuthRestClient`, overriding the relevant methods.
3333

3434
### NoAuthRestClient
35-
[NoAuthRestClient](https://github.com/elasticio/component-commons-library/blob/master/lib/authentication/NoAuthRestClient.ts) class to make rest requests no no auth APIs by provided options.
35+
[NoAuthRestClient](https://github.com/elasticio/component-commons-library/blob/master/lib/authentication/NoAuthRestClient.ts) class to make rest requests no no auth APIs by provided options.
3636

3737
#### constructor(emitter, cfg)
3838
- emitter - EIO emitting context.
@@ -123,12 +123,12 @@ This class can handle, refresh and emit oauth2 EIO configuration.
123123
### NtlmRestClient
124124
[NtlmRestClient](https://github.com/elasticio/component-commons-library/blob/master/lib/authentication/NtlmRestClient.ts)
125125
class extends [NoAuthRestClient](#NoAuthRestClient) class.
126-
Makes requests to resource with [NTLM authentication](https://en.wikipedia.org/wiki/NT_LAN_Manager).
127-
Falls back to basic authentication if NTLM authentication fails.
126+
Makes requests to resource with [NTLM authentication](https://en.wikipedia.org/wiki/NT_LAN_Manager).
127+
Falls back to basic authentication if NTLM authentication fails.
128128
Handles both V1 and V2 of the NTLM Protocol.
129129

130130
#### constructor(emitter, cfg)
131-
- cfg.username - mandatory cfg parameter contains username for authorization. Domain information should be combined with this field. (e.g. `SOMEDOMAIN\SomeUser`)
131+
- cfg.username - mandatory cfg parameter contains username for authorization. Domain information should be combined with this field. (e.g. `SOMEDOMAIN\SomeUser`)
132132
- cfg.password - mandatory cfg parameter contains password for authorization.
133133

134134
```
@@ -150,7 +150,9 @@ Contains functions to transform platform data that contains JSONata expressions
150150
The attachment processor function can be used to store attachments on the platform. It exposes the following functions
151151

152152
- `uploadAttachment(streamContent)`, which will upload an attachment to the platform and return the result and file url
153-
- `getAttachment(url, contentType)`, which will retrieve an attachment from the platform
153+
- `getAttachment(url, contentType)`, which will retrieve an attachment from `steward` or `maester` storage. To specify the storage - query parameter
154+
`storage_type` must be provided. To get items from `maester` storage - `?storage_type=maester` should added to the `url` argument. By default attachments are retrieved from `steward` storage, so `?storage_type=steward` is not obligated to be added to the `url` argument. `contentType` -
155+
one of [`stream`, `arraybuffer` ]
154156

155157
Example:
156158

@@ -162,6 +164,13 @@ const result = await new AttachmentProcessor().uploadAttachment(stream);
162164

163165
const storedFileUrl = result.config.url;
164166
```
167+
```javascript
168+
const { AttachmentProcessor } = require('@elastic.io/component-commons-library');
169+
170+
const result = await new AttachmentProcessor().getAttachment('http://example.com', 'stream'); // steward storage
171+
const result = await new AttachmentProcessor().getAttachment('http://example.com?storage_type=steward', 'arraybuffer'); // steward storage
172+
const result = await new AttachmentProcessor().getAttachment('http://example.com?storage_type=maester', 'stream'); // maester storage
173+
```
165174

166175
## Logger
167176
The built in logger uses Bunyan Logger as its base implementation. The available logger methods can be found [here](https://github.com/elasticio/component-commons-library/blob/master/lib/logger/logger.ts#L19).

lib/attachment/AttachmentProcessor.ts

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import axios, { AxiosRequestConfig } from 'axios';
2+
import { URL } from 'url';
3+
import { StorageClient, ObjectStorage } from '@elastic.io/maester-client/dist';
24
const restNodeClient = require('elasticio-rest-node')();
35

6+
export const STORAGE_TYPE_PARAMETER = 'storage_type';
7+
export const DEFAULT_STORAGE_TYPE = 'steward';
8+
export const MAESTER_OBJECT_ID_ENDPOINT = '/objects/';
9+
const { ELASTICIO_OBJECT_STORAGE_TOKEN = '' , ELASTICIO_OBJECT_STORAGE_URI = '' } = process.env;
10+
const maesterCreds = { jwtSecret: ELASTICIO_OBJECT_STORAGE_TOKEN, uri: ELASTICIO_OBJECT_STORAGE_URI };
411
const REQUEST_TIMEOUT = process.env.REQUEST_TIMEOUT ? parseInt(process.env.REQUEST_TIMEOUT, 10) : 10000; // 10s
512
const REQUEST_MAX_RETRY = process.env.REQUEST_MAX_RETRY ? parseInt(process.env.REQUEST_MAX_RETRY, 10) : 7; // 10s
613
const REQUEST_RETRY_DELAY = process.env.REQUEST_RETRY_DELAY ? parseInt(process.env.REQUEST_RETRY_DELAY, 10) : 7000; // 7s
7-
const REQUEST_MAX_CONTENT_LENGTH = process.env.REQUEST_MAX_CONTENT_LENGTH ? parseInt(process.env.REQUEST_MAX_CONTENT_LENGTH, 10) : 10485760; // 10MB
14+
const REQUEST_MAX_BODY_LENGTH = process.env.REQUEST_MAX_BODY_LENGTH ? parseInt(process.env.REQUEST_MAX_BODY_LENGTH, 10) : 10485760; // 10MB
815

916
export class AttachmentProcessor {
1017

1118
async getAttachment(url: string, responseType: string) {
12-
const ax = axios.create();
13-
AttachmentProcessor.addRetryCountInterceptorToAxios(ax);
14-
19+
const storageType = AttachmentProcessor.getStorageTypeByUrl(url);
1520
const axConfig = {
1621
url,
1722
responseType,
@@ -21,7 +26,11 @@ export class AttachmentProcessor {
2126
delay: REQUEST_RETRY_DELAY,
2227
} as AxiosRequestConfig;
2328

24-
return ax(axConfig);
29+
switch (storageType) {
30+
case 'steward': return AttachmentProcessor.getStewardAttachment(axConfig);
31+
case 'maester': return AttachmentProcessor.getMaesterAttachment(axConfig);
32+
default: throw new Error(`Storage type "${storageType}" is not supported`);
33+
}
2534
}
2635

2736
async uploadAttachment(body) {
@@ -36,7 +45,7 @@ export class AttachmentProcessor {
3645
timeout: REQUEST_TIMEOUT,
3746
retry: REQUEST_MAX_RETRY,
3847
delay: REQUEST_RETRY_DELAY,
39-
maxContentLength: REQUEST_MAX_CONTENT_LENGTH,
48+
maxBodyLength: REQUEST_MAX_BODY_LENGTH,
4049
} as AxiosRequestConfig;
4150

4251
return ax(axConfig);
@@ -47,6 +56,35 @@ export class AttachmentProcessor {
4756
return signedUrl.put_url;
4857
}
4958

59+
static async getStewardAttachment(axConfig) {
60+
const ax = axios.create();
61+
AttachmentProcessor.addRetryCountInterceptorToAxios(ax);
62+
return ax(axConfig);
63+
}
64+
65+
static async getMaesterAttachment(axConfig) {
66+
const client = new StorageClient(maesterCreds);
67+
const objectStorage = new ObjectStorage(maesterCreds, client);
68+
const maesterAttachmentId = AttachmentProcessor.getMaesterAttachmentIdByUrl(axConfig.url);
69+
const response = await objectStorage.getById(maesterAttachmentId, axConfig.responseType);
70+
return { data: response };
71+
}
72+
73+
static getStorageTypeByUrl(urlString) {
74+
const url = new URL(urlString);
75+
const storageType = url.searchParams.get(STORAGE_TYPE_PARAMETER);
76+
return storageType || DEFAULT_STORAGE_TYPE;
77+
}
78+
79+
static getMaesterAttachmentIdByUrl(urlString): string {
80+
const { pathname } = new URL(urlString);
81+
const maesterAttachmentId = pathname.split(MAESTER_OBJECT_ID_ENDPOINT)[1];
82+
if (!maesterAttachmentId) {
83+
throw new Error('Invalid Maester Endpoint');
84+
}
85+
return maesterAttachmentId;
86+
}
87+
5088
static addRetryCountInterceptorToAxios(ax) {
5189
ax.interceptors.response.use(undefined, (err) => { // Retry count interceptor for axios
5290
const { config } = err;

0 commit comments

Comments
 (0)