Skip to content

Commit

Permalink
Refactoring/aipaidao renew api calls (#73)
Browse files Browse the repository at this point in the history
* replace deprecated api calls for plugin fetching

* - remove Create New field,
- Component selector from "app" to "", since this is how the components are named
- resolved some TS warnings

* - resolved all TS warnings in plugin-editor.component.ts

* - allow leading underscore in variable names

* - added policy details such as objectives and parameters

* - hidden the edit buttons

* fixes in query.controller.ts

- query function
- tag function
- address function

* fixes in query.controller.ts

- query function
- tag function
- address function

* console debug error in tag

* adjusted the query.service.ts to the modern response shape of the api;
fixed lots of issues reported by tslint

* switched default to SkillsAndDistance due to outdated default

* tslint fixes

* removed commented code

* added todo;
cleanup;
error info

* clean up
  • Loading branch information
Davo00 authored Oct 10, 2023
1 parent dabe64b commit 3dcdb5e
Show file tree
Hide file tree
Showing 22 changed files with 829 additions and 724 deletions.
1 change: 1 addition & 0 deletions workbench/backend/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ module.exports = {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/camelcase': 'off',
},
};
950 changes: 475 additions & 475 deletions workbench/backend/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion workbench/backend/src/app/booking/booking.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export class BookingController {
.json({ activityId: e.message });
}

let axiosError: AxiosError = e?.error;
const axiosError: AxiosError = e?.error;
return res
.status(axiosError?.response?.status || 500)
.json(axiosError?.response?.data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class JobSlotsController {
return res.json(data);
} catch ({ error }) {

let axiosError: AxiosError = error;
const axiosError: AxiosError = error;
return res
.status(parseInt(axiosError?.code || '500'))
.json(axiosError?.response?.data);
Expand Down
32 changes: 16 additions & 16 deletions workbench/backend/src/app/plugin/ai-data-api.dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,27 @@ export class AiDataAPIDAO {
private request<T>(config: AxiosRequestConfig) {
const requestStart: Date = new Date();
return this.http.request<T>(config).pipe(
tap(response => {
try {
const elapsedMilliseconds: number = new Date().getTime() - requestStart.getTime();
console.debug(
`[AiDataAPIDAO:${config.method}] url: [${config.url}] response: [${JSON.stringify(response ? response.status : null)}], time: [${elapsedMilliseconds}]`,
);
} catch {
console.debug(`[AiDataAPIDAO:${config.method}] url: [${config.url}] response[UNPROCESSIBLE]`);
}
}),
catchError((error: AxiosError) => {
console.error('AiDataAPIDAO', error);
return throwError({ error });
})
tap(response => {
try {
const elapsedMilliseconds: number = new Date().getTime() - requestStart.getTime();
console.debug(
`[AiDataAPIDAO:${config.method}] url: [${config.url}] response: [${JSON.stringify(response ? response.status : null)}], time: [${elapsedMilliseconds}]`,
);
} catch {
console.debug(`[AiDataAPIDAO:${config.method}] url: [${config.url}] response[UNPROCESSIBLE]`);
}
}),
catchError((error: AxiosError) => {
console.error('AiDataAPIDAO', error);
return throwError({ error });
})
);
}

getAll(ctx: Context) {
return this.request<PluginDto[]>({
method: 'GET',
url: `${this.resolveHost(ctx.cloudHost)}/cloud-ai-data-service/api/autoscheduler/v1/optimization-plugins`,
url: `${this.resolveHost(ctx.cloudHost)}/cloud-ai-policy-designer/api/optimization/v1/policies`,
headers: this.getHeaders(ctx),
params: this.getParams(ctx),
responseType: 'json',
Expand All @@ -93,7 +93,7 @@ export class AiDataAPIDAO {
getByName(ctx: Context, name: string) {
return this.request<PluginDto[]>({
method: 'GET',
url: `${this.resolveHost(ctx.cloudHost)}/cloud-ai-data-service/api/autoscheduler/v1/optimization-plugins/by-name/${name}`,
url: `${this.resolveHost(ctx.cloudHost)}/cloud-ai-policy-designer/api/optimization/v1/policies/by-name/${name}`,
headers: this.getHeaders(ctx),
params: this.getParams(ctx),
responseType: 'json',
Expand Down
37 changes: 27 additions & 10 deletions workbench/backend/src/app/query/query.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,44 @@ import { AddressDTO, TagDTO } from '../../common/dto-models';
import { FsmAPIClientFactory } from '../../common/fsm-api-client.factory';
import { DTOName } from 'fsm-sdk/release/core/dto-name.model';

interface QueryResponse<T> {
data: T[];
}

@Controller('api/query')
export class QueryController {

constructor(private factory: FsmAPIClientFactory) { }

@Post()
async query<T>(@Context() ctx: Context, @Body() { query }: { query: string }): Promise<T> {
return await this.factory.fromContext(ctx).query(query, Object.keys(this.factory.ALL_DTO_VERSIONS) as DTOName[])
.then(x => x.data)
.catch(e => { console.error(query); throw e; return undefined as any }) as T;


const coreApiClient = this.factory.fromContext(ctx);
const all_dto_versions = this.factory.ALL_DTO_VERSIONS
delete all_dto_versions["CrowdExecutionRecord"] // TODO remove this line after fsm-sdk has been updated


const dto_names = Object.keys(all_dto_versions) as DTOName[]
return await coreApiClient.query(query, dto_names)
.then(x =>{
return x})
.catch(e => {
throw e;
return undefined as any }) as T;
}

@Get('tags')
async listTags(@Context() ctx: Context) {

const data: { tag: TagDTO }[] = await this.query(ctx, { query: `SELECT tag FROM Tag tag` });

const work = data.map(({ tag }) => {
const data: QueryResponse<{ tag: TagDTO }> = await this.query(ctx, { query: `SELECT tag FROM Tag tag` });
const work = data.data.map(({ tag }) => {
return this.query(ctx, { query: `SELECT it.tag, it.person FROM Skill it WHERE it.tag = '${tag.id}' LIMIT 500` })
.then((resp: { it: { person: string } }[]) => ({ ...tag, persons: resp.map(({ it }) => it.person) }))
.catch(error => ({ ...tag, persons: [] }));
.then((resp: QueryResponse<{ it: { person: string } }>) => ({ ...tag, persons: resp.data.map(({ it }) => it.person) }))
.catch(error => {
console.error("List of Tags could not be collected due to: ", error)
return { ...tag, persons: [] };
});
});

return await Promise.all(work);
Expand All @@ -38,8 +55,8 @@ export class QueryController {
@Get('address')
async listAddress(@Context() ctx: Context) {
const query = `SELECT address FROM Address address LIMIT 2500`;
const list: { address: AddressDTO }[] = await this.query(ctx, { query });
return list.map(x => x.address);
const list: QueryResponse<{ address: AddressDTO }> = await this.query(ctx, { query });
return list.data.map(x => x.address);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class ReOptimizeController {
const { data } = await this.dao.reOptimize('sync', ctx, body).toPromise();
return res.json(data);
} catch (e) {
let axiosError: AxiosError = e?.error;
const axiosError: AxiosError = e?.error;
return res
.status(axiosError?.response?.status || 500)
.json(axiosError?.response?.data);
Expand All @@ -30,7 +30,7 @@ export class ReOptimizeController {
const { data } = await this.dao.reOptimize('async', ctx, body).toPromise();
return res.json(data);
} catch (e) {
let axiosError: AxiosError = e?.error;
const axiosError: AxiosError = e?.error;
return res
.status(axiosError?.response?.status || 500)
.json(axiosError?.response?.data);
Expand Down
4 changes: 3 additions & 1 deletion workbench/backend/src/common/error.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export class ErrorFilter implements ExceptionFilter {
let message = 'Error';
let inner: {} = {};

const _inner = (error as any).error as undefined | AxiosError;


const _inner = (error as any).error as undefined | Record<any, any>;

if (!!_inner) {
inner = typeof _inner.toJSON === 'function' ? _inner.toJSON() : {};
Expand Down
21 changes: 14 additions & 7 deletions workbench/backend/src/common/fsm-api-client.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ import { Context } from '../ctx.decorator';
@Injectable()
export class FsmAPIClientFactory {

public ALL_DTO_VERSIONS: { [name: string]: number } = ALL_DTO_VERSIONS;

public fromContext(ctx: Context) {
return new CoreAPIClient({
const result = new CoreAPIClient({
debug: configService.useVerboseLogs(),
clientIdentifier: ctx.clientId,
clientVersion: ctx.clientVersion,
clientSecret: 'none',
clientSecret: ctx.authToken,
authAccountName: ctx.account,
authCompany: ctx.company,
authUserName: ctx.user
}).setToken({
authUserName: ctx.user,
authGrantType: 'client_credentials',
});
result.setToken({
// eslint-disable-next-line @typescript-eslint/camelcase
access_token: ctx.authToken.split(' ')[1],
token_type: ctx.authToken.split(' ')[0],
expires_in: 9999,
Expand All @@ -28,8 +33,10 @@ export class FsmAPIClientFactory {
companies: [{ name: ctx.company, id: parseInt(ctx.companyId), strictEncryptionPolicy: false, description: '' }],
authorities: [],
cluster_url: `https://${ctx.cloudHost}`
})
});

return result;
}

public ALL_DTO_VERSIONS: { [name: string]: number } = ALL_DTO_VERSIONS;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,6 @@
</mat-select>
</mat-form-field>


<button mat-button [disabled]="form.invalid" (click)="save()" color="primary" class="inline-btn">
<mat-icon>save</mat-icon>
</button>

<button mat-button [disabled]="selectedPlugin.value === 'create new (unsaved)'" (click)="delete()" color="primary"
class="inline-btn">
<mat-icon>delete</mat-icon>
</button>

<button mat-button [disabled]="(selectedPlugin.value !== 'create new (unsaved)') || (disableEditor$ | async)"
(click)="createNewFromTemplate()" color="primary" class="inline-btn">
<mat-icon>insert_drive_file</mat-icon>
</button>


</div>
</section>

Expand All @@ -38,14 +22,50 @@
<mat-progress-bar *ngIf="!!(isLoading$ | async)" style="height: 5px;" mode="indeterminate"></mat-progress-bar>
</div>

<input type="text" formControlName="description" style="border:0" />
<p>{{ form.value.description }}</p>

<mat-card>
<mat-card-content>
<h2>Policy Objective Details</h2>
<table>
<tr>
<td><strong>Description:</strong></td>
<td>{{ form.value.objective?.description }}</td>
</tr>
<tr>
<td><strong>Is Objective Parent:</strong></td>
<td>{{ form.value.objective?.isObjectiveParent ? 'Yes' : 'No' }}</td>
</tr>
<tr>
<td><strong>Is Rule Parent:</strong></td>
<td>{{ form.value.objective?.isRuleParent ? 'Yes' : 'No' }}</td>
</tr>
<tr>
<td><strong>Object Type:</strong></td>
<td>{{ form.value.objective?.objectType }}</td>
</tr>
<tr>
<td><strong>Origin:</strong></td>
<td>{{ form.value.objective?.origin }}</td>
</tr>
</table>
<h3>Parameters:</h3>
<table class="parameters">
<tr>
<th>Description</th>
<th>Value</th>
</tr>
<tr *ngFor="let parameter of form.value.objective?.parameters; let i = index">
<td>{{ parameter?.description }}</td>
<td><pre>{{ parameter?.value | json }}</pre></td>
</tr>
</table>
</mat-card-content>
</mat-card>

<ngx-monaco-editor #editorInstance class="monaco-editor" [options]="editorOptions" (onInit)="onEditorInit($event)"
formControlName="pluginCode" style="min-height: 700px;">
</ngx-monaco-editor>

</form>

<!--
<!--
<pre>{{ form.value | json }}</pre>
-->
-->
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ section {
.action-row {
display: table-cell;
width: 100%;

.inline-btn {
height: 50px;
margin-left: 10px;
}

}
}

.parameters {
margin-top: 20px;
border-collapse: separate;
border-spacing: 10px;
width: 100%;
}
Loading

0 comments on commit 3dcdb5e

Please sign in to comment.