Newer
Older
import { HttpService } from '@nestjs/axios';
import { firstValueFrom, map, Observable } from 'rxjs';
import { ENGINE_MODULE_OPTIONS } from 'src/engine/engine.constants';
import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces';
import { Domain } from 'src/engine/models/domain.model';
import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
import {
Experiment,
PartialExperiment,
} from 'src/engine/models/experiment/experiment.model';
import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
import { ExperimentEditInput } from 'src/engine/models/experiment/input/experiment-edit.input';
import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model';
import { Group } from 'src/engine/models/group.model';
import { Variable } from 'src/engine/models/variable.model';
import { ExperimentData } from './interfaces/experiment/experiment.interface';
import { ExperimentsData } from './interfaces/experiment/experiments.interface';
import { Hierarchy } from './interfaces/hierarchy.interface';
import { Pathology } from './interfaces/pathology.interface';
export default class ExaremeService implements IEngineService {
@Inject(ENGINE_MODULE_OPTIONS) private readonly options: IEngineOptions,
private readonly httpService: HttpService,
@Inject(REQUEST) private readonly req: Request, //TODO: remove inject, set request from manually take care of graphql request
) {
const gqlRequest = req['req']; // graphql headers exception
this.headers =
gqlRequest && gqlRequest instanceof IncomingMessage
? gqlRequest.headers
: req.headers;
}
await firstValueFrom(this.httpService.get(path, { headers: this.headers }));
async createExperiment(
data: ExperimentCreateInput,
isTransient = false,
): Promise<Experiment> {
const form = experimentInputToData(data);
const path =
this.options.baseurl + `experiments${isTransient ? '/transient' : ''}`;
const resultAPI = await firstValueFrom(
this.httpService.post<ExperimentData>(path, form, {
);
return dataToExperiment(resultAPI.data);
}
async listExperiments(page: number, name: string): Promise<ListExperiments> {
const path = this.options.baseurl + 'experiments';
const resultAPI = await firstValueFrom(
this.httpService.get<ExperimentsData>(path, {
params: { page, name },
);
return {
...resultAPI.data,
experiments: resultAPI.data.experiments?.map(dataToExperiment) ?? [],
async getAlgorithms(): Promise<Algorithm[]> {
const path = this.options.baseurl + 'algorithms';
const resultAPI = await firstValueFrom(
this.httpService.get<string>(path, {
return dataToAlgorithms(resultAPI.data);
}
async getExperiment(id: string): Promise<Experiment> {
const path = this.options.baseurl + `experiments/${id}`;
const resultAPI = await firstValueFrom(
this.httpService.get<ExperimentData>(path, {
return dataToExperiment(resultAPI.data);
}
async editExperient(
expriment: ExperimentEditInput,
): Promise<Experiment> {
const path = this.options.baseurl + `experiments/${id}`;
const resultAPI = await firstValueFrom(
this.httpService.patch<ExperimentData>(path, expriment, {
);
return dataToExperiment(resultAPI.data);
}
async removeExperiment(id: string): Promise<PartialExperiment> {
const path = this.options.baseurl + `experiments/${id}`;
await firstValueFrom(
this.httpService.delete(path, {
throw new BadRequestException(`${id} does not exists`);
async getDomains(ids: string[]): Promise<Domain[]> {
const path = this.options.baseurl + 'pathologies';
try {
const data = await firstValueFrom(
this.httpService.get<Pathology[]>(path, {
return (
data?.data
.filter((data) => !ids || ids.length == 0 || ids.includes(data.code))
.map((data): Domain => {
const groups = this.flattenGroups(data.metadataHierarchy);
return {
id: data.code,
label: data.label,
groups: groups,
rootGroup: dataToGroup(data.metadataHierarchy),
datasets: data.datasets ? data.datasets.map(dataToDataset) : [],
variables: data.metadataHierarchy
? this.flattenVariables(data.metadataHierarchy, groups)
: [],
};
}) ?? []
);
} catch (error) {
`Error in exareme engine : '${error.response.data['message']}'`,
error.response.data['statusCode'] ?? HttpStatus.INTERNAL_SERVER_ERROR,
getActiveUser(): Observable<string> {
const path = this.options.baseurl + 'activeUser';
return this.httpService
.get<string>(path, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
}
editActiveUser(): Observable<string> {
const path = this.options.baseurl + 'activeUser/agreeNDA';
return this.httpService
.post<string>(path, this.req.body, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
}
getExperimentREST(id: string): Observable<string> {
const path = this.options.baseurl + `experiments/${id}`;
.get<string>(path, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
}
deleteExperiment(id: string): Observable<string> {
const path = this.options.baseurl + `experiments/${id}`;
return this.httpService
.delete(path, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
editExperimentREST(id: string): Observable<string> {
const path = this.options.baseurl + `experiments/${id}`;
.patch(path, this.req.body, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
}
startExperimentTransient(): Observable<string> {
const path = this.options.baseurl + 'experiments/transient';
return this.httpService
.post(path, this.req.body, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
}
startExperiment(): Observable<string> {
const path = this.options.baseurl + 'experiments';
return this.httpService
.post(path, this.req.body, {
headers: this.req.headers,
})
.pipe(map((response) => response.data));
}
getExperiments(): Observable<string> {
const path = this.options.baseurl + 'experiments';
return this.httpService
.get<string>(path, { params: this.req.query, headers: this.headers })
.pipe(map((response) => response.data));
}
getAlgorithmsREST(): Observable<string> {
const path = this.options.baseurl + 'algorithms';
return this.httpService
.get<string>(path, { params: this.req.query, headers: this.headers })
.pipe(map((response) => response.data));
}
getPassthrough(suffix: string): string | Observable<string> {
const path = this.options.baseurl + suffix;
return this.httpService
.get<string>(path, { params: this.req.query, headers: this.headers })
.pipe(map((response) => response.data));
}
private flattenGroups = (data: Hierarchy): Group[] => {
let groups: Group[] = [dataToGroup(data)];
if (data.groups) {
groups = groups.concat(data.groups.flatMap(this.flattenGroups));
}
private flattenVariables = (data: Hierarchy, groups: Group[]): Variable[] => {
const group = groups.find((group) => group.id == data.code);
let variables = data.variables ? data.variables.map(dataToVariable) : [];
variables.forEach((variable) => (variable.groups = group ? [group] : []));
if (data.groups) {
variables = variables.concat(
data.groups.flatMap((hierarchy) =>
this.flattenVariables(hierarchy, groups),
),
);
}