@things-factory/aws-base 5.0.0-alpha.16
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/CHANGELOG.md +8 -0
- package/README.md +19 -0
- package/config/config.development.js +12 -0
- package/config/config.production.js +12 -0
- package/dist-server/controllers/athena-controller.js +81 -0
- package/dist-server/controllers/athena-controller.js.map +1 -0
- package/dist-server/controllers/index.js +18 -0
- package/dist-server/controllers/index.js.map +1 -0
- package/dist-server/index.js +22 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/middlewares/index.js +8 -0
- package/dist-server/middlewares/index.js.map +1 -0
- package/dist-server/migrations/index.js +12 -0
- package/dist-server/migrations/index.js.map +1 -0
- package/dist-server/routes.js +25 -0
- package/dist-server/routes.js.map +1 -0
- package/dist-server/service/athena/athena-query.js +39 -0
- package/dist-server/service/athena/athena-query.js.map +1 -0
- package/dist-server/service/athena/index.js +7 -0
- package/dist-server/service/athena/index.js.map +1 -0
- package/dist-server/service/index.js +15 -0
- package/dist-server/service/index.js.map +1 -0
- package/package.json +30 -0
- package/server/controllers/athena-controller.ts +91 -0
- package/server/controllers/index.ts +2 -0
- package/server/index.ts +6 -0
- package/server/middlewares/index.ts +3 -0
- package/server/migrations/index.ts +9 -0
- package/server/routes.ts +28 -0
- package/server/service/athena/athena-query.ts +23 -0
- package/server/service/athena/index.ts +4 -0
- package/server/service/index.ts +14 -0
- package/things-factory.config.js +1 -0
- package/translations/en.json +1 -0
- package/translations/ko.json +1 -0
- package/translations/ms.json +1 -0
- package/translations/zh.json +1 -0
- package/tsconfig.json +9 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
|
+
and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
<!-- ## [Unreleased] -->
|
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
# AWS Base
|
|
3
|
+
|
|
4
|
+
## Athena
|
|
5
|
+
### Graphql Query Sample
|
|
6
|
+
```
|
|
7
|
+
# query
|
|
8
|
+
query ($queryData: Object!){
|
|
9
|
+
queryFromAthena(queryData: $queryData)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
# query variables
|
|
13
|
+
{ "queryData":
|
|
14
|
+
{
|
|
15
|
+
"sql": "SELECT * FROM operatochef_dev_iot LIMIT 10;",
|
|
16
|
+
"db": "operatochef_dev_iot"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AthenaController = void 0;
|
|
7
|
+
const athena_express_1 = require("athena-express");
|
|
8
|
+
const aws_sdk_1 = __importDefault(require("aws-sdk"));
|
|
9
|
+
const env_1 = require("@things-factory/env");
|
|
10
|
+
// athenaconfig sample
|
|
11
|
+
/*
|
|
12
|
+
athena: {
|
|
13
|
+
accessKeyId: 'YOUR ACCESS KEY ID',
|
|
14
|
+
secretAccessKey: 'YOUR SECRET ACCESS KEY',
|
|
15
|
+
region: 'YOUR S3 REGION'
|
|
16
|
+
options: { athenaExpressConfig
|
|
17
|
+
retry: 200,
|
|
18
|
+
getStats: true,
|
|
19
|
+
formatJson: true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
*/
|
|
23
|
+
// refer to https://github.com/ghdna/athena-express#advance-config-parameters
|
|
24
|
+
// about more detail configuration parameters
|
|
25
|
+
const athenaConfig = env_1.config.get('athena', {});
|
|
26
|
+
const awsCredentials = {
|
|
27
|
+
region: athenaConfig.region,
|
|
28
|
+
accessKeyId: athenaConfig.secretKeyId,
|
|
29
|
+
secretAccessKey: athenaConfig.secretAccessKey
|
|
30
|
+
};
|
|
31
|
+
aws_sdk_1.default.config.update(awsCredentials);
|
|
32
|
+
class AthenaController {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.queryPaginationInfo = {
|
|
35
|
+
NextToken: '',
|
|
36
|
+
QueryExecutionId: ''
|
|
37
|
+
};
|
|
38
|
+
// refer to https://github.com/ghdna/athena-express#advance-config-parameters
|
|
39
|
+
// about more detail configuration parameters
|
|
40
|
+
let athenaExpressConfig = Object.assign({ aws: aws_sdk_1.default }, athenaConfig.options);
|
|
41
|
+
this.athenaExpressClient = new athena_express_1.AthenaExpress(athenaExpressConfig);
|
|
42
|
+
}
|
|
43
|
+
// query parameters: https://github.com/ghdna/athena-express#advance-query-parameters
|
|
44
|
+
/* SAMPLE QUERY PARAMTERS
|
|
45
|
+
{
|
|
46
|
+
sql: "SELECT * FROM elb_logs LIMIT 3" // required,
|
|
47
|
+
db: "sampledb", // optional.
|
|
48
|
+
pagination: 5, //optional
|
|
49
|
+
NextToken: "ARfCDXRjMk...", //optional
|
|
50
|
+
QueryExecutionId: "c274843b-4c5c-4ccf-ac8b-e33d595b927d", //optional
|
|
51
|
+
catalog: "hive" //optional
|
|
52
|
+
}; */
|
|
53
|
+
// pagination: https://github.com/ghdna/athena-express#pagination
|
|
54
|
+
async query(reqQuery) {
|
|
55
|
+
var queryResult;
|
|
56
|
+
try {
|
|
57
|
+
// check if sql key is available in the input parameter
|
|
58
|
+
if (reqQuery.sql === undefined || reqQuery.sql === '')
|
|
59
|
+
return {};
|
|
60
|
+
let queryInput = Object.assign({}, reqQuery);
|
|
61
|
+
// check if pagination would be available.
|
|
62
|
+
if (reqQuery.pagination > 0 &&
|
|
63
|
+
this.queryPaginationInfo.NextToken !== '' &&
|
|
64
|
+
this.queryPaginationInfo.QueryExecutionId !== '') {
|
|
65
|
+
queryInput.NextToken = this.queryPaginationInfo.NextToken;
|
|
66
|
+
queryInput.QueryExecutionId = this.queryPaginationInfo.QueryExecutionId;
|
|
67
|
+
}
|
|
68
|
+
// run the query
|
|
69
|
+
queryResult = await this.athenaExpressClient.query(queryInput);
|
|
70
|
+
// keep pagination parameters if they are available in the result
|
|
71
|
+
this.queryPaginationInfo.NextToken = (queryResult === null || queryResult === void 0 ? void 0 : queryResult.NextToken) || '';
|
|
72
|
+
this.queryPaginationInfo.QueryExecutionId = (queryResult === null || queryResult === void 0 ? void 0 : queryResult.QueryExecutionId) || '';
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error(error);
|
|
76
|
+
}
|
|
77
|
+
return queryResult;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.AthenaController = AthenaController;
|
|
81
|
+
//# sourceMappingURL=athena-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"athena-controller.js","sourceRoot":"","sources":["../../server/controllers/athena-controller.ts"],"names":[],"mappings":";;;;;;AAAA,mDAA8C;AAC9C,sDAAyB;AAEzB,6CAA4C;AAE5C,sBAAsB;AACtB;;;;;;;;;;;EAWE;AACF,6EAA6E;AAC7E,6CAA6C;AAC7C,MAAM,YAAY,GAAG,YAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;AAC7C,MAAM,cAAc,GAAG;IACrB,MAAM,EAAE,YAAY,CAAC,MAAM;IAC3B,WAAW,EAAE,YAAY,CAAC,WAAW;IACrC,eAAe,EAAE,YAAY,CAAC,eAAe;CAC9C,CAAA;AACD,iBAAG,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;AAEjC,MAAa,gBAAgB;IAO3B;QALQ,wBAAmB,GAAG;YAC5B,SAAS,EAAE,EAAE;YACb,gBAAgB,EAAE,EAAE;SACrB,CAAA;QAGC,6EAA6E;QAC7E,6CAA6C;QAC7C,IAAI,mBAAmB,mBACrB,GAAG,EAAE,iBAAG,IACL,YAAY,CAAC,OAAO,CACxB,CAAA;QAED,IAAI,CAAC,mBAAmB,GAAG,IAAI,8BAAa,CAAC,mBAAmB,CAAC,CAAA;IACnE,CAAC;IAED,qFAAqF;IACrF;;;;;;;;YAQQ;IAER,iEAAiE;IACjE,KAAK,CAAC,KAAK,CAAC,QAAQ;QAClB,IAAI,WAAW,CAAA;QACf,IAAI;YACF,uDAAuD;YACvD,IAAI,QAAQ,CAAC,GAAG,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,KAAK,EAAE;gBAAE,OAAO,EAAE,CAAA;YAEhE,IAAI,UAAU,qBACT,QAAQ,CACZ,CAAA;YAED,0CAA0C;YAC1C,IACE,QAAQ,CAAC,UAAU,GAAG,CAAC;gBACvB,IAAI,CAAC,mBAAmB,CAAC,SAAS,KAAK,EAAE;gBACzC,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,KAAK,EAAE,EAChD;gBACA,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAA;gBACzD,UAAU,CAAC,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAA;aACxE;YAED,gBAAgB;YAChB,WAAW,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YAE9D,iEAAiE;YACjE,IAAI,CAAC,mBAAmB,CAAC,SAAS,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,SAAS,KAAI,EAAE,CAAA;YACjE,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,GAAG,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,KAAI,EAAE,CAAA;SAChF;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;SACrB;QAED,OAAO,WAAW,CAAA;IACpB,CAAC;CACF;AA9DD,4CA8DC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./athena-controller"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,sDAAmC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./controllers"), exports);
|
|
18
|
+
__exportStar(require("./migrations"), exports);
|
|
19
|
+
__exportStar(require("./middlewares"), exports);
|
|
20
|
+
__exportStar(require("./service"), exports);
|
|
21
|
+
require("./routes");
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA6B;AAC7B,+CAA4B;AAC5B,gDAA6B;AAC7B,4CAAyB;AAEzB,oBAAiB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initMiddlewares = void 0;
|
|
4
|
+
function initMiddlewares(app) {
|
|
5
|
+
/* can add middlewares into app */
|
|
6
|
+
}
|
|
7
|
+
exports.initMiddlewares = initMiddlewares;
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/middlewares/index.ts"],"names":[],"mappings":";;;AAAA,SAAgB,eAAe,CAAC,GAAG;IACjC,kCAAkC;AACpC,CAAC;AAFD,0CAEC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrations = void 0;
|
|
4
|
+
const glob = require('glob');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
exports.migrations = [];
|
|
7
|
+
glob.sync(path.resolve(__dirname, '.', '**', '*.js')).forEach(function (file) {
|
|
8
|
+
if (file.indexOf('index.js') !== -1)
|
|
9
|
+
return;
|
|
10
|
+
exports.migrations = exports.migrations.concat(Object.values(require(path.resolve(file))) || []);
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/migrations/index.ts"],"names":[],"mappings":";;;AAAA,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAEjB,QAAA,UAAU,GAAG,EAAE,CAAA;AAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,UAAS,IAAI;IACzE,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAAE,OAAM;IAC3C,kBAAU,GAAG,kBAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;AAClF,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const debug = require('debug')('things-factory:aws-base:routes');
|
|
2
|
+
process.on('bootstrap-module-global-public-route', (app, globalPublicRouter) => {
|
|
3
|
+
/*
|
|
4
|
+
* can add global public routes to application (auth not required, tenancy not required)
|
|
5
|
+
*
|
|
6
|
+
* ex) routes.get('/path', async(context, next) => {})
|
|
7
|
+
* ex) routes.post('/path', async(context, next) => {})
|
|
8
|
+
*/
|
|
9
|
+
});
|
|
10
|
+
process.on('bootstrap-module-global-private-route', (app, globalPrivateRouter) => {
|
|
11
|
+
/*
|
|
12
|
+
* can add global private routes to application (auth required, tenancy not required)
|
|
13
|
+
*/
|
|
14
|
+
});
|
|
15
|
+
process.on('bootstrap-module-domain-public-route', (app, domainPublicRouter) => {
|
|
16
|
+
/*
|
|
17
|
+
* can add domain public routes to application (auth not required, tenancy required)
|
|
18
|
+
*/
|
|
19
|
+
});
|
|
20
|
+
process.on('bootstrap-module-domain-private-route', (app, domainPrivateRouter) => {
|
|
21
|
+
/*
|
|
22
|
+
* can add domain private routes to application (auth required, tenancy required)
|
|
23
|
+
*/
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../server/routes.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,gCAAgC,CAAC,CAAA;AAEhE,OAAO,CAAC,EAAE,CAAC,sCAA6C,EAAE,CAAC,GAAG,EAAE,kBAAkB,EAAE,EAAE;IACpF;;;;;OAKG;AACL,CAAC,CAAC,CAAA;AAEF,OAAO,CAAC,EAAE,CAAC,uCAA8C,EAAE,CAAC,GAAG,EAAE,mBAAmB,EAAE,EAAE;IACtF;;OAEG;AACL,CAAC,CAAC,CAAA;AAEF,OAAO,CAAC,EAAE,CAAC,sCAA6C,EAAE,CAAC,GAAG,EAAE,kBAAkB,EAAE,EAAE;IACpF;;OAEG;AACL,CAAC,CAAC,CAAA;AAEF,OAAO,CAAC,EAAE,CAAC,uCAA8C,EAAE,CAAC,GAAG,EAAE,mBAAmB,EAAE,EAAE;IACtF;;OAEG;AACL,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var _a;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AthenaQuery = void 0;
|
|
17
|
+
const type_graphql_1 = require("type-graphql");
|
|
18
|
+
const shell_1 = require("@things-factory/shell");
|
|
19
|
+
const controllers_1 = require("../../controllers");
|
|
20
|
+
const debug = require('debug')('things-factory:reference-app');
|
|
21
|
+
const athenaClient = new controllers_1.AthenaController();
|
|
22
|
+
class AthenaQuery {
|
|
23
|
+
async queryFromAthena(_, queryData, context) {
|
|
24
|
+
const { domain } = context.state;
|
|
25
|
+
var queryResult = await athenaClient.query(queryData);
|
|
26
|
+
return queryResult;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, type_graphql_1.Query)(returns => shell_1.ScalarAny, { description: 'To query data in S3 using Amazon Athena SDK' }),
|
|
31
|
+
__param(0, (0, type_graphql_1.Root)()),
|
|
32
|
+
__param(1, (0, type_graphql_1.Arg)('queryData', type => shell_1.ScalarObject)),
|
|
33
|
+
__param(2, (0, type_graphql_1.Ctx)()),
|
|
34
|
+
__metadata("design:type", Function),
|
|
35
|
+
__metadata("design:paramtypes", [Object, typeof (_a = typeof shell_1.ScalarObject !== "undefined" && shell_1.ScalarObject) === "function" ? _a : Object, Object]),
|
|
36
|
+
__metadata("design:returntype", Promise)
|
|
37
|
+
], AthenaQuery.prototype, "queryFromAthena", null);
|
|
38
|
+
exports.AthenaQuery = AthenaQuery;
|
|
39
|
+
//# sourceMappingURL=athena-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"athena-query.js","sourceRoot":"","sources":["../../../server/service/athena/athena-query.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA8F;AAE9F,iDAAgF;AAEhF,mDAAoD;AAEpD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,8BAA8B,CAAC,CAAA;AAC9D,MAAM,YAAY,GAAG,IAAI,8BAAgB,EAAE,CAAA;AAE3C,MAAa,WAAW;IAEtB,KAAK,CAAC,eAAe,CACX,CAAC,EAC+B,SAAuB,EACxD,OAAY;QAEnB,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEhC,IAAI,WAAW,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAErD,OAAO,WAAW,CAAA;IACpB,CAAC;CACF;AAXC;IADC,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,iBAAS,EAAE,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IAEzF,WAAA,IAAA,mBAAI,GAAE,CAAA;IACN,WAAA,IAAA,kBAAG,EAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,oBAAY,CAAC,CAAA;IACtC,WAAA,IAAA,kBAAG,GAAE,CAAA;;iEAD6C,oBAAY,oBAAZ,oBAAY;;kDAQhE;AAZH,kCAaC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolvers = exports.entities = void 0;
|
|
4
|
+
const athena_query_1 = require("./athena-query");
|
|
5
|
+
exports.entities = [];
|
|
6
|
+
exports.resolvers = [athena_query_1.AthenaQuery];
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/athena/index.ts"],"names":[],"mappings":";;;AAAA,iDAA4C;AAE/B,QAAA,QAAQ,GAAG,EAAE,CAAA;AACb,QAAA,SAAS,GAAG,CAAC,0BAAW,CAAC,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schema = exports.entities = void 0;
|
|
4
|
+
/* IMPORT ENTITIES AND RESOLVERS */
|
|
5
|
+
const athena_1 = require("./athena");
|
|
6
|
+
exports.entities = [
|
|
7
|
+
/* ENTITIES */
|
|
8
|
+
];
|
|
9
|
+
exports.schema = {
|
|
10
|
+
resolverClasses: [
|
|
11
|
+
/* RESOLVER CLASSES */
|
|
12
|
+
...athena_1.resolvers,
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;AAAA,mCAAmC;AACnC,qCAAuD;AAE1C,QAAA,QAAQ,GAAG;AACtB,cAAc;CACf,CAAA;AAGY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,sBAAsB;QACxB,GAAG,kBAAe;KACjB;CACF,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@things-factory/aws-base",
|
|
3
|
+
"version": "5.0.0-alpha.16",
|
|
4
|
+
"main": "dist-server/index.js",
|
|
5
|
+
"things-factory": true,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "heartyoh",
|
|
8
|
+
"description": "aws service utils",
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public",
|
|
11
|
+
"@things-factory:registry": "https://registry.npmjs.org"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/hatiolab/things-factory.git",
|
|
16
|
+
"directory": "packages/aws-base"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc --p tsconfig.json",
|
|
20
|
+
"build:server": "npm run clean:server && tsc",
|
|
21
|
+
"clean:server": "rm -rf dist-server",
|
|
22
|
+
"clean": "npm run clean:server",
|
|
23
|
+
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@things-factory/shell": "^5.0.0-alpha.12",
|
|
27
|
+
"athena-express": "^7.1.4",
|
|
28
|
+
"aws-sdk": "^2.1096.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { AthenaExpress } from 'athena-express'
|
|
2
|
+
import AWS from 'aws-sdk'
|
|
3
|
+
|
|
4
|
+
import { config } from '@things-factory/env'
|
|
5
|
+
|
|
6
|
+
// athenaconfig sample
|
|
7
|
+
/*
|
|
8
|
+
athena: {
|
|
9
|
+
accessKeyId: 'YOUR ACCESS KEY ID',
|
|
10
|
+
secretAccessKey: 'YOUR SECRET ACCESS KEY',
|
|
11
|
+
region: 'YOUR S3 REGION'
|
|
12
|
+
options: { athenaExpressConfig
|
|
13
|
+
retry: 200,
|
|
14
|
+
getStats: true,
|
|
15
|
+
formatJson: true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
*/
|
|
19
|
+
// refer to https://github.com/ghdna/athena-express#advance-config-parameters
|
|
20
|
+
// about more detail configuration parameters
|
|
21
|
+
const athenaConfig = config.get('athena', {})
|
|
22
|
+
const awsCredentials = {
|
|
23
|
+
region: athenaConfig.region,
|
|
24
|
+
accessKeyId: athenaConfig.secretKeyId,
|
|
25
|
+
secretAccessKey: athenaConfig.secretAccessKey
|
|
26
|
+
}
|
|
27
|
+
AWS.config.update(awsCredentials)
|
|
28
|
+
|
|
29
|
+
export class AthenaController {
|
|
30
|
+
private athenaExpressClient
|
|
31
|
+
private queryPaginationInfo = {
|
|
32
|
+
NextToken: '',
|
|
33
|
+
QueryExecutionId: ''
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
constructor() {
|
|
37
|
+
// refer to https://github.com/ghdna/athena-express#advance-config-parameters
|
|
38
|
+
// about more detail configuration parameters
|
|
39
|
+
let athenaExpressConfig = {
|
|
40
|
+
aws: AWS,
|
|
41
|
+
...athenaConfig.options
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.athenaExpressClient = new AthenaExpress(athenaExpressConfig)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// query parameters: https://github.com/ghdna/athena-express#advance-query-parameters
|
|
48
|
+
/* SAMPLE QUERY PARAMTERS
|
|
49
|
+
{
|
|
50
|
+
sql: "SELECT * FROM elb_logs LIMIT 3" // required,
|
|
51
|
+
db: "sampledb", // optional.
|
|
52
|
+
pagination: 5, //optional
|
|
53
|
+
NextToken: "ARfCDXRjMk...", //optional
|
|
54
|
+
QueryExecutionId: "c274843b-4c5c-4ccf-ac8b-e33d595b927d", //optional
|
|
55
|
+
catalog: "hive" //optional
|
|
56
|
+
}; */
|
|
57
|
+
|
|
58
|
+
// pagination: https://github.com/ghdna/athena-express#pagination
|
|
59
|
+
async query(reqQuery) {
|
|
60
|
+
var queryResult
|
|
61
|
+
try {
|
|
62
|
+
// check if sql key is available in the input parameter
|
|
63
|
+
if (reqQuery.sql === undefined || reqQuery.sql === '') return {}
|
|
64
|
+
|
|
65
|
+
let queryInput = {
|
|
66
|
+
...reqQuery
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// check if pagination would be available.
|
|
70
|
+
if (
|
|
71
|
+
reqQuery.pagination > 0 &&
|
|
72
|
+
this.queryPaginationInfo.NextToken !== '' &&
|
|
73
|
+
this.queryPaginationInfo.QueryExecutionId !== ''
|
|
74
|
+
) {
|
|
75
|
+
queryInput.NextToken = this.queryPaginationInfo.NextToken
|
|
76
|
+
queryInput.QueryExecutionId = this.queryPaginationInfo.QueryExecutionId
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// run the query
|
|
80
|
+
queryResult = await this.athenaExpressClient.query(queryInput)
|
|
81
|
+
|
|
82
|
+
// keep pagination parameters if they are available in the result
|
|
83
|
+
this.queryPaginationInfo.NextToken = queryResult?.NextToken || ''
|
|
84
|
+
this.queryPaginationInfo.QueryExecutionId = queryResult?.QueryExecutionId || ''
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(error)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return queryResult
|
|
90
|
+
}
|
|
91
|
+
}
|
package/server/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const glob = require('glob')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
export var migrations = []
|
|
5
|
+
|
|
6
|
+
glob.sync(path.resolve(__dirname, '.', '**', '*.js')).forEach(function(file) {
|
|
7
|
+
if (file.indexOf('index.js') !== -1) return
|
|
8
|
+
migrations = migrations.concat(Object.values(require(path.resolve(file))) || [])
|
|
9
|
+
})
|
package/server/routes.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const debug = require('debug')('things-factory:aws-base:routes')
|
|
2
|
+
|
|
3
|
+
process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRouter) => {
|
|
4
|
+
/*
|
|
5
|
+
* can add global public routes to application (auth not required, tenancy not required)
|
|
6
|
+
*
|
|
7
|
+
* ex) routes.get('/path', async(context, next) => {})
|
|
8
|
+
* ex) routes.post('/path', async(context, next) => {})
|
|
9
|
+
*/
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
process.on('bootstrap-module-global-private-route' as any, (app, globalPrivateRouter) => {
|
|
13
|
+
/*
|
|
14
|
+
* can add global private routes to application (auth required, tenancy not required)
|
|
15
|
+
*/
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
process.on('bootstrap-module-domain-public-route' as any, (app, domainPublicRouter) => {
|
|
19
|
+
/*
|
|
20
|
+
* can add domain public routes to application (auth not required, tenancy required)
|
|
21
|
+
*/
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
process.on('bootstrap-module-domain-private-route' as any, (app, domainPrivateRouter) => {
|
|
25
|
+
/*
|
|
26
|
+
* can add domain private routes to application (auth required, tenancy required)
|
|
27
|
+
*/
|
|
28
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
|
|
2
|
+
import { User } from '@things-factory/auth-base'
|
|
3
|
+
import { publishProgress, ScalarAny, ScalarObject } from '@things-factory/shell'
|
|
4
|
+
|
|
5
|
+
import { AthenaController } from '../../controllers'
|
|
6
|
+
|
|
7
|
+
const debug = require('debug')('things-factory:reference-app')
|
|
8
|
+
const athenaClient = new AthenaController()
|
|
9
|
+
|
|
10
|
+
export class AthenaQuery {
|
|
11
|
+
@Query(returns => ScalarAny, { description: 'To query data in S3 using Amazon Athena SDK' })
|
|
12
|
+
async queryFromAthena(
|
|
13
|
+
@Root() _,
|
|
14
|
+
@Arg('queryData', type => ScalarObject) queryData: ScalarObject,
|
|
15
|
+
@Ctx() context: any
|
|
16
|
+
): Promise<ScalarAny> {
|
|
17
|
+
const { domain } = context.state
|
|
18
|
+
|
|
19
|
+
var queryResult = await athenaClient.query(queryData)
|
|
20
|
+
|
|
21
|
+
return queryResult
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* IMPORT ENTITIES AND RESOLVERS */
|
|
2
|
+
import { resolvers as AthenaResolvers } from './athena'
|
|
3
|
+
|
|
4
|
+
export const entities = [
|
|
5
|
+
/* ENTITIES */
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export const schema = {
|
|
10
|
+
resolverClasses: [
|
|
11
|
+
/* RESOLVER CLASSES */
|
|
12
|
+
...AthenaResolvers,
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|