Skip to content

Commit

Permalink
Custom Event Hub Endpoint (#312)
Browse files Browse the repository at this point in the history
* tmp

* Basic version

* Store/delete IoT Hub info

* Stop Monitoring Custom Event Hub Endpoint

* Refresh button; Built-in ednpoint; Other Custom Endpoint

* Add BI

* Add more BI

* Add BI for built-in-events

* Fix security vulnerability

* Not show welcome page when azure-iot-tools is installed

* Handle there is no iot hub
  • Loading branch information
formulahendry authored May 13, 2019
1 parent 5ede282 commit 285c0a7
Show file tree
Hide file tree
Showing 23 changed files with 687 additions and 952 deletions.
1,032 changes: 165 additions & 867 deletions package-lock.json

Large diffs are not rendered by default.

63 changes: 56 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,17 @@
"onCommand:azure-iot-toolkit.updateDistributedTracingSetting",
"onCommand:azure-iot-toolkit.deleteModule",
"onCommand:azure-iot-toolkit.getModule",
"onCommand:azure-iot-toolkit.copyModuleConnectionString"
"onCommand:azure-iot-toolkit.copyModuleConnectionString",
"onCommand:azure-iot-toolkit.startMonitorCustomEventHubEndpoint",
"onCommand:azure-iot-toolkit.stopMonitorCustomEventHubEndpoint"
],
"main": "./dist/extension",
"contributes": {
"views": {
"explorer": [
{
"id": "iotHubDevices",
"name": "Azure IoT Hub Devices"
"name": "Azure IoT Hub"
}
]
},
Expand All @@ -84,12 +86,17 @@
},
{
"command": "azure-iot-toolkit.startMonitorIoTHubMessage",
"title": "Start Monitoring D2C Message",
"title": "Start Monitoring Built-in Event Endpoint",
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.startMonitorIoTHubMessageWithAbbreviation",
"title": "Start Monitoring",
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.stopMonitorIoTHubMessage",
"title": "Stop Monitoring D2C Message",
"title": "Stop Monitoring Built-in Event Endpoint",
"category": "Azure IoT Hub"
},
{
Expand Down Expand Up @@ -260,6 +267,16 @@
"command": "azure-iot-toolkit.copyModuleConnectionString",
"title": "Copy Module Connection String",
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.startMonitorCustomEventHubEndpoint",
"title": "Start Monitoring",
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.stopMonitorCustomEventHubEndpoint",
"title": "Stop Monitoring Custom Event Hub Endpoint",
"category": "Azure IoT Hub"
}
],
"menus": {
Expand Down Expand Up @@ -326,6 +343,11 @@
}
],
"view/item/context": [
{
"command": "azure-iot-toolkit.refresh",
"when": "view == iotHubDevices && viewItem == devices-label",
"group": "inline"
},
{
"command": "azure-iot-toolkit.refresh",
"when": "view == iotHubDevices && viewItem == device",
Expand Down Expand Up @@ -535,6 +557,19 @@
"command": "azure-iot-toolkit.editDistributedTracingSamplingRate",
"when": "view == iotHubDevices && viewItem == desired-sampling-rate-property",
"group": "azure-iot-toolkit@7"
},
{
"command": "azure-iot-toolkit.refresh",
"when": "view == iotHubDevices && viewItem == endpoints-label",
"group": "inline"
},
{
"command": "azure-iot-toolkit.startMonitorCustomEventHubEndpoint",
"when": "view == iotHubDevices && viewItem == event-hub"
},
{
"command": "azure-iot-toolkit.startMonitorIoTHubMessageWithAbbreviation",
"when": "view == iotHubDevices && viewItem == events"
}
],
"editor/context": [
Expand All @@ -545,9 +580,14 @@
},
{
"when": "inOutput",
"command": "azure-iot-toolkit.stopMonitorC2DMessage",
"command": "azure-iot-toolkit.stopMonitorCustomEventHubEndpoint",
"group": "azure-iot-toolkit@2"
},
{
"when": "inOutput",
"command": "azure-iot-toolkit.stopMonitorC2DMessage",
"group": "azure-iot-toolkit@3"
},
{
"when": "resourceFilename == azure-iot-device-twin.json",
"command": "azure-iot-toolkit.updateDeviceTwin",
Expand Down Expand Up @@ -599,6 +639,14 @@
{
"command": "azure-iot-toolkit.copyModuleConnectionString",
"when": "never"
},
{
"command": "azure-iot-toolkit.startMonitorCustomEventHubEndpoint",
"when": "never"
},
{
"command": "azure-iot-toolkit.startMonitorIoTHubMessageWithAbbreviation",
"when": "never"
}
]
},
Expand All @@ -624,7 +672,7 @@
"azure-iot-toolkit.monitorD2CBeforeNowInMinutes": {
"type": "number",
"default": 0,
"description": "The time span (in minutes) of monitoring D2C message before current time."
"description": "The time span (in minutes) of monitoring built-in event endpoint before current time."
},
"azure-iot-toolkit.showVerboseMessage": {
"type": "boolean",
Expand Down Expand Up @@ -689,14 +737,15 @@
"ts-loader": "^5.3.1",
"tslint": "^4.5.1",
"typescript": "^3.0.0",
"vscode": "^1.1.29",
"vscode": "^1.1.34",
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2"
},
"dependencies": {
"@azure/event-hubs": "^2.0.0",
"ajv": "^6.10.0",
"axios": "^0.18.0",
"azure-arm-eventhub": "^3.2.0",
"azure-arm-iothub": "^2.0.1",
"azure-arm-resource": "^2.0.0-preview",
"azure-iot-common": "^1.8.1",
Expand Down
11 changes: 11 additions & 0 deletions src/Model/CustomEndpointItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { TreeItem } from "vscode";

export class CustomEndpointItem extends TreeItem {
constructor(name: string) {
super(name);
this.contextValue = "custom-endpoint";
}
}
15 changes: 15 additions & 0 deletions src/Model/EventHubItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { RoutingEventHubProperties } from "azure-arm-iothub/lib/models";
import { TreeItem } from "vscode";
import { AzureSubscription } from "../azure-account.api";

export class EventHubItem extends TreeItem {
constructor(
public readonly azureSubscription: AzureSubscription,
public readonly eventHubProperty: RoutingEventHubProperties) {
super(eventHubProperty.name);
this.contextValue = "event-hub";
}
}
45 changes: 45 additions & 0 deletions src/Nodes/DeviceLabelNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import * as vscode from "vscode";
import { Constants } from "../constants";
import { DeviceItem } from "../Model/DeviceItem";
import { TelemetryClient } from "../telemetryClient";
import { Utility } from "../utility";
import { DeviceNode } from "./DeviceNode";
import { InfoNode } from "./InfoNode";
import { INode } from "./INode";

export class DeviceLabelNode implements INode {
constructor(private iotHubConnectionString: string) {
}

public getTreeItem(): vscode.TreeItem {
return {
label: "Devices",
collapsibleState: vscode.TreeItemCollapsibleState.Expanded,
contextValue: "devices-label",
};
}

public async getChildren(): Promise<INode[]> {
TelemetryClient.sendEvent(Constants.IoTHubAIStartLoadDeviceTreeEvent);

try {
const deviceList: vscode.TreeItem[] = await Utility.getDeviceList(this.iotHubConnectionString, Constants.ExtensionContext);

let deviceNode: INode[] = deviceList.map((item) => new DeviceNode(item as DeviceItem));

if (deviceNode.length === 0) {
deviceNode.push(new InfoNode(`No devices in ${Utility.getHostName(this.iotHubConnectionString)}`));
}

TelemetryClient.sendEvent(Constants.IoTHubAILoadDeviceTreeEvent, { Result: "Success", DeviceCount: deviceList.length.toString() });

return deviceNode;
} catch (err) {
TelemetryClient.sendEvent(Constants.IoTHubAILoadDeviceTreeEvent, { Result: "Fail", Message: err.message });
return Utility.getErrorMessageTreeItems("IoT Hub devices", err.message);
}
}
}
21 changes: 21 additions & 0 deletions src/Nodes/Endpoints/BuiltInEndpointItemNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import * as vscode from "vscode";
import { INode } from "../INode";

export class BuiltInEndpointItemNode implements INode {
constructor() {
}

public getTreeItem(): vscode.TreeItem {
return {
label: "events",
contextValue: "events",
};
}

public getChildren(): INode[] {
return [];
}
}
23 changes: 23 additions & 0 deletions src/Nodes/Endpoints/BuiltInEndpointLabelNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import * as vscode from "vscode";
import { INode } from "../INode";
import { BuiltInEndpointItemNode } from "./BuiltInEndpointItemNode";

export class BuiltInEndpointLabelNode implements INode {
constructor() {
}

public getTreeItem(): vscode.TreeItem {
return {
label: "Built-in endpints",
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextValue: "built-in-endpoint-label",
};
}

public getChildren(): INode[] {
return [new BuiltInEndpointItemNode()];
}
}
19 changes: 19 additions & 0 deletions src/Nodes/Endpoints/CustomEndpointItemNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import * as vscode from "vscode";
import { CustomEndpointItem } from "../../Model/CustomEndpointItem";
import { INode } from "../INode";

export class CustomEndpointItemNode implements INode {
constructor(private name: string) {
}

public getTreeItem(): vscode.TreeItem {
return new CustomEndpointItem(this.name);
}

public getChildren(): INode[] {
return [];
}
}
23 changes: 23 additions & 0 deletions src/Nodes/Endpoints/CustomEndpointLabelNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import * as vscode from "vscode";
import { INode } from "../INode";
import { CustomEndpointItemNode } from "./CustomEndpointItemNode";

export class CustomEndpointLabelNode implements INode {
constructor(private label: string, private properties: any[]) {
}

public getTreeItem(): vscode.TreeItem {
return {
label: this.label,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextValue: "custom-endpoint-label",
};
}

public getChildren(): INode[] {
return this.properties.map((property) => new CustomEndpointItemNode(property.name));
}
}
62 changes: 62 additions & 0 deletions src/Nodes/Endpoints/EndpointsLabelNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import IotHubClient from "azure-arm-iothub";
import * as vscode from "vscode";
import { Constants } from "../../constants";
import { TelemetryClient } from "../../telemetryClient";
import { Utility } from "../../utility";
import { CommandNode } from "../CommandNode";
import { INode } from "../INode";
import { BuiltInEndpointLabelNode } from "./BuiltInEndpointLabelNode";
import { CustomEndpointLabelNode } from "./CustomEndpointLabelNode";
import { EventHubLabelNode } from "./EventHubLabelNode";

export class EndpointsLabelNode implements INode {
constructor() {
}

public getTreeItem(): vscode.TreeItem {
return {
label: "Endpoints",
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
contextValue: "endpoints-label",
};
}

public async getChildren(): Promise<INode[]> {
TelemetryClient.sendEvent(Constants.IoTHubAILoadEndpointsTreeStartEvent);

try {
const accountApi = Utility.getAzureAccountApi();
const subscriptionId = Constants.ExtensionContext.globalState.get(Constants.StateKeySubsID);
if (!subscriptionId || !(await accountApi.waitForLogin())) {
return [this.getSelectIoTHubCommandNode()];
}

const subscription = accountApi.subscriptions.find((element) => element.subscription.subscriptionId === subscriptionId);
const client = new IotHubClient(subscription.session.credentials, subscription.subscription.subscriptionId, subscription.session.environment.resourceManagerEndpointUrl);
const iotHubs = await client.iotHubResource.listBySubscription();
const iothub = iotHubs.find((element) =>
element.id === Constants.ExtensionContext.globalState.get(Constants.StateKeyIoTHubID));
TelemetryClient.sendEvent(Constants.IoTHubAILoadEndpointsTreeDoneEvent, { Result: "Success" });

if (!iothub) {
return [this.getSelectIoTHubCommandNode()];
}

return [new BuiltInEndpointLabelNode(),
new EventHubLabelNode(subscription, iothub.properties.routing.endpoints.eventHubs),
new CustomEndpointLabelNode("Service Bus queue", iothub.properties.routing.endpoints.serviceBusQueues),
new CustomEndpointLabelNode("Service Bus topic", iothub.properties.routing.endpoints.serviceBusTopics),
new CustomEndpointLabelNode("Blob storage", iothub.properties.routing.endpoints.storageContainers)];
} catch (err) {
TelemetryClient.sendEvent(Constants.IoTHubAILoadEndpointsTreeDoneEvent, { Result: "Fail", Message: err.message });
return Utility.getErrorMessageTreeItems("endpoints", err.message);
}
}

private getSelectIoTHubCommandNode(): CommandNode {
return new CommandNode("-> Please select an IoT Hub", "azure-iot-toolkit.selectIoTHub");
}
}
19 changes: 19 additions & 0 deletions src/Nodes/Endpoints/EventHubItemNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import * as vscode from "vscode";
import { EventHubItem } from "../../Model/EventHubItem";
import { INode } from "../INode";

export class EventHubItemNode implements INode {
constructor(public eventHubItem: EventHubItem) {
}

public getTreeItem(): vscode.TreeItem {
return this.eventHubItem;
}

public getChildren(): INode[] {
return [];
}
}
Loading

0 comments on commit 285c0a7

Please sign in to comment.