Skip to content

Commit

Permalink
List, create, delete modules (#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
formulahendry authored Aug 27, 2018
1 parent 6e5297c commit 365a3af
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 31 deletions.
44 changes: 38 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
"onCommand:azure-iot-toolkit.generateSasTokenForDevice",
"onCommand:azure-iot-toolkit.generateSasTokenForIotHub",
"onCommand:azure-iot-toolkit.showWelcomePage",
"onCommand:azure-iot-toolkit.generateCode"
"onCommand:azure-iot-toolkit.generateCode",
"onCommand:azure-iot-toolkit.createModule",
"onCommand:azure-iot-toolkit.deleteModule"
],
"main": "./out/src/extension",
"contributes": {
Expand Down Expand Up @@ -193,12 +195,12 @@
{
"command": "azure-iot-toolkit.getModuleTwin",
"title": "Edit Module Twin",
"category": "Azure IoT Edge"
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.updateModuleTwin",
"title": "Update Module Twin",
"category": "Azure IoT Edge"
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.generateSasTokenForDevice",
Expand All @@ -214,6 +216,16 @@
"command": "azure-iot-toolkit.generateCode",
"title": "Generate Code",
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.createModule",
"title": "Create Module",
"category": "Azure IoT Hub"
},
{
"command": "azure-iot-toolkit.deleteModule",
"title": "Delete Module",
"category": "Azure IoT Hub"
}
],
"menus": {
Expand Down Expand Up @@ -321,10 +333,15 @@
"group": "azure-iot-toolkit@9"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"command": "azure-iot-toolkit.createModule",
"when": "view == iotHubDevices && viewItem == device",
"group": "azure-iot-toolkit@10"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"when": "view == iotHubDevices && viewItem == device",
"group": "azure-iot-toolkit@11"
},
{
"command": "azure-iot-toolkit.generateCode",
"when": "view == iotHubDevices && viewItem == edge",
Expand Down Expand Up @@ -376,10 +393,15 @@
"group": "azure-iot-toolkit@9"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"command": "azure-iot-toolkit.createModule",
"when": "view == iotHubDevices && viewItem == edge",
"group": "azure-iot-toolkit@10"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"when": "view == iotHubDevices && viewItem == edge",
"group": "azure-iot-toolkit@11"
},
{
"command": "azure-iot-toolkit.createDeployment",
"when": "view == iotHubDevices && viewItem == edge",
Expand All @@ -392,11 +414,17 @@
},
{
"command": "azure-iot-toolkit.getModuleTwin",
"when": "view == iotHubDevices && viewItem == module"
"when": "view == iotHubDevices && viewItem == module",
"group": "azure-iot-toolkit@0"
},
{
"command": "azure-iot-toolkit.getModuleTwin",
"when": "view == iotHubDevices && viewItem == edge-module"
},
{
"command": "azure-iot-toolkit.deleteModule",
"when": "view == iotHubDevices && viewItem == module",
"group": "azure-iot-toolkit@1"
}
],
"editor/context": [
Expand Down Expand Up @@ -437,6 +465,10 @@
{
"command": "azure-iot-toolkit.getModuleTwin",
"when": "never"
},
{
"command": "azure-iot-toolkit.deleteModule",
"when": "never"
}
]
},
Expand Down
4 changes: 2 additions & 2 deletions src/Model/DeviceItem.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { Command, QuickPickItem, TreeItem } from "vscode";
import { QuickPickItem, TreeItem, TreeItemCollapsibleState } from "vscode";

export class DeviceItem extends TreeItem implements QuickPickItem {
public readonly label: string;
constructor(
public readonly deviceId: string,
public readonly connectionString: string,
public iconPath: string,
public command: Command,
public readonly connectionState: string,
public readonly description: string) {
super(deviceId);
this.contextValue = "device";
this.collapsibleState = TreeItemCollapsibleState.Collapsed;
}
}
5 changes: 4 additions & 1 deletion src/Model/ModuleItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
// Licensed under the MIT license.

import { Command, TreeItem } from "vscode";
import { DeviceItem } from "./DeviceItem";

export class ModuleItem extends TreeItem {
public readonly deviceId: string;
constructor(
public readonly deviceId: string,
public readonly deviceItem: DeviceItem,
public readonly moduleId: string,
public readonly runtimeStatus: string,
public readonly iconPath: string,
public readonly contextValue: string) {
super(runtimeStatus ? `${moduleId} (${runtimeStatus})` : moduleId);
this.deviceId = deviceItem.deviceId;
}
}
11 changes: 11 additions & 0 deletions src/azureIoTExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { IotHubC2DMessageExplorer } from "./iotHubC2DMessageExplorer";
import { IotHubDeviceTwinExplorer } from "./iotHubDeviceTwinExplorer";
import { IotHubDirectMethodExplorer } from "./iotHubDirectMethodExplorer";
import { IoTHubMessageExplorer } from "./iotHubMessageExplorer";
import { IotHubModuleExplorer } from "./iotHubModuleExplorer";
import { IoTHubResourceExplorer } from "./iotHubResourceExplorer";
import { DeviceItem } from "./Model/DeviceItem";
import { ModuleItem } from "./Model/ModuleItem";
Expand All @@ -27,6 +28,7 @@ export class AzureIoTExplorer {
private _iotEdgeExplorer: IoTEdgeExplorer;
private _welcomePage: WelcomePage;
private _codeManager: CodeManager;
private _iotHubModuleExplorer: IotHubModuleExplorer;

constructor(private context: vscode.ExtensionContext) {
let outputChannel = vscode.window.createOutputChannel("Azure IoT Toolkit");
Expand All @@ -40,6 +42,7 @@ export class AzureIoTExplorer {
this._iotEdgeExplorer = new IoTEdgeExplorer(outputChannel);
this._welcomePage = new WelcomePage(this.context);
this._codeManager = new CodeManager(this.context);
this._iotHubModuleExplorer = new IotHubModuleExplorer(outputChannel);
}

public sendD2CMessage(deviceItem?: DeviceItem): void {
Expand Down Expand Up @@ -149,4 +152,12 @@ export class AzureIoTExplorer {
public generateCode(deviceItem: DeviceItem): void {
this._codeManager.generateCode(deviceItem);
}

public createModule(deviceItem: DeviceItem): void {
this._iotHubModuleExplorer.createModule(deviceItem);
}

public deleteModule(moduleItem: ModuleItem): void {
this._iotHubModuleExplorer.deleteModule(moduleItem);
}
}
18 changes: 12 additions & 6 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,20 @@ export class Constants {
public static IoTHubAIEdgeDeployAtScaleDoneEvent = "AZ.Edge.DeployAtScale.Done";
public static IoTHubAICreateStartEvent = "General.IoTHub.Create.Start";
public static IoTHubAICreateDoneEvent = "AZ.IoTHub.Create.Done";
public static IoTHubAIGetModuleTwinStartEvent = "AZ.Edge.ModuleTwin.Get.Start";
public static IoTHubAIGetModuleTwinDoneEvent = "AZ.Edge.ModuleTwin.Get.Done";
public static IoTHubAIUpdateModuleTwinStartEvent = "AZ.Edge.ModuleTwin.Update.Start";
public static IoTHubAIUpdateModuleTwinDoneEvent = "AZ.Edge.ModuleTwin.Update.Done";
public static IoTHubAIGetModuleTwinStartEvent = "AZ.ModuleTwin.Get.Start";
public static IoTHubAIGetModuleTwinDoneEvent = "AZ.ModuleTwin.Get.Done";
public static IoTHubAIUpdateModuleTwinStartEvent = "AZ.ModuleTwin.Update.Start";
public static IoTHubAIUpdateModuleTwinDoneEvent = "AZ.ModuleTwin.Update.Done";
public static ModuleTwinJosnFileName = "azure-iot-module-twin.json";
public static ModuleTwinJosnFilePath: string;
public static IoTHubAILoadModuleTreeStartEvent = "AZ.Edge.LoadModuleTree.Start";
public static IoTHubAILoadModuleTreeDoneEvent = "AZ.Edge.LoadModuleTree.Done";
public static IoTHubAILoadModuleTreeStartEvent = "AZ.LoadModuleTree.Start";
public static IoTHubAILoadModuleTreeDoneEvent = "AZ.LoadModuleTree.Done";
public static IoTHubAILoadEdgeModuleTreeStartEvent = "AZ.Edge.LoadModuleTree.Start";
public static IoTHubAILoadEdgeModuleTreeDoneEvent = "AZ.Edge.LoadModuleTree.Done";
public static IoTHubAICreateModuleStartEvent = "AZ.Module.Create.Start";
public static IoTHubAICreateModuleDoneEvent = "AZ.Module.Create.Done";
public static IoTHubAIDeleteModuleStartEvent = "AZ.Module.Delete.Start";
public static IoTHubAIDeleteModuleDoneEvent = "AZ.Module.Delete.Done";

public static IoTHubAIStartLoadDeviceTreeEvent = "General.StartLoadDeviceTree";
public static IoTHubAIShowWelcomePagetEvent = "General.WelcomePage.Show";
Expand Down
15 changes: 14 additions & 1 deletion src/deviceTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,23 @@ export class DeviceTree implements vscode.TreeDataProvider<vscode.TreeItem> {
}

if (element && element.contextValue === "edge") {
TelemetryClient.sendEvent(Constants.IoTHubAILoadEdgeModuleTreeStartEvent);
try {
const moduleList: vscode.TreeItem[] = await Utility.getModuleItemsForEdge(iotHubConnectionString, element as DeviceItem, this.context);
TelemetryClient.sendEvent(Constants.IoTHubAILoadEdgeModuleTreeDoneEvent, { Result: "Success" });
return moduleList;
} catch (err) {
TelemetryClient.sendEvent(Constants.IoTHubAILoadEdgeModuleTreeDoneEvent, { Result: "Fail", Message: err.message });
return this.getErrorMessageTreeItems("modules", err.message);
}
} else if (element && element.contextValue === "device") {
TelemetryClient.sendEvent(Constants.IoTHubAILoadModuleTreeStartEvent);
try {
const moduleList: vscode.TreeItem[] = await Utility.getModuleItems(iotHubConnectionString, (element as DeviceItem).deviceId, this.context);
const moduleList: vscode.TreeItem[] = await Utility.getModuleItems(iotHubConnectionString, element as DeviceItem, this.context);
TelemetryClient.sendEvent(Constants.IoTHubAILoadModuleTreeDoneEvent, { Result: "Success" });
if (moduleList.length === 0) {
moduleList.push(new vscode.TreeItem(`No modules`));
}
return moduleList;
} catch (err) {
TelemetryClient.sendEvent(Constants.IoTHubAILoadModuleTreeDoneEvent, { Result: "Fail", Message: err.message });
Expand Down
8 changes: 8 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ export function activate(context: vscode.ExtensionContext) {
azureIoTExplorer.generateCode(DeviceItem);
}));

context.subscriptions.push(vscode.commands.registerCommand("azure-iot-toolkit.createModule", (DeviceItem) => {
azureIoTExplorer.createModule(DeviceItem);
}));

context.subscriptions.push(vscode.commands.registerCommand("azure-iot-toolkit.deleteModule", (moduleItem) => {
azureIoTExplorer.deleteModule(moduleItem);
}));

vscode.workspace.onDidChangeTextDocument((event) => azureIoTExplorer.replaceConnectionString(event));

context.subscriptions.push(vscode.window.onDidCloseTerminal((closedTerminal: vscode.Terminal) => {
Expand Down
6 changes: 3 additions & 3 deletions src/iotEdgeExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class IoTEdgeExplorer extends BaseExplorer {

public async getModuleTwin(moduleItem: ModuleItem) {
if (moduleItem) {
await this.getModuleTwinById(moduleItem.deviceId, moduleItem.moduleId);
await this.getModuleTwinById(moduleItem.deviceId, moduleItem.moduleId, moduleItem.contextValue);
}
}

Expand Down Expand Up @@ -105,8 +105,8 @@ export class IoTEdgeExplorer extends BaseExplorer {
}
}

private async getModuleTwinById(deviceId: string, moduleId: string) {
TelemetryClient.sendEvent(Constants.IoTHubAIGetModuleTwinStartEvent);
private async getModuleTwinById(deviceId: string, moduleId: string, moduleType: string = "unknown") {
TelemetryClient.sendEvent(Constants.IoTHubAIGetModuleTwinStartEvent, { moduleType });
const iotHubConnectionString = await Utility.getConnectionString(Constants.IotHubConnectionStringKey, Constants.IotHubConnectionStringTitle);
if (!iotHubConnectionString) {
return;
Expand Down
77 changes: 77 additions & 0 deletions src/iotHubModuleExplorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

"use strict";
import * as iothub from "azure-iothub";
import * as vscode from "vscode";
import { BaseExplorer } from "./baseExplorer";
import { Constants } from "./constants";
import { DeviceItem } from "./Model/DeviceItem";
import { ModuleItem } from "./Model/ModuleItem";
import { TelemetryClient } from "./telemetryClient";
import { Utility } from "./utility";

export class IotHubModuleExplorer extends BaseExplorer {
constructor(outputChannel: vscode.OutputChannel) {
super(outputChannel);
}

public async createModule(deviceItem?: DeviceItem) {
const label = "Module";
deviceItem = await Utility.getInputDevice(deviceItem, Constants.IoTHubAICreateModuleStartEvent);
if (!deviceItem) {
return;
}

const iotHubConnectionString = await Utility.getConnectionString(Constants.IotHubConnectionStringKey, Constants.IotHubConnectionStringTitle);
if (!iotHubConnectionString) {
return;
}

const registry: iothub.Registry = iothub.Registry.fromConnectionString(iotHubConnectionString);

const moduleId: string = await vscode.window.showInputBox({ prompt: "Enter Module ID to create", ignoreFocusOut: true });
if (!moduleId) {
return;
}

this._outputChannel.show();
this.outputLine(label, `Creating '${moduleId}'`);

registry.addModule({ deviceId: deviceItem.deviceId, moduleId }, (err, module) => {
if (err) {
this.outputLine(label, `Error: ${err.message}`);
TelemetryClient.sendEvent(Constants.IoTHubAICreateModuleDoneEvent, { Result: "Fail", Message: err.message });
} else {
this.outputLine(label, `Created: ${JSON.stringify(module, null, 2)}`);
vscode.commands.executeCommand("azure-iot-toolkit.refresh", deviceItem);
TelemetryClient.sendEvent(Constants.IoTHubAICreateModuleDoneEvent, { Result: "Success" });
}
});
}

public async deleteModule(moduleItem: ModuleItem) {
TelemetryClient.sendEvent(Constants.IoTHubAIDeleteModuleStartEvent);
const label = "Module";
const iotHubConnectionString = await Utility.getConnectionString(Constants.IotHubConnectionStringKey, Constants.IotHubConnectionStringTitle);
if (!iotHubConnectionString) {
return;
}

const registry: iothub.Registry = iothub.Registry.fromConnectionString(iotHubConnectionString);

this._outputChannel.show();
this.outputLine(label, `Deleting '${moduleItem.moduleId}'`);

registry.removeModule(moduleItem.deviceId, moduleItem.moduleId, (err) => {
if (err) {
this.outputLine(label, `Error: ${err.message}`);
TelemetryClient.sendEvent(Constants.IoTHubAIDeleteModuleDoneEvent, { Result: "Fail", Message: err.message });
} else {
this.outputLine(label, `Deleted '${moduleItem.moduleId}'`);
vscode.commands.executeCommand("azure-iot-toolkit.refresh", moduleItem.deviceItem);
TelemetryClient.sendEvent(Constants.IoTHubAIDeleteModuleDoneEvent, { Result: "Success" });
}
});
}
}
Loading

0 comments on commit 365a3af

Please sign in to comment.