From bb4423d5ace49c82ea42727ee71373f3473c167e Mon Sep 17 00:00:00 2001
From: stevereis <stevereis93@gmail.com>
Date: Fri, 1 Oct 2021 16:00:07 +0200
Subject: [PATCH] WIP: adding experiment (non transient) to graphql

---
 .../connectors/datashield/main.connector.ts   |  6 +---
 .../engine/connectors/exareme/converters.ts   | 15 ++++++---
 .../connectors/exareme/main.connector.ts      | 22 +++++--------
 api/src/engine/engine.interfaces.ts           |  5 +--
 api/src/engine/engine.resolver.ts             |  7 +++--
 .../experiment/algorithm-parameter.model.ts   | 10 ++++++
 .../models/experiment/algorithm.model.ts      | 14 +++++++++
 .../models/experiment/experiment.model.ts     | 31 +++++++++++++++++--
 .../experiment/input/algorithm.input.ts       |  2 +-
 .../input/experiment-create.input.ts          |  3 ++
 api/src/schema.gql                            | 24 ++++++++++++--
 11 files changed, 102 insertions(+), 37 deletions(-)
 create mode 100644 api/src/engine/models/experiment/algorithm-parameter.model.ts
 create mode 100644 api/src/engine/models/experiment/algorithm.model.ts

diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts
index 34cc6ae..4ee4587 100644
--- a/api/src/engine/connectors/datashield/main.connector.ts
+++ b/api/src/engine/connectors/datashield/main.connector.ts
@@ -10,11 +10,7 @@ export default class DataShieldService implements IEngineService {
   ): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
   }
-  createTransient(
-    data: ExperimentCreateInput,
-  ): Experiment | Promise<Experiment> {
-    throw new Error('Method not implemented.');
-  }
+
   getDomains(): Domain[] {
     throw new Error('Method not implemented.');
   }
diff --git a/api/src/engine/connectors/exareme/converters.ts b/api/src/engine/connectors/exareme/converters.ts
index 8520cde..c5ecdfc 100644
--- a/api/src/engine/connectors/exareme/converters.ts
+++ b/api/src/engine/connectors/exareme/converters.ts
@@ -1,6 +1,6 @@
 import { Category } from 'src/engine/models/category.model';
 import { Experiment } from 'src/engine/models/experiment/experiment.model';
-import { AlgorithmParamInput } from 'src/engine/models/experiment/input/algorithm-parameter.input';
+import { AlgorithmParameter } from 'src/engine/models/experiment/algorithm-parameter.model';
 import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
 import { Group } from 'src/engine/models/group.model';
 import { TableResult } from 'src/engine/models/result/table-result.model';
@@ -40,7 +40,7 @@ export const dataToVariable = (data: VariableEntity): Variable => {
   };
 };
 
-const algoParamInputToData = (param: AlgorithmParamInput) => {
+const algoParamInputToData = (param: AlgorithmParameter) => {
   return {
     name: param.name,
     value: param.value.join(','),
@@ -63,6 +63,10 @@ export const experimentInputToData = (data: ExperimentCreateInput) => {
           name: 'pathology',
           value: data.domain,
         },
+        {
+          name: 'y',
+          value: data.variables.join(','),
+        },
       ].concat(data.algorithm.parameters.map(algoParamInputToData)),
       type: data.algorithm.type ?? 'string',
       name: data.algorithm.name,
@@ -71,11 +75,14 @@ export const experimentInputToData = (data: ExperimentCreateInput) => {
   };
 };
 
-export const dataToTransient = (data: TransientDataResult): Experiment => {
+export const dataToTransient = (
+  input: ExperimentCreateInput,
+  data: TransientDataResult,
+): Experiment => {
   const tabs: TableResult[] = transientToTable.evaluate(data);
 
   return {
-    title: data.name,
+    ...input,
     results: tabs,
   };
 };
diff --git a/api/src/engine/connectors/exareme/main.connector.ts b/api/src/engine/connectors/exareme/main.connector.ts
index 8e549b4..4b06e93 100644
--- a/api/src/engine/connectors/exareme/main.connector.ts
+++ b/api/src/engine/connectors/exareme/main.connector.ts
@@ -24,28 +24,20 @@ export default class ExaremeService implements IEngineService {
     private readonly options: IEngineOptions,
     private readonly httpService: HttpService,
   ) {}
-  async createExperiment(data: ExperimentCreateInput): Promise<Experiment> {
+  async createExperiment(
+    data: ExperimentCreateInput,
+    isTransient = false,
+  ): Promise<Experiment> {
     const form = experimentInputToData(data);
 
-    const path = this.options.baseurl + 'experiments';
-
-    const resultAPI = await firstValueFrom(
-      this.httpService.post<TransientDataResult>(path, form),
-    );
-
-    return dataToTransient(resultAPI.data);
-  }
-
-  async createTransient(data: ExperimentCreateInput): Promise<Experiment> {
-    const form = experimentInputToData(data);
-
-    const path = this.options.baseurl + 'experiments/transient';
+    const path =
+      this.options.baseurl + `experiments${isTransient ? '/transient' : ''}`;
 
     const resultAPI = await firstValueFrom(
       this.httpService.post<TransientDataResult>(path, form),
     );
 
-    return dataToTransient(resultAPI.data);
+    return dataToTransient(data, resultAPI.data);
   }
 
   async getDomains(ids: string[]): Promise<Domain[]> {
diff --git a/api/src/engine/engine.interfaces.ts b/api/src/engine/engine.interfaces.ts
index 7539024..0fcf9f1 100644
--- a/api/src/engine/engine.interfaces.ts
+++ b/api/src/engine/engine.interfaces.ts
@@ -13,12 +13,9 @@ export interface IEngineService {
   //GraphQL
   getDomains(ids: string[]): Domain[] | Promise<Domain[]>;
 
-  createTransient(
-    data: ExperimentCreateInput,
-  ): Promise<Experiment> | Experiment;
-
   createExperiment(
     data: ExperimentCreateInput,
+    isTransient: boolean,
   ): Promise<Experiment> | Experiment;
 
   // Standard REST API call
diff --git a/api/src/engine/engine.resolver.ts b/api/src/engine/engine.resolver.ts
index 6432cd1..fba8296 100644
--- a/api/src/engine/engine.resolver.ts
+++ b/api/src/engine/engine.resolver.ts
@@ -26,8 +26,9 @@ export class EngineResolver {
     @Args('transient', { nullable: true, defaultValue: false })
     isTransient: boolean,
   ) {
-    return isTransient
-      ? this.engineService.createTransient(experimentCreateInput)
-      : this.engineService.createExperiment(experimentCreateInput);
+    return this.engineService.createExperiment(
+      experimentCreateInput,
+      isTransient,
+    );
   }
 }
diff --git a/api/src/engine/models/experiment/algorithm-parameter.model.ts b/api/src/engine/models/experiment/algorithm-parameter.model.ts
new file mode 100644
index 0000000..79666de
--- /dev/null
+++ b/api/src/engine/models/experiment/algorithm-parameter.model.ts
@@ -0,0 +1,10 @@
+import { Field, ObjectType } from '@nestjs/graphql';
+
+@ObjectType()
+export class AlgorithmParameter {
+  @Field()
+  name: string;
+
+  @Field(() => [String])
+  value: string[];
+}
diff --git a/api/src/engine/models/experiment/algorithm.model.ts b/api/src/engine/models/experiment/algorithm.model.ts
new file mode 100644
index 0000000..30087c5
--- /dev/null
+++ b/api/src/engine/models/experiment/algorithm.model.ts
@@ -0,0 +1,14 @@
+import { Field, ObjectType } from '@nestjs/graphql';
+import { AlgorithmParameter } from './algorithm-parameter.model';
+
+@ObjectType()
+export class Algorithm {
+  @Field()
+  name: string;
+
+  @Field(() => [AlgorithmParameter], { nullable: true, defaultValue: [] })
+  parameters: AlgorithmParameter[];
+
+  @Field()
+  type: string;
+}
diff --git a/api/src/engine/models/experiment/experiment.model.ts b/api/src/engine/models/experiment/experiment.model.ts
index 4e7abae..d11abde 100644
--- a/api/src/engine/models/experiment/experiment.model.ts
+++ b/api/src/engine/models/experiment/experiment.model.ts
@@ -6,6 +6,7 @@ import {
 } from '@nestjs/graphql';
 import { DummyResult } from '../result/dummy-result.model';
 import { TableResult } from '../result/table-result.model';
+import { Algorithm } from './algorithm.model';
 
 export const ResultUnion = createUnionType({
   name: 'ResultUnion',
@@ -24,9 +25,6 @@ export const ResultUnion = createUnionType({
 
 @ObjectType()
 export class Experiment {
-  @Field()
-  title: string;
-
   @Field({ nullable: true })
   uuid?: string;
 
@@ -39,6 +37,33 @@ export class Experiment {
   @Field(() => GraphQLISODateTime, { nullable: true })
   finished_at?: Date;
 
+  @Field({ defaultValue: false })
+  viewed?: boolean;
+
+  @Field({ nullable: true })
+  status?: string;
+
+  @Field({ defaultValue: false })
+  shared?: boolean;
+
   @Field(() => [ResultUnion])
   results: Array<typeof ResultUnion>;
+
+  @Field(() => [String])
+  datasets: string[];
+
+  @Field(() => String, { nullable: true })
+  filter: string;
+
+  @Field()
+  domain: string;
+
+  @Field(() => [String])
+  variables: string[];
+
+  @Field()
+  algorithm: Algorithm;
+
+  @Field()
+  name: string;
 }
diff --git a/api/src/engine/models/experiment/input/algorithm.input.ts b/api/src/engine/models/experiment/input/algorithm.input.ts
index d435595..54d26b7 100644
--- a/api/src/engine/models/experiment/input/algorithm.input.ts
+++ b/api/src/engine/models/experiment/input/algorithm.input.ts
@@ -6,7 +6,7 @@ export class AlgorithmInput {
   @Field()
   name: string;
 
-  @Field(() => [AlgorithmParamInput])
+  @Field(() => [AlgorithmParamInput], { nullable: true, defaultValue: [] })
   parameters: AlgorithmParamInput[];
 
   @Field()
diff --git a/api/src/engine/models/experiment/input/experiment-create.input.ts b/api/src/engine/models/experiment/input/experiment-create.input.ts
index 746e0f5..85a5404 100644
--- a/api/src/engine/models/experiment/input/experiment-create.input.ts
+++ b/api/src/engine/models/experiment/input/experiment-create.input.ts
@@ -12,6 +12,9 @@ export class ExperimentCreateInput {
   @Field()
   domain: string;
 
+  @Field(() => [String])
+  variables: string[];
+
   @Field()
   algorithm: AlgorithmInput;
 
diff --git a/api/src/schema.gql b/api/src/schema.gql
index bb7d32c..9b71c50 100644
--- a/api/src/schema.gql
+++ b/api/src/schema.gql
@@ -39,13 +39,32 @@ type Header {
   type: String!
 }
 
+type AlgorithmParameter {
+  name: String!
+  value: [String!]!
+}
+
+type Algorithm {
+  name: String!
+  parameters: [AlgorithmParameter!]
+  type: String!
+}
+
 type Experiment {
-  title: String!
   uuid: String
   created_at: DateTime
   update_at: DateTime
   finished_at: DateTime
+  viewed: Boolean!
+  status: String
+  shared: Boolean!
   results: [ResultUnion!]!
+  datasets: [String!]!
+  filter: String
+  domain: String!
+  variables: [String!]!
+  algorithm: Algorithm!
+  name: String!
 }
 
 """
@@ -81,13 +100,14 @@ input ExperimentCreateInput {
   datasets: [String!]!
   filter: String
   domain: String!
+  variables: [String!]!
   algorithm: AlgorithmInput!
   name: String!
 }
 
 input AlgorithmInput {
   name: String!
-  parameters: [AlgorithmParamInput!]!
+  parameters: [AlgorithmParamInput!] = []
   type: String!
 }
 
-- 
GitLab