alwaysai
Version:
The alwaysAI command-line interface (CLI)
179 lines (153 loc) • 4.72 kB
text/typescript
//import { CliTerseError } from '@alwaysai/alwayscli';
import {
SystemInformationShadowUpdate,
validateSystemInformationShadowUpdate,
getReportedFromMessage
} from '@alwaysai/device-agent-schemas';
import { v4 as uuidv4 } from 'uuid';
import { CliAuthenticationClient } from '../infrastructure/authentication-client';
import { serviceEndpointBuilder } from '../infrastructure/urls';
import { logger } from './';
export interface SecureTunnelPorts {
enabled: boolean;
type: string;
port: number;
ip: string;
}
interface Shadow {
txId: string;
responseType: string;
payload: {
code?: number;
message?: string;
state?: {
desired?: { st_ports?: SecureTunnelPorts[] };
reported?: { st_ports?: SecureTunnelPorts[] };
};
version?: number;
timestamp?: number;
};
}
export enum HttpStatusCode {
OK = 200,
FORBIDDEN = 403
}
export const getShadow = async (thingId: string) => {
const idTokenAuthorizationHeader =
await CliAuthenticationClient().getIdAuthorizationHeader();
const requestURL = serviceEndpointBuilder('device-shadow', 'GetThingShadow');
const body = {
deviceUuid: thingId,
shadowName: 'secure-tunnel',
txId: uuidv4()
};
logger.debug('getShadow body: ', body);
const response = await fetch(requestURL, {
method: 'post',
body: JSON.stringify(body),
headers: {
...idTokenAuthorizationHeader,
'Content-Type': 'application/json'
}
});
if (!response) {
const errorMsg = 'Error: Receiving response from server';
logger.error(errorMsg);
throw new Error(errorMsg);
}
// if (response.status !== HttpStatusCode.OK) {
// const errorMsg = `Error, response.status = ${response.status}`;
// logger.error(errorMsg);
// throw new Error(errorMsg);
// }
const readerStream = Buffer.from(await response.arrayBuffer());
const parsedJson = JSON.parse(readerStream.toString());
return parsedJson as Shadow;
};
interface UpdateThingShadow {
txtId: string;
responseType: string;
payload: {
state: any;
version: number;
timestamp: number;
};
}
export const updateShadow = async (thingId: string, payload) => {
const idTokenAuthorizationHeader =
await CliAuthenticationClient().getIdAuthorizationHeader();
const requestURL = serviceEndpointBuilder(
'device-shadow',
'UpdateThingShadow'
);
const body = {
deviceUuid: thingId,
shadowName: 'secure-tunnel',
txId: uuidv4(),
payload
};
logger.debug('updateShadow body: ', body);
const response = await fetch(requestURL, {
method: 'post',
body: JSON.stringify(body),
headers: {
...idTokenAuthorizationHeader,
'Content-Type': 'application/json'
}
});
if (!response) {
const errorMsg = 'Error: Receiving response from server';
logger.error(errorMsg);
throw new Error(errorMsg);
}
if (response.status !== HttpStatusCode.OK) {
const errorMsg = `Error, response.status = ${response.status}`;
logger.error(errorMsg);
throw new Error(errorMsg);
}
const readerStream = Buffer.from(await response.arrayBuffer());
const parsedJson = JSON.parse(readerStream.toString());
return parsedJson as UpdateThingShadow;
};
export async function getSystemInfoShadow(
thingId: string
): Promise<SystemInformationShadowUpdate> {
const idTokenAuthorizationHeader =
await CliAuthenticationClient().getIdAuthorizationHeader();
const requestURL = serviceEndpointBuilder('device-shadow', 'GetThingShadow');
const body = {
deviceUuid: thingId,
shadowName: 'system-info',
txId: uuidv4()
};
const response = await fetch(requestURL, {
method: 'post',
body: JSON.stringify(body),
headers: {
...idTokenAuthorizationHeader,
'Content-Type': 'application/json'
}
});
if (!response) {
const errorMsg = 'Error: Receiving response from server';
logger.error(errorMsg);
throw new Error(errorMsg);
}
if (response.status !== HttpStatusCode.OK) {
const errorMsg = `Error, response.status = ${response.status}`;
logger.error(errorMsg);
throw new Error(errorMsg);
}
const readerStream = Buffer.from(await response.arrayBuffer());
const parsedJson = JSON.parse(readerStream.toString());
const reported = getReportedFromMessage(parsedJson.payload);
const valid = validateSystemInformationShadowUpdate(reported);
if (!valid) {
const errorMsg = 'Invalid system info shadow';
logger.error(errorMsg);
logger.error(JSON.stringify(validateSystemInformationShadowUpdate.errors));
// FIXME: Skip validation until disk size provided as string issue is fixed
//throw new CliTerseError(errorMsg);
}
return reported;
}