[backend] replace ruleApply in background task to direct inferred creation (#11626)#11628
[backend] replace ruleApply in background task to direct inferred creation (#11626)#11628JeremyCloarec wants to merge 8 commits intomasterfrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #11628 +/- ##
==========================================
- Coverage 30.86% 30.83% -0.03%
==========================================
Files 2911 2913 +2
Lines 192439 192678 +239
Branches 39244 39244
==========================================
+ Hits 59388 59404 +16
- Misses 133051 133274 +223
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
4ad068a to
54a76cd
Compare
| import type { AuthContext, AuthUser } from '../types/user'; | ||
|
|
||
| export const createInternalInferredRelation = async (context: AuthContext, _user: AuthUser, jsonInput: string) => { | ||
| const { input, ruleContent, opts } = JSON.parse(jsonInput); |
There was a problem hiding this comment.
We should validate that the json is correct for the creation
There was a problem hiding this comment.
Since it's only used internally for now, and since the validation isn't that easy to implement, we'll skip it until it's used externally
dd25eeb to
337210b
Compare
337210b to
013064a
Compare
e4f6040 to
ac88d47
Compare
opencti-platform/opencti-graphql/src/rules/containerWithRefsBuilder.ts
Outdated
Show resolved
Hide resolved
ac88d47 to
4ebdb98
Compare
a40e1ff to
6d4e1ed
Compare
57ac643 to
f3d44de
Compare
| throw ForbiddenAccess(); | ||
| } | ||
| // TODO: JSON input validation? Maybe we don't need it since it's only coming from task manager? | ||
| const { input, ruleContent, opts } = JSON.parse(jsonInput); |
There was a problem hiding this comment.
would it possible to have these structure in the GraphQL schema ? or it's a bad idea ?
There was a problem hiding this comment.
Since it's only used internally for now, and since the validation isn't that easy to implement, we'll skip it until it's used externally
| const applyFromStixRelation = async ( | ||
| context: AuthContext, | ||
| data: StixRelation, | ||
| createInferredRelationCallback?: createInferredRelationCallbackFunction | undefined |
There was a problem hiding this comment.
can be simplified with
createInferredRelationCallback: createInferredRelationCallbackFunction = createInferredRelation
so then createInferredRelationCallback can be directly called
same apply for other methods/rules
but in fact it can be probably resolved at an higher level in rulesApplyHandler
| return applyUpsert(element); | ||
| const insert = async ( | ||
| element: StixRelation, | ||
| _createInferredEntityCallback?: createInferredEntityCallbackFunction | undefined, |
There was a problem hiding this comment.
it look likes we must ignore some parameters in many places, it would be more readable to have an object that contains the different methods
moreover we are replicating the method signature in many places (it was already the case before this change and also apply to other methods like clean & update). It would be more efficient to reuse types, either:
- typing insert :
const insert: RuleRuntime['insert'] = async (element, _createInferredEntityCallback, createInferredRelationCallback) => { - inlining insert in the return so it can be infered by TS:
return {
...def,
insert: async (element, _createInferredEntityCallback, createInferredRelationCallback) => applyUpsert(element, createInferredRelationCallback),
update: async (element) => applyUpsert(element),
clean: async (element: StoreObject, deletedDependencies: Array<string>) => {
await deleteInferredRuleElement(def.id, element, deletedDependencies);
},
};
There was a problem hiding this comment.
To make sure I understand correctly:
In the new approach, bundles are split using RULE_APPLY_MAX_BUNDLE_SIZE. The same logic should also be applied to standardOperationCallback, which currently doesn’t split and creates a single (potentially very large) bundle.
Adding queues introduces an extra step and increases code complexity.
Is this additional complexity intended to take advantage of the worker queues’ consumption regulation?
There was a problem hiding this comment.
standardOperationCallback bundles are already split (at least in query tasks) during the elList with MAX_TASK_ELEMENTS (it can be found in the opts in taskQuery).
As for your question, just to make sure I understand it correctly also: you're asking specifically about the new RULE_APPLY_MAX_BUNDLE_SIZE, and not the overall design of sending inferred objects in the bundle right?
The RULE_APPLY_MAX_BUNDLE_SIZE was used to prevent very large bundle from being sent to the worker, since a single ruleApply call can lead to a very large amount of inferred data. Only sending a bundle at the end of the ruleApply could lead to a bundle having >100k objects, which in theory could be handled by the worker, but it would put unnecessary load on the splitting of the bundle
675b6bc to
70fd15a
Compare
70fd15a to
15665bd
Compare
4da3326 to
e5594e1
Compare
| bundleObject.extensions[STIX_EXT_OCTI] = { | ||
| ...bundleObject.extensions[STIX_EXT_OCTI], | ||
| ...baseOperationBuilder(actionType, operations, element) | ||
| }; |
There was a problem hiding this comment.
It should be removed since it has already been done
54c0d1e to
473bd34
Compare
54fe191 to
6bfd59b
Compare
9f9f285 to
e1a4611
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors the rule application system to send inferred object creation operations directly to workers instead of applying rules in the background task manager. The change enables background tasks to generate inferred entity and relation creation instructions that workers can process asynchronously.
Key changes:
- Rule insert methods now accept callback functions for creating inferred entities/relations
- Background task manager generates inferred creation bundles instead of applying rules directly
- New GraphQL mutations and Python client methods handle inferred object creation
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| SightingObservableRule.ts | Updated insert method signature to accept inferred creation callbacks |
| SightingIndicatorRule.ts | Updated insert method signature to accept inferred creation callbacks |
| SightingIncidentRule.ts | Modified to use callbacks and generate standard IDs for inferred entities |
| relationWithRelationBuilder.ts | Updated insert method to use callback pattern |
| relationToRelationBuilder.ts | Updated insert method to use callback pattern |
| ObserveSightingRule.ts | Updated insert method to use callback pattern |
| ObservableRelatedRule.ts | Updated insert method to use callback pattern |
| LocalizationOfTargetsRule.ts | Updated insert method to use callback pattern |
| IndicateSightedRule.ts | Updated insert method to use callback pattern |
| containerWithRefsBuilder.ts | Updated to use callbacks and refactored bundle element building |
| inferredObject.ts | New domain file with inferred creation methods |
| inferredObjectResolvers | New resolver for inferred object mutations |
| taskManager.js | Added ruleApplyCallback to generate inferred creation bundles |
| ruleManager.ts | Updated to accept callback functions throughout rule processing |
| opencti.graphql | Added inferredRelationAdd and inferredEntityAdd mutations |
| relay.schema.graphql | Added inferredRelationAdd and inferredEntityAdd mutations |
| opencti_stix2.py | Added handling for inferred_entity and inferred_rel operations |
| opencti_api_inferred.py | New Python API client for inferred object creation |
| opencti_api_client.py | Integrated OpenCTIApiInferred into client |
1c222ef to
2cb4539
Compare
Proposed changes
Related issues
Checklist
Further comments