Skip to content

Commit

Permalink
feat(ml): add ml models resource
Browse files Browse the repository at this point in the history
  • Loading branch information
rosalie-liu authored and gdostie committed Nov 1, 2019
1 parent 0f70407 commit 03c98af
Show file tree
Hide file tree
Showing 15 changed files with 318 additions and 1 deletion.
23 changes: 23 additions & 0 deletions src/resources/MachineLearning/MachineLearning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import API from '../../APICore';
import Resource from '../Resource';
import {MLModelCreated, RegistrationModel} from './MachineLearningInterfaces';
import ModelInformation from './ModelInformation/ModelInformation';
import Models from './Models/Models';

export default class MachineLearning extends Resource {
static baseUrl = `/rest/organizations/${API.orgPlaceholder}/machinelearning`;

models: Models;
modelInfo: ModelInformation;

constructor(protected api: API) {
super(api);

this.models = new Models(api);
this.modelInfo = new ModelInformation(api);
}

register(registration: RegistrationModel) {
return this.api.post<MLModelCreated>(`${MachineLearning.baseUrl}/model`, registration);
}
}
26 changes: 26 additions & 0 deletions src/resources/MachineLearning/MachineLearningInterfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {IdAndDisplayNameModel} from '../BaseInterfaces';
import {MLModel} from './Models/ModelsInterfaces';

export interface RegistrationModel {
engineId: string;
modelName: string;
modelDisplayName?: string;
exportPeriod: string;
intervalTime: number;
intervalUnit: 'DAY' | 'WEEK' | 'MONTH';
exportOffset?: string;
apiKeysThatCanEdit?: IdAndDisplayNameModel[];
groupsThatCanEdit?: IdAndDisplayNameModel[];
commandLineParameters?: string[];
commonFilter?: string;
customEventFilter?: string;
searchEventFilter?: string;
viewEventFilter?: string;
versionMatcher?: string;
}

export interface MLModelCreated extends MLModel {
endTime?: number;
startTime?: number;
resourceId?: string;
}
22 changes: 22 additions & 0 deletions src/resources/MachineLearning/ModelInformation/ModelInformation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import API from '../../../APICore';
import Resource from '../../Resource';
import {RegistrationModel} from '../MachineLearningInterfaces';
import {MLModel} from '../Models/ModelsInterfaces';
import {MLModelInfo} from './ModelInformationInterfaces';

export default class ModelInformation extends Resource {
static getBaseUrl = (engineId: string, modelName: string) =>
`/rest/organizations/${API.orgPlaceholder}/machinelearning/engines/${engineId}/models/${modelName}`;

get(engineId: string, modelName: string) {
return this.api.get<MLModelInfo>(`${ModelInformation.getBaseUrl(engineId, modelName)}/details`);
}

delete(engineId: string, modelName: string) {
return this.api.delete(ModelInformation.getBaseUrl(engineId, modelName));
}

update(engineId: string, modelName: string, modelInformation: RegistrationModel) {
return this.api.put<Partial<MLModel>>(ModelInformation.getBaseUrl(engineId, modelName), modelInformation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface MLModelInfo {
id: string;
info?: {};
}
2 changes: 2 additions & 0 deletions src/resources/MachineLearning/ModelInformation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ModelInformation';
export * from './ModelInformationInterfaces';
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import API from '../../../../APICore';
import {RegistrationModel} from '../../MachineLearningInterfaces';
import ModelInformation from '../ModelInformation';

jest.mock('../../../../APICore');

const APIMock: jest.Mock<API> = API as any;

describe('ModelInformation', () => {
let modelInfo: ModelInformation;
const api = new APIMock() as jest.Mocked<API>;

beforeEach(() => {
jest.clearAllMocks();
modelInfo = new ModelInformation(api);
});

describe('get', () => {
it('should make a GET call to the specific ModelInformation url', () => {
const engineId = 'O. O';
const modelName = 'O .O';

modelInfo.get(engineId, modelName);
expect(api.get).toHaveBeenCalledTimes(1);
expect(api.get).toHaveBeenCalledWith(`${ModelInformation.getBaseUrl(engineId, modelName)}/details`);
});
});

describe('delete', () => {
it('should make a DELETE call to the specific ModelInformation url', () => {
const engineId = 'OAO';
const modelName = 'QAQ';

modelInfo.delete(engineId, modelName);
expect(api.delete).toHaveBeenCalledTimes(1);
expect(api.delete).toHaveBeenCalledWith(ModelInformation.getBaseUrl(engineId, modelName));
});
});

describe('update', () => {
it('should make a PUT call to the specific ModelInformation url', () => {
const engineId = '-_-';
const modelName = '@_@';
const modelInformation: RegistrationModel = {
engineId: 'O_O',
modelName: 'mini model',
exportPeriod: 'XYZ',
intervalTime: 999,
intervalUnit: 'WEEK',
};

modelInfo.update(engineId, modelName, modelInformation);
expect(api.put).toHaveBeenCalledTimes(1);
expect(api.put).toHaveBeenCalledWith(ModelInformation.getBaseUrl(engineId, modelName), modelInformation);
});
});
});
24 changes: 24 additions & 0 deletions src/resources/MachineLearning/Models/Models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import API from '../../../APICore';
import Resource from '../../Resource';
import {MLModelInfo} from '../ModelInformation/ModelInformationInterfaces';
import {MLModel} from './ModelsInterfaces';

export default class Models extends Resource {
static baseUrl = `/rest/organizations/${API.orgPlaceholder}/machinelearning/models`;

list() {
return this.api.get<MLModel[]>(Models.baseUrl);
}

listDetails() {
return this.api.get<MLModel[]>(`${Models.baseUrl}/details`);
}

get(modelId: string) {
return this.api.get<MLModelInfo>(`${Models.baseUrl}/${modelId}/details`);
}

delete(modelId: string) {
return this.api.delete(`${Models.baseUrl}/${modelId}`);
}
}
55 changes: 55 additions & 0 deletions src/resources/MachineLearning/Models/ModelsInterfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {IdAndDisplayNameModel} from '../../BaseInterfaces';
import {MLModelInfo} from '../ModelInformation/ModelInformationInterfaces';

export interface MLModel extends MLModelInfo {
orgId: string;
id: string;
engineId: string;
modelName: string;
modelDisplayName?: string;
modelCreationTime: number;
nextModelUpdateTime?: number;
modelVersion?: string;
engineVersion?: string;
platformVersion?: 1 | 2;
versionMatcher?: string;
apiKeysThatCanEdit?: IdAndDisplayNameModel[];
groupsThatCanEdit?: IdAndDisplayNameModel[];
modelErrorDescription?: ModelErrorDescription;
previousModelUpdateTime?: number;
intervalTime: number;
intervalUnit: 'DAY' | 'WEEK' | 'MONTH';
exportPeriod: string;
exportOffset?: string;
status:
| 'DELETED'
| 'SCHEDULING'
| 'SCHEDULED'
| 'ERROR'
| 'PENDING'
| 'REGISTERED'
| 'PAUSED'
| 'REGISTERING'
| 'IN_PROGRESS'
| 'ERROR_DELETING'
| 'ONLINE'
| 'OFFLINE'
| 'IN_CREATION';
commandLineParameters?: string[];
commonFilter?: string;
customEventFilter?: string;
searchEventFilter?: string;
viewEventFilter?: string;
}

export interface ModelErrorDescription {
customer_errors?: CustomerError[];
}

export interface CustomerError {
description?: string;
errorCode?: string;
errorType?: string;
precision?: string;
troubleshoot?: string;
}
2 changes: 2 additions & 0 deletions src/resources/MachineLearning/Models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './Models';
export * from './ModelsInterfaces';
52 changes: 52 additions & 0 deletions src/resources/MachineLearning/Models/tests/Models.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import API from '../../../../APICore';
import Models from '../Models';

jest.mock('../../../../APICore');

const APIMock: jest.Mock<API> = API as any;

describe('Models', () => {
let models: Models;
const api = new APIMock() as jest.Mocked<API>;

beforeEach(() => {
jest.clearAllMocks();
models = new Models(api);
});

describe('list', () => {
it('should make a GET call to the Models base url', () => {
models.list();
expect(api.get).toHaveBeenCalledTimes(1);
expect(api.get).toHaveBeenCalledWith(Models.baseUrl);
});
});

describe('listDetails', () => {
it('should make a GET call to the specific Models url', () => {
models.listDetails();
expect(api.get).toHaveBeenCalledTimes(1);
expect(api.get).toHaveBeenCalledWith(`${Models.baseUrl}/details`);
});
});

describe('get', () => {
it('should make a GET call to the specific Models url', () => {
const modelId = 'O. O';

models.get(modelId);
expect(api.get).toHaveBeenCalledTimes(1);
expect(api.get).toHaveBeenCalledWith(`${Models.baseUrl}/${modelId}/details`);
});
});

describe('delete', () => {
it('should make a DELETE call to the specific Models url', () => {
const modelId = 'O .O';

models.delete(modelId);
expect(api.delete).toHaveBeenCalledTimes(1);
expect(api.delete).toHaveBeenCalledWith(`${Models.baseUrl}/${modelId}`);
});
});
});
4 changes: 4 additions & 0 deletions src/resources/MachineLearning/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './MachineLearning';
export * from './MachineLearningInterfaces';
export * from './Models/';
export * from './ModelInformation/';
33 changes: 33 additions & 0 deletions src/resources/MachineLearning/tests/MachineLearning.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import API from '../../../APICore';
import MachineLearning from '../MachineLearning';
import {RegistrationModel} from '../MachineLearningInterfaces';

jest.mock('../../../APICore');

const APIMock: jest.Mock<API> = API as any;

describe('MachineLearning', () => {
let ml: MachineLearning;
const api = new APIMock() as jest.Mocked<API>;

beforeEach(() => {
jest.clearAllMocks();
ml = new MachineLearning(api);
});

describe('register', () => {
it('should make a POST call to the specific MachineLearning url', () => {
const registration: RegistrationModel = {
engineId: 'OvO',
modelName: 'super model',
exportPeriod: 'ABC',
intervalTime: 666,
intervalUnit: 'DAY',
};

ml.register(registration);
expect(api.post).toHaveBeenCalledTimes(1);
expect(api.post).toHaveBeenCalledWith(`${MachineLearning.baseUrl}/model`, registration);
});
});
});
3 changes: 3 additions & 0 deletions src/resources/PlatformResources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Catalog from './Catalogs/Catalog';
import Cluster from './Clusters/Cluster';
import Group from './Groups/Groups';
import Index from './Indexes/Indexes';
import MachineLearning from './MachineLearning/MachineLearning';
import Organization from './Organizations/Organization';
import Resource from './Resource';
import SecurityCache from './SecurityCache/SecurityCache';
Expand All @@ -18,6 +19,7 @@ const resourcesMap: Array<{key: string; resource: typeof Resource}> = [
{key: 'index', resource: Index},
{key: 'securityCache', resource: SecurityCache},
{key: 'apiKey', resource: ApiKey},
{key: 'ml', resource: MachineLearning},
];

class PlatformResources {
Expand All @@ -30,6 +32,7 @@ class PlatformResources {
organization: Organization;
index: Index;
apiKey: ApiKey;
ml: MachineLearning;
securityCache: SecurityCache;

registerAll() {
Expand Down
1 change: 1 addition & 0 deletions src/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './Indexes';
export * from './License';
export * from './Organizations';
export * from './ApiKeys';
export * from './MachineLearning';
11 changes: 10 additions & 1 deletion src/resources/tests/PlatformResources.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import AWS from '../AWS/AWS';
import Catalog from '../Catalogs/Catalog';
import Cluster from '../Clusters/Cluster';
import Group from '../Groups/Groups';
import MachineLearning from '../MachineLearning/MachineLearning';
import Organization from '../Organizations/Organization';
import PlatformResources from '../PlatformResources';
import SecurityCache from '../SecurityCache/SecurityCache';
Expand Down Expand Up @@ -57,12 +58,20 @@ describe('PlatformResources', () => {
expect(platformResources.securityCache).toBeInstanceOf(SecurityCache);
});

it('should register the api keys ressource on the platform instance', () => {
it('should register the apiKey resource on the platform instance', () => {
const platformResources = new PlatformResources();
platformResources.registerAll();

expect(platformResources.apiKey).toBeDefined();
expect(platformResources.apiKey).toBeInstanceOf(ApiKey);
});

it('should register the ml resource on the platform instance', () => {
const platformResources = new PlatformResources();
platformResources.registerAll();

expect(platformResources.ml).toBeDefined();
expect(platformResources.ml).toBeInstanceOf(MachineLearning);
});
});
});

0 comments on commit 03c98af

Please sign in to comment.