зеркало из
1
0
Форкнуть 0

add pnp column, add error for device method (#338)

This commit is contained in:
YingXue 2020-07-23 18:43:55 -07:00 коммит произвёл GitHub
Родитель 310d0902f8
Коммит 003383b24d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 48 добавлений и 35 удалений

2
package-lock.json сгенерированный
Просмотреть файл

@ -18258,4 +18258,4 @@
}
}
}
}
}

Просмотреть файл

@ -17,6 +17,7 @@ describe('utils', () => {
DeviceId: 'test',
IotEdge: false,
LastActivityTime: '2019-07-18T10:01:20.0568390Z',
ModelId: 'dtmi:com:example:Thermostat;1',
Status: 'Enabled',
StatusUpdatedTime: null,
@ -28,6 +29,7 @@ describe('utils', () => {
deviceId: 'test',
iotEdge: false,
lastActivityTime: '3:01:20 AM, July 18, 2019',
modelId: 'dtmi:com:example:Thermostat;1',
status: 'Enabled',
statusUpdatedTime: null,
};
@ -42,6 +44,7 @@ describe('utils', () => {
expect(transformedDevice.lastActivityTime.match(isLocalTime)).toBeTruthy();
expect(transformedDevice.status).toEqual(deviceSummary.status);
expect(transformedDevice.statusUpdatedTime).toEqual(deviceSummary.statusUpdatedTime);
expect(transformedDevice.modelId).toEqual(deviceSummary.modelId);
});
});
});

Просмотреть файл

@ -14,6 +14,7 @@ export const transformDevice = (device: Device): DeviceSummary => {
deviceId: device.DeviceId,
iotEdge: device.IotEdge,
lastActivityTime: parseDateTimeString(device.LastActivityTime),
modelId: device.ModelId,
status: device.Status,
statusUpdatedTime: parseDateTimeString(device.StatusUpdatedTime)
};

Просмотреть файл

@ -11,6 +11,7 @@ export interface Device {
AuthenticationType: string;
IotEdge: boolean;
ConnectionState: string;
ModelId: string;
}
export interface DataPlaneResponse<T> {

Просмотреть файл

@ -11,4 +11,5 @@ export interface DeviceSummary {
authenticationType: string;
connectionState: string;
iotEdge: boolean;
modelId: string;
}

Просмотреть файл

@ -5,7 +5,7 @@
import 'jest';
import * as utils from './utils';
import { ParameterType, OperationType, DeviceCapability, DeviceStatus } from '../models/deviceQuery';
import { LIST_PLUG_AND_PLAY_DEVICES } from '../../constants/devices';
import { LIST_IOT_DEVICES } from '../../constants/devices';
describe('utils', () => {
it('builds query string', () => {
@ -16,7 +16,7 @@ describe('utils', () => {
currentPageIndex: 1,
deviceId: 'device1',
}
)).toEqual(`${LIST_PLUG_AND_PLAY_DEVICES} WHERE STARTSWITH(devices.deviceId, 'device1')`);
)).toEqual(`${LIST_IOT_DEVICES} WHERE STARTSWITH(devices.deviceId, 'device1')`);
expect(utils.buildQueryString(
{
@ -25,11 +25,11 @@ describe('utils', () => {
currentPageIndex: 1,
deviceId: '',
}
)).toEqual(LIST_PLUG_AND_PLAY_DEVICES + ' ');
)).toEqual(LIST_IOT_DEVICES + ' ');
expect(utils.buildQueryString(
null
)).toEqual(LIST_PLUG_AND_PLAY_DEVICES);
)).toEqual(LIST_IOT_DEVICES);
expect(utils.buildQueryString(
{
@ -44,7 +44,7 @@ describe('utils', () => {
currentPageIndex: 1,
deviceId: '',
}
)).toEqual(`${LIST_PLUG_AND_PLAY_DEVICES} WHERE (${ParameterType.edge}=true)`);
)).toEqual(`${LIST_IOT_DEVICES} WHERE (${ParameterType.edge}=true)`);
expect(utils.buildQueryString(
{
@ -59,7 +59,7 @@ describe('utils', () => {
currentPageIndex: 1,
deviceId: '',
}
)).toEqual(`${LIST_PLUG_AND_PLAY_DEVICES} WHERE (${ParameterType.status}='enabled')`);
)).toEqual(`${LIST_IOT_DEVICES} WHERE (${ParameterType.status}='enabled')`);
});
it('converts query object to string', () => {
@ -110,15 +110,6 @@ describe('utils', () => {
expect(utils.escapeValue(`o'really`)).toEqual(`'o'really'`);
});
it('coverts pnp query clauses', () => {
expect(utils.toPnPClause(utils.PnPQueryPrefix.HAS_CAPABILITY_MODEL, 'urn:contoso:com:EnvironmentalSensor:1')).toEqual(
`HAS_CAPABILITYMODEL('urn:contoso:com:EnvironmentalSensor', 1)`
);
expect(utils.toPnPClause(utils.PnPQueryPrefix.HAS_INTERFACE, 'urn:contoso:com:EnvironmentalSensor')).toEqual(
`HAS_INTERFACE('urn:contoso:com:EnvironmentalSensor')`
);
});
it('gets connectionObject from hub connection string', () => {
const connectionObject = utils.getConnectionInfoFromConnectionString('HostName=test.azure-devices-int.net;SharedAccessKeyName=iothubowner;SharedAccessKey=key');
expect(connectionObject.hostName = 'test.azure-devices-int.net');

Просмотреть файл

@ -4,7 +4,7 @@
**********************************************************/
import { createHmac } from 'crypto';
import { IoTHubConnectionSettings } from '../services/devicesService';
import { LIST_PLUG_AND_PLAY_DEVICES, SAS_EXPIRES_MINUTES } from '../../constants/devices';
import { LIST_IOT_DEVICES, SAS_EXPIRES_MINUTES } from '../../constants/devices';
import { DeviceQuery, QueryClause, ParameterType, OperationType } from '../models/deviceQuery';
import { MILLISECONDS_PER_SECOND, SECONDS_PER_MINUTE } from '../../constants/shared';
@ -81,8 +81,8 @@ export const getConnectionInfoFromConnectionString = (connectionString: string):
export const buildQueryString = (query: DeviceQuery) => {
return query ?
`${LIST_PLUG_AND_PLAY_DEVICES} ${queryToString(query)}` :
LIST_PLUG_AND_PLAY_DEVICES;
`${LIST_IOT_DEVICES} ${queryToString(query)}` :
LIST_IOT_DEVICES;
};
export const queryToString = (query: DeviceQuery) => {
@ -127,17 +127,6 @@ export const escapeValue = (value: string) => {
return value;
};
export const toPnPClause = (pnpFunctionName: string, value: string): string => {
const urnVersionRegEx = new RegExp(/:[0-9]+$/);
if (urnVersionRegEx.test(value)) {
const urnVersion = urnVersionRegEx.exec(value)[0].replace(':', '');
const urnName = value.replace(urnVersionRegEx, '');
return `${pnpFunctionName}(${escapeValue(urnName)}, ${urnVersion})`;
}
return `${pnpFunctionName}('${value}')`; // when provided value is not urn with version, pass it in as string
};
export const toEdgeClause = (edgeFunctionName: string, value: string): string => {
return `${edgeFunctionName}=${value === 'true' ? true : false}`;
};

Просмотреть файл

@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License
**********************************************************/
export const LIST_PLUG_AND_PLAY_DEVICES = `
export const LIST_IOT_DEVICES = `
SELECT deviceId as DeviceId,
status as Status,
lastActivityTime as LastActivityTime,
@ -10,7 +10,8 @@ export const LIST_PLUG_AND_PLAY_DEVICES = `
authenticationType as AuthenticationType,
cloudToDeviceMessageCount as CloudToDeviceMessageCount,
connectionState as ConnectionState,
capabilities.iotEdge as IotEdge
capabilities.iotEdge as IotEdge,
modelId as ModelId
FROM devices`;
export const DEVICE_TWIN_QUERY_STRING = ' SELECT * FROM devices WHERE deviceId = {deviceId}';

Просмотреть файл

@ -96,6 +96,15 @@ exports[`DeviceList matches snapshot 1`] = `
"minWidth": 100,
"name": "deviceLists.columns.statusUpdatedTime",
},
Object {
"fieldName": "modelId",
"isMultiline": true,
"isResizable": true,
"key": "modelId",
"maxWidth": 400,
"minWidth": 100,
"name": "deviceLists.columns.isPnpDevice",
},
Object {
"fieldName": "edge",
"isResizable": true,

Просмотреть файл

@ -138,6 +138,8 @@ export const DeviceList: React.FC = () => {
maxWidth: SMALL_COLUMN_WIDTH, minWidth: 100, name: t(ResourceKeys.deviceLists.columns.authenticationType)},
{ fieldName: 'statusUpdatedTime', isMultiline: true, isResizable: true, key: 'statusUpdatedTime',
maxWidth: MEDIUM_COLUMN_WIDTH, minWidth: 100, name: t(ResourceKeys.deviceLists.columns.statusUpdatedTime)},
{ fieldName: 'modelId', isMultiline: true, isResizable: true, key: 'modelId',
maxWidth: LARGE_COLUMN_WIDTH, minWidth: 100, name: t(ResourceKeys.deviceLists.columns.isPnpDevice)},
{ fieldName: 'edge', isResizable: true, key: 'edge',
minWidth: 100, name: t(ResourceKeys.deviceLists.columns.isEdgeDevice.label)},
];
@ -195,6 +197,14 @@ export const DeviceList: React.FC = () => {
t(ResourceKeys.deviceLists.columns.isEdgeDevice.yes) : t(ResourceKeys.deviceLists.columns.isEdgeDevice.no)}
/>
);
case 'modelId':
return (
<Label
key={column.key}
>
{item.modelId}
</Label>
);
default:
return;
}

Просмотреть файл

@ -105,7 +105,7 @@ describe('server', () => {
it('generates data plane response with no httpResponse', () => {
const response = processDataPlaneResponse(null, null);
expect(response.body).toEqual(`Cannot read property 'headers' of null`);
expect(response.body).toEqual({body: {Message: `Cannot read property 'headers' of null`}});
});
it('generates data plane response using device status code', () => {

Просмотреть файл

@ -35,8 +35,15 @@ export const generateDataPlaneResponse = (httpRes: request.Response, body: any,
export const processDataPlaneResponse = (httpRes: request.Response, body: any): {body: {body: any, headers?: any}, statusCode: number} => { // tslint:disable-line:no-any
try {
if (httpRes.headers && httpRes.headers[DEVICE_STATUS_HEADER]) { // handles happy failure cases when error code is returned as a header
let deviceResponseBody;
try {
deviceResponseBody = body && JSON.parse(body);
}
catch {
throw new Error('Failed to parse response from device. The response is expected to be a JSON document up to 128 KB. Learn more: https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-direct-methods#method-lifecycle.');
}
return {
body: {body: body && JSON.parse(body)},
body: {body: deviceResponseBody},
statusCode: parseInt(httpRes.headers[DEVICE_STATUS_HEADER] as string) // tslint:disable-line:radix
};
}
@ -49,7 +56,7 @@ export const processDataPlaneResponse = (httpRes: request.Response, body: any):
}
catch (error) {
return {
body: error.message,
body: {body: {Message: error.message}},
statusCode: SERVER_ERROR
};
}