Skip to content

Commit 177c992

Browse files
authored
feat: Validate dataset properties in jobs (#1473)
## Description Allows jobs to validate properties of the dataset. ## Motivation The `validate` action currently allows operators to enforce attributes of the DTO. However, many jobs depend on `jobParams.datasetLists` to link a job to certain datasets. This allows validation of properties on datasets associated with the dataset. The motivating example would be checking datasetLifecycle properties for certain jobs. These are currently hard-coded for special job types. This would allow them to be applied to custom job types as well. ``` configVersion: v1.0 jobs: - jobType: custom_archive create: auth: "#datasetAccess" actions: - actionType: validate datasets: datasetlifecycle.archivable: const: true ``` ## Changes: * Add `datasets` property to validate actions (only in `create` operations) to validate linked dataset properties ## Tests included (WIP pending tests and documentation) - [x] Included for each change/fix? - [x] Passing? <!-- Merge will not be approved unless tests pass --> ## Documentation - [x] swagger documentation updated (required for API changes) - [x] official documentation updated ### official documentation info Docs are included in SciCatProject/documentation#56
2 parents e33eb49 + fe255c7 commit 177c992

File tree

12 files changed

+738
-280
lines changed

12 files changed

+738
-280
lines changed

jobConfig.example.yaml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ configVersion: v1.0 2024-03-01 6f3f38
22
jobs:
33
- jobType: archive
44
create:
5-
auth: "#all"
5+
auth: "#datasetOwner"
66
actions:
7-
- actionType: log
7+
- actionType: validate
8+
datasets:
9+
"datasetlifecycle.archivable":
10+
const: true
811
- actionType: url
912
url: http://localhost:3000/api/v3/health?jobid={{id}}
1013
headers:
@@ -28,6 +31,17 @@ jobs:
2831
exchange: jobs.write
2932
queue: client.jobs.write
3033
key: jobqueue
34+
- jobType: retrieve
35+
create:
36+
auth: "#datasetOwner"
37+
actions:
38+
- actionType: validate
39+
datasets:
40+
"datasetlifecycle.retrievable":
41+
const: true
42+
statusUpdate:
43+
auth: "archivemanager"
44+
actions: []
3145
- jobType: public
3246
create:
3347
auth: "#all"
@@ -39,5 +53,8 @@ jobs:
3953
required:
4054
- pid
4155
- files
56+
datasets:
57+
isPublished:
58+
const: true
4259
statusUpdate:
43-
auth: "#all"
60+
auth: "archivemanager"

src/config/job-config/actions/corejobactioncreators.module.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { actionType as logActionType } from "./logaction/logaction.interface";
77
import { actionType as emailActionType } from "./emailaction/emailaction.interface";
88
import { ValidateJobActionModule } from "./validateaction/validateaction.module";
99
import { actionType as validateActionType } from "./validateaction/validateaction.interface";
10-
import { ValidateJobActionCreator } from "./validateaction/validateaction.service";
10+
import {
11+
ValidateCreateJobActionCreator,
12+
ValidateJobActionCreator,
13+
} from "./validateaction/validateaction.service";
1114
import { URLJobActionModule } from "./urlaction/urlaction.module";
1215
import { URLJobActionCreator } from "./urlaction/urlaction.service";
1316
import { actionType as urlActionType } from "./urlaction/urlaction.interface";
@@ -39,22 +42,22 @@ import {
3942
useFactory: (
4043
logJobActionCreator,
4144
emailJobActionCreator,
42-
validateJobActionCreator,
45+
validateCreateJobActionCreator,
4346
urlJobActionCreator,
4447
rabbitMQJobActionCreator,
4548
) => {
4649
return {
4750
[logActionType]: logJobActionCreator,
4851
[emailActionType]: emailJobActionCreator,
49-
[validateActionType]: validateJobActionCreator,
52+
[validateActionType]: validateCreateJobActionCreator,
5053
[urlActionType]: urlJobActionCreator,
5154
[rabbitmqActionType]: rabbitMQJobActionCreator,
5255
};
5356
},
5457
inject: [
5558
LogJobActionCreator,
5659
EmailJobActionCreator,
57-
ValidateJobActionCreator,
60+
ValidateCreateJobActionCreator,
5861
URLJobActionCreator,
5962
RabbitMQJobActionCreator,
6063
],

src/config/job-config/actions/validateaction/validateaction.interface.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ export const actionType = "validate";
44

55
export interface ValidateJobActionOptions extends JobActionOptions {
66
actionType: typeof actionType;
7-
request: Record<string, unknown>;
7+
request?: Record<string, unknown>;
8+
}
9+
10+
export interface ValidateCreateJobActionOptions
11+
extends ValidateJobActionOptions {
12+
actionType: typeof actionType;
13+
request?: Record<string, unknown>;
14+
datasets?: Record<string, unknown>;
815
}
916

1017
/**
@@ -15,7 +22,27 @@ export function isValidateJobActionOptions(
1522
): options is ValidateJobActionOptions {
1623
if (typeof options === "object" && options !== null) {
1724
const opts = options as ValidateJobActionOptions;
18-
return opts.actionType === actionType && typeof opts.request === "object";
25+
return (
26+
opts.actionType === actionType &&
27+
(opts.request === undefined || typeof opts.request === "object")
28+
);
29+
}
30+
return false;
31+
}
32+
33+
/**
34+
* Type guard for EmailJobActionOptions
35+
*/
36+
export function isValidateCreateJobActionOptions(
37+
options: unknown,
38+
): options is ValidateJobActionOptions {
39+
if (typeof options === "object" && options !== null) {
40+
const opts = options as ValidateCreateJobActionOptions;
41+
return (
42+
opts.actionType === actionType &&
43+
(opts.request === undefined || typeof opts.request === "object") &&
44+
(opts.datasets === undefined || typeof opts.datasets === "object")
45+
);
1946
}
2047
return false;
2148
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { Module } from "@nestjs/common";
2-
import { ValidateJobActionCreator } from "./validateaction.service";
2+
import {
3+
ValidateCreateJobActionCreator,
4+
ValidateJobActionCreator,
5+
} from "./validateaction.service";
36

47
@Module({
5-
providers: [ValidateJobActionCreator],
6-
exports: [ValidateJobActionCreator],
8+
providers: [ValidateJobActionCreator, ValidateCreateJobActionCreator],
9+
exports: [ValidateJobActionCreator, ValidateCreateJobActionCreator],
710
})
811
export class ValidateJobActionModule {}

src/config/job-config/actions/validateaction/validateaction.service.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import {
44
JobActionOptions,
55
JobDto,
66
} from "../../jobconfig.interface";
7-
import { ValidateJobAction } from "./validateaction";
7+
import { ValidateCreateJobAction, ValidateJobAction } from "./validateaction";
88
import { isValidateJobActionOptions } from "./validateaction.interface";
9+
import { DatasetsService } from "src/datasets/datasets.service";
10+
import { CreateJobDto } from "src/jobs/dto/create-job.dto";
11+
import { ModuleRef } from "@nestjs/core";
912

1013
@Injectable()
1114
export class ValidateJobActionCreator implements JobActionCreator<JobDto> {
@@ -20,3 +23,18 @@ export class ValidateJobActionCreator implements JobActionCreator<JobDto> {
2023
return new ValidateJobAction(options);
2124
}
2225
}
26+
27+
@Injectable()
28+
export class ValidateCreateJobActionCreator
29+
implements JobActionCreator<CreateJobDto>
30+
{
31+
private datasetsService: DatasetsService;
32+
constructor(private moduleRef: ModuleRef) {}
33+
34+
public create<Options extends JobActionOptions>(options: Options) {
35+
if (!isValidateJobActionOptions(options)) {
36+
throw new Error("Invalid options for ValidateJobAction.");
37+
}
38+
return new ValidateCreateJobAction(this.moduleRef, options);
39+
}
40+
}

0 commit comments

Comments
 (0)