Skip to content

Commit

Permalink
List PnP Interfaces in tree view (#354)
Browse files Browse the repository at this point in the history
* Interfaces list

* Add BI and icon

* Add refresh button

* Wrap REST Api
  • Loading branch information
formulahendry authored Jul 26, 2019
1 parent 08cc565 commit f4b03c0
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 1 deletion.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,11 @@
{
"command": "azure-iot-toolkit.startMonitorIoTHubMessageWithAbbreviation",
"when": "view == iotHubDevices && viewItem == events"
},
{
"command": "azure-iot-toolkit.refresh",
"when": "view == iotHubDevices && viewItem == interfaces-label",
"group": "inline"
}
],
"editor/context": [
Expand Down
1 change: 1 addition & 0 deletions resources/interface.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/Model/InterfaceItem.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 InterfaceItem extends TreeItem {
constructor(name: string, public readonly iconPath: string) {
super(name);
this.contextValue = "interface";
}
}
2 changes: 2 additions & 0 deletions src/Nodes/DeviceNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DeviceItem } from "../Model/DeviceItem";
import { TelemetryClient } from "../telemetryClient";
import { DistributedTracingLabelNode } from "./DistributedTracingLabelNode";
import { INode } from "./INode";
import { InterfaceLabelNode } from "./InterfaceLabelNode";
import { ModuleLabelNode } from "./ModuleLabelNode";

export class DeviceNode implements INode {
Expand All @@ -24,6 +25,7 @@ export class DeviceNode implements INode {
public async getChildren(context: vscode.ExtensionContext, iotHubConnectionString: string): Promise<INode[]> {
let nodeList: INode[] = [];
nodeList.push(new ModuleLabelNode(this));
nodeList.push(new InterfaceLabelNode(this));
if (this.deviceItem.contextValue === "device" && iotHubConnectionString.toLowerCase().indexOf("azure-devices.cn;") < 0) {
nodeList.push(new DistributedTracingLabelNode(this));
}
Expand Down
46 changes: 46 additions & 0 deletions src/Nodes/InterfaceLabelNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

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

export class InterfaceLabelNode implements INode {
constructor(public deviceNode: DeviceNode) {
}

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

public async getChildren(context: vscode.ExtensionContext, iotHubConnectionString: string): Promise<INode[]> {
TelemetryClient.sendEvent(Constants.IoTHubAILoadInterfacesTreeStartEvent);

try {
const interfaces = (await axios.request(Utility.generateIoTHubAxiosRequestConfig(
iotHubConnectionString,
`/digitalTwins/${this.deviceNode.deviceId}/interfaces?api-version=${Constants.IoTHubApiVersion}`,
"get",
))).data;
TelemetryClient.sendEvent(Constants.IoTHubAILoadInterfacesTreeDoneEvent, { Result: "Success" });
if (!interfaces || !interfaces.interfaces || Object.keys(interfaces.interfaces).length === 0) {
return [new InfoNode("No Interfaces")];
}
return Object.keys(interfaces.interfaces).map((name) => new InterfaceNode(name, context.asAbsolutePath(path.join("resources", `interface.svg`))));
} catch (err) {
TelemetryClient.sendEvent(Constants.IoTHubAILoadInterfacesTreeDoneEvent, { Result: "Fail", Message: err.message });
return Utility.getErrorMessageTreeItems("interfaces", err.message);
}
}
}
19 changes: 19 additions & 0 deletions src/Nodes/InterfaceNode.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 { InterfaceItem } from "../Model/InterfaceItem";
import { INode } from "./INode";

export class InterfaceNode implements INode {
constructor(private name: string, private iconPath: string) {
}

public getTreeItem(): vscode.TreeItem {
return new InterfaceItem(this.name, this.iconPath);
}

public getChildren(): INode[] {
return [];
}
}
4 changes: 3 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export class Constants {
public static CREATE_OPTIONS_MAX_CHUNKS = 8;
public static StateKeySubsID = "subscriptionId";
public static StateKeyIoTHubID = "iothubid";
public static IoTHubAILoadInterfacesTreeStartEvent = "AZ.LoadInterfacesTree.Start";
public static IoTHubAILoadInterfacesTreeDoneEvent = "AZ.LoadInterfacesTree.Done";

public static DeleteLabel = "Delete";
public static DeleteMessage = "Are you sure you want to delete"; public static readonly DISTRIBUTED_TWIN_NAME: string = "azureiot*com^dtracing^1";
Expand All @@ -138,7 +140,7 @@ export class Constants {

public static ShowIoTHubInfoKey = "showIoTHubInfo";
public static ShowConnectionStringInputBoxKey = "showConnectionStringInputBox";
public static IoTHubApiVersion = "2018-06-30";
public static IoTHubApiVersion = "2019-07-01-preview";

public static CodeTemplates = {
[TemplateLanguage.CSharp]: {
Expand Down
13 changes: 13 additions & 0 deletions src/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { INode } from "./Nodes/INode";
import { TelemetryClient } from "./telemetryClient";
import iothub = require("azure-iothub");
import { EventData } from "@azure/event-hubs";
import { AxiosRequestConfig } from "axios";
import { IotHubDescription } from "azure-arm-iothub/lib/models";
import { AzureAccount } from "./azure-account.api";
import { CredentialStore } from "./credentialStore";
Expand Down Expand Up @@ -423,6 +424,18 @@ export class Utility {
await Constants.ExtensionContext.globalState.update(Constants.StateKeyIoTHubID, "");
}

public static generateIoTHubAxiosRequestConfig(iotHubConnectionString: string, url: string, method: string, data?: any): AxiosRequestConfig {
return {
url,
method,
baseURL: `https://${Utility.getHostName(iotHubConnectionString)}`,
headers: {
Authorization: Utility.generateSasTokenForService(iotHubConnectionString),
},
data,
};
}

private static tryGetStringFromCharCode(source) {
if (source instanceof Uint8Array) {
try {
Expand Down

0 comments on commit f4b03c0

Please sign in to comment.