Skip to content

Commit a0b59f1

Browse files
authored
chore: 3.9.0-2 alpha release (#196)
* chore: assets command * feat: mc download-events command * feat: analyze events * chore: alpha-release: 3.9.0-2 🎉 * chore: fixed lgtm * chore: lgtm ignores
1 parent a03e180 commit a0b59f1

13 files changed

+554
-218
lines changed

CHANGELOG.md

+21-5
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,35 @@
22

33
## 3.9.0 - (Pewter Vienna) - October 2020
44

5-
- SDK: event analytics api (#162)
6-
- SDK: EventManagement: sharedEvents support included in GetEvents operation (#170)
5+
- CLI: mc aspects command (list, create, delete)
6+
- CLI: mc asset-types command (list, create, delete)
7+
- CLI: mc assets command (list, create, delete)
8+
- CLI: mc download-events command
9+
- CLI: mc aspects command (list, create, delete)
710
- CLI: mc configure-agent --mode test can now produce a configurable number of test records
811
- CLI will now notify users that there is a new version of the CLI available (#190) [#hacktoberfest lyallemma]
12+
- SDK: event analytics api (#162)
13+
- SDK: EventManagement: sharedEvents support included in GetEvents operation (#170)
914
- provided binary versions of the command line interface for windows, macos and linux (#185) [#hacktoberfest issue-03]
10-
- improved the build script to run in powershell as well (#184) [#hacktoberfest coding4funrocks]
11-
- fixed the example in `mc iam` command (#182) [#hacktoberfest, coding4funrocks]
15+
- CLI: mc aspects command -- mode convert added support for multiple targets in schema (#193) [#hacktopberfest phbender]
1216
- bumped all dependencies
1317

18+
## Bugfix 3.9.0
19+
20+
- fixed the example in `mc iam` command (#182) [#hacktoberfest, coding4funrocks]
21+
- improved the build script to run in powershell as well (#184) [#hacktoberfest coding4funrocks]
22+
- added the digital twin type to mc assets --mode create command (#195) [#hacktoberfest RhnSaxena]
23+
1424
### Contributions 3.9.0
1525

1626
- The mindconnect-nodejs participated in #hacktoberfest2020
17-
- Thanks to coding4funrocks, issue-03 and lyallemma for their #hacktoberfest contributions. <3 :heart:
27+
- Thanks to :
28+
- coding4funrocks
29+
- issue-03
30+
- lyallemma
31+
- RhnSaxena
32+
- PhBender
33+
for their #hacktoberfest contributions. <3 :heart:
1834

1935
## 3.8.3 - (Electric Blue Vienna) - August 2020
2036

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mindconnect/mindconnect-nodejs",
3-
"version": "3.9.0-1",
3+
"version": "3.9.0-2",
44
"description": "MindConnect Library for NodeJS (community based)",
55
"main": "./dist/src/index.js",
66
"browser": "./dist/src/index.bundle.js",

src/cli/commands/analyze-events.ts

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import { CommanderStatic } from "commander";
2+
import { log } from "console";
3+
import * as fs from "fs";
4+
import { isArray } from "lodash";
5+
import * as path from "path";
6+
import { EventAnalyticsClient } from "../../api/sdk";
7+
import { retry } from "../../api/utils";
8+
import { errorLog, getColor, getSdk, homeDirLog, proxyLog, serviceCredentialLog, verboseLog } from "./command-utils";
9+
10+
const color = getColor("blue");
11+
12+
export default (program: CommanderStatic) => {
13+
program
14+
.command("event-analytics")
15+
.alias("ea")
16+
.option("-m, --mode [count|filter|duplicate|top]", `mode see ${color("@ Additional Documentation")}`, "top")
17+
.option("-f, --file <file>", `events file`)
18+
.option("-o, --output <output>", `result ${color("mode")}.ea.mdsp.json`)
19+
.option(
20+
"-t, --type [timeseries|event]",
21+
`event analytics can be used on both timeseries (with string properties as event names) and event formats`,
22+
"event"
23+
)
24+
.option("-p, --property <property>", `property name used for grouping and counting`, "description")
25+
.option("-l, --filterlist <filterlist>", `filter events`, "[]")
26+
.option("-x, --top <top>", "number of events (for top mode)", "10")
27+
.option("-s, --split <split>", "split interval (for count, duplicate)", "5000")
28+
.option("-y, --retry <number>", "retry attempts before giving up", "3")
29+
.option("-p, --passkey <passkey>", `passkey`)
30+
.option("-v, --verbose", "verbose output")
31+
.description(`${color("analyze mindsphere events @")}`)
32+
.action((options) => {
33+
(async () => {
34+
try {
35+
checkRequiredParameters(options);
36+
const sdk = getSdk(options);
37+
homeDirLog(options.verbose, color);
38+
proxyLog(options.verbose, color);
39+
const fileName = path.resolve(options.file);
40+
const data = fs.readFileSync(fileName).toString();
41+
const events = JSON.parse(data);
42+
43+
let newEvents: any[] = events;
44+
45+
if (options.type === "event") {
46+
newEvents = [];
47+
48+
events.events.forEach((element: any) => {
49+
const newObject: any = { _time: element.timestamp };
50+
newObject[options.property] = element[options.property];
51+
newEvents.push(newObject);
52+
});
53+
}
54+
const ea = sdk.GetEventAnalyticsClient();
55+
56+
const output = options.output || `${options.mode}.ea.mdsp.json`;
57+
58+
switch (options.mode) {
59+
case "top":
60+
await getTopEvents(ea, options, newEvents, output);
61+
break;
62+
63+
case "count":
64+
await countEvents(ea, options, newEvents, output);
65+
break;
66+
67+
case "duplicate":
68+
await removeDuplicates(ea, options, newEvents, output);
69+
break;
70+
71+
case "filter":
72+
await filterEvents(ea, options, newEvents, output);
73+
break;
74+
75+
default:
76+
throw Error(`no such option: ${options.mode}`);
77+
}
78+
} catch (err) {
79+
errorLog(err, options.verbose);
80+
}
81+
})();
82+
})
83+
.on("--help", () => {
84+
log("\n Examples:\n");
85+
log(
86+
` mc event-analytics --mode top --file events.json --property description \t\t find the top 10 events in events.json`
87+
);
88+
log(
89+
` mc event-analytics --mode duplicate --file events.json --property description --split 5000 \t\t remove all duplicate events`
90+
);
91+
log("\n Additional Documentation:\n");
92+
log(
93+
` ${color(
94+
"https://developer.mindsphere.io/apis/analytics-eventanalytics/api-eventanalytics-overview.html"
95+
)}`
96+
);
97+
98+
log(
99+
` ${color(
100+
"https://developer.mindsphere.io/apis/analytics-eventanalytics/api-eventanalytics-samples.html"
101+
)}`
102+
);
103+
104+
serviceCredentialLog(color);
105+
});
106+
};
107+
108+
async function getTopEvents(ea: EventAnalyticsClient, options: any, newEvents: any[], output: any) {
109+
const result = await retry(options.retry, () =>
110+
ea.FindTopEvents({
111+
numberOfTopPositionsRequired: parseInt(options.top),
112+
eventsMetadata: { eventTextPropertyName: options.property },
113+
events: newEvents,
114+
})
115+
);
116+
fs.writeFileSync(output, JSON.stringify(result, null, 2));
117+
verboseLog(JSON.stringify(result, null, 2), options.verbose);
118+
console.log(`wrote results to ${color(output)}`);
119+
}
120+
121+
async function countEvents(ea: EventAnalyticsClient, options: any, newEvents: any[], output: any) {
122+
const result = await retry(options.retry, () =>
123+
ea.CountEvents({
124+
eventsMetadata: {
125+
eventTextPropertyName: options.property,
126+
splitInterval: parseInt(options.split),
127+
},
128+
events: newEvents,
129+
})
130+
);
131+
fs.writeFileSync(output, JSON.stringify(result, null, 2));
132+
verboseLog(JSON.stringify(result, null, 2), options.verbose);
133+
console.log(`wrote results to ${color(output)}`);
134+
}
135+
136+
async function removeDuplicates(ea: EventAnalyticsClient, options: any, newEvents: any[], output: any) {
137+
const result = await retry(options.retry, () =>
138+
ea.RemoveDuplicateEvents({
139+
eventsMetadata: {
140+
eventTextPropertyName: options.property,
141+
splitInterval: parseInt(options.split),
142+
},
143+
events: newEvents,
144+
})
145+
);
146+
fs.writeFileSync(output, JSON.stringify(result, null, 2));
147+
verboseLog(JSON.stringify(result, null, 2), options.verbose);
148+
console.log(`wrote results to ${color(output)}`);
149+
}
150+
151+
async function filterEvents(ea: EventAnalyticsClient, options: any, newEvents: any[], output: any) {
152+
const resultFilter = await retry(options.retry, () =>
153+
ea.FilterEvents({
154+
eventsMetadata: {
155+
eventTextPropertyName: options.property,
156+
},
157+
events: newEvents,
158+
filterList: options.filterlist ? JSON.parse(options.filterlist) : [],
159+
})
160+
);
161+
fs.writeFileSync(output, JSON.stringify(resultFilter, null, 2));
162+
verboseLog(JSON.stringify(resultFilter, null, 2), options.verbose);
163+
console.log(`wrote results to ${color(output)}`);
164+
}
165+
166+
function checkRequiredParameters(options: any) {
167+
!["timeseries", "event"].includes(options.type) &&
168+
errorLog(`invalid type ${options.type}; type must be timeseries or event`, true);
169+
170+
if (options.filterlist) {
171+
try {
172+
const obj = JSON.parse(options.filterlist);
173+
if (!isArray(obj)) {
174+
errorLog(
175+
"invalid filter, you have to pass an array with event names. example --filterlist '[\"Flow to low\"]' ",
176+
true
177+
);
178+
}
179+
} catch (error) {
180+
errorLog(
181+
"invalid filter, you have to pass an array with event names. example --filterlist '[\"Flow to low\"]' ",
182+
true
183+
);
184+
}
185+
}
186+
}

src/cli/commands/aspect-commands.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ function writeAspectTypeToFile(
242242
variables: any[];
243243
}
244244
) {
245-
const fileName = `${options.aspect}.aspect.mdsp.json`;
245+
const fileName = options.file || `${options.aspect}.aspect.mdsp.json`;
246246
fs.writeFileSync(fileName, JSON.stringify(aspectType, null, 2));
247247
console.log(
248248
`The data was written into ${color(

src/cli/commands/aspecttypes-commands.ts renamed to src/cli/commands/asset-types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function createTemplate(options: any) {
125125
}
126126

127127
function writeAssetTypeToFile(options: any, AssetType: any) {
128-
const fileName = `${options.assettype}.assettype.mdsp.json`;
128+
const fileName = options.file || `${options.assettype}.assettype.mdsp.json`;
129129
fs.writeFileSync(fileName, JSON.stringify(AssetType, null, 2));
130130
console.log(
131131
`The data was written into ${color(

0 commit comments

Comments
 (0)