Skip to content

Commit

Permalink
Add JSON schema check when create deployment (#285)
Browse files Browse the repository at this point in the history
* Add JSON schema check when create deployment

* Use message box instead of output channel, add json string check

* Clean validate json schema logic

* simplify code

* clean code

* remove unnecessary file and reference

* Move validate json schema logic to getDeploymentJson function
  • Loading branch information
SLdragon authored Mar 18, 2019
1 parent 14c23c7 commit ea73821
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 8 deletions.
42 changes: 37 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,8 @@
},
"dependencies": {
"@azure/event-hubs": "^1.0.8",
"ajv": "^6.10.0",
"axios": "^0.18.0",
"azure-arm-iothub": "^2.0.1",
"azure-arm-resource": "^2.0.0-preview",
"azure-iot-common": "^1.8.1",
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class Constants {
public static IoTHubDeviceTwinLabel = "DeviceTwin";
public static IoTHubModuleTwinLabel = "ModuleTwin";
public static IoTHubDistributedTracingSettingLabel = "DistributedTracingSetting";
public static IoTHubEdgeLabel = "Edge";

public static IoTHubAILoadDeviceTreeEvent = "AZ.LoadDeviceTree";
public static IoTHubAIStartMonitorEvent = "AZ.D2C.startMonitoring";
Expand Down Expand Up @@ -108,10 +109,12 @@ export class Constants {
public static IoTHubAILoadLabelInDeviceTreeDoneEvent = "AZ.LoadLabelInDeviceTree.Done";
public static IoTHubAIStartLoadDeviceTreeEvent = "General.StartLoadDeviceTree";
public static IoTHubAIShowWelcomePagetEvent = "General.WelcomePage.Show";
public static IoTHubAIValidateJsonSchemaEvent = "General.ValidateJsonSchema.Done";
public static PercentageLabel = "(%)";
public static NotSetLabel = "Not Set";
public static DisabledLabel = "Disabled";
public static EnabledLabel = "Enabled";
public static DeploymentJsonSchemaUrl = "http://json.schemastore.org/azure-iot-edge-deployment-1.0";

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 Down
30 changes: 27 additions & 3 deletions src/iotEdgeExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the MIT license.

"use strict";
import * as Ajv from "ajv";
import axios from "axios";
import * as iothub from "azure-iothub";
import * as fs from "fs";
import * as path from "path";
Expand Down Expand Up @@ -102,6 +104,18 @@ export class IoTEdgeExplorer extends BaseExplorer {
}
}

private async isValidDeploymentJsonSchema(json: object): Promise<boolean> {
const schema = (await axios.get(Constants.DeploymentJsonSchemaUrl)).data;
const ajv = new Ajv({ allErrors: true });
const valid = ajv.validate(schema, json);
if (!valid) {
vscode.window.showErrorMessage(`There are errors in deployment json file: ${ajv.errorsText(null, { separator: ", " })}`);
return false;
}

return true;
}

private async getModuleTwinById(deviceId: string, moduleId: string, moduleType: string = "unknown") {
TelemetryClient.sendEvent(Constants.IoTHubAIGetModuleTwinStartEvent, { moduleType });
const iotHubConnectionString = await Utility.getConnectionString(Constants.IotHubConnectionStringKey, Constants.IotHubConnectionStringTitle);
Expand Down Expand Up @@ -152,8 +166,18 @@ export class IoTEdgeExplorer extends BaseExplorer {
if (!contentJson.modulesContent && contentJson.moduleContent) {
contentJson.modulesContent = contentJson.moduleContent;
delete contentJson.moduleContent;
content = JSON.stringify(contentJson, null, 2);
}

try {
const isValid = await this.isValidDeploymentJsonSchema(contentJson);
if (!isValid) {
return "";
}
} catch (error) {
TelemetryClient.sendEvent(Constants.IoTHubAIValidateJsonSchemaEvent, { error: error.message });
}

content = JSON.stringify(contentJson, null, 2);
} catch (error) {
vscode.window.showErrorMessage("Failed to parse deployment manifest: " + error.toString());
return "";
Expand All @@ -163,7 +187,7 @@ export class IoTEdgeExplorer extends BaseExplorer {
}

private async deploy(iotHubConnectionString: string, deviceId: string, deploymentJson: string, from: string) {
const label = "Edge";
const label = Constants.IoTHubEdgeLabel;
this._outputChannel.show();
this.outputLine(label, `Start deployment to device [${deviceId}]`);
const entry = from === "none" ? "commandPalette" : "contextMenu";
Expand Down Expand Up @@ -268,7 +292,7 @@ export class IoTEdgeExplorer extends BaseExplorer {
priority: parseInt(priority, 10),
};

const label = "Edge";
const label = Constants.IoTHubEdgeLabel;
this._outputChannel.show();
this.outputLine(label, `Start deployment with deployment id [${deploymentId}] and target condition [${targetCondition}]`);

Expand Down

0 comments on commit ea73821

Please sign in to comment.