From 6840f87cf8673ecafae6ca11fdd174076813e5f2 Mon Sep 17 00:00:00 2001 From: Jeremy Cloarec Date: Fri, 29 Nov 2024 19:45:15 +0100 Subject: [PATCH] [backend] add cache status --- .../src/schema/relay.schema.graphql | 7 +++++++ .../opencti-graphql/src/generated/graphql.ts | 19 +++++++++++++++++++ .../exclusionList/exclusionList-domain.ts | 17 ++++++++++++++++- .../exclusionList/exclusionList-resolver.ts | 3 ++- .../exclusionList/exclusionList.graphql | 6 +++--- 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/opencti-platform/opencti-front/src/schema/relay.schema.graphql b/opencti-platform/opencti-front/src/schema/relay.schema.graphql index bb7c48910c62..a23a823b9248 100644 --- a/opencti-platform/opencti-front/src/schema/relay.schema.graphql +++ b/opencti-platform/opencti-front/src/schema/relay.schema.graphql @@ -8138,6 +8138,7 @@ type Query { supportPackages(first: Int, after: ID, orderBy: SupportPackageOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): SupportPackageConnection exclusionList(id: String!): ExclusionList exclusionLists(first: Int, after: ID, orderBy: ExclusionListOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): ExclusionListConnection + exclusionListCacheStatus: ExclusionListCacheStatus draftWorkspace(id: String!): DraftWorkspace draftWorkspaces(first: Int, after: ID, orderBy: DraftWorkspacesOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): DraftWorkspaceConnection draftWorkspaceEntities(draftId: String!, types: [String], first: Int, after: ID, orderBy: StixCoreObjectsOrdering, orderMode: OrderingMode, filters: FilterGroup, search: String): StixCoreObjectConnection @@ -12327,6 +12328,12 @@ type ExclusionListEdge { node: ExclusionList! } +type ExclusionListCacheStatus { + refreshAskDate: String! + cacheDate: String! + allNodeCacheUpdated: Boolean! +} + enum ExclusionListOrdering { name created_at diff --git a/opencti-platform/opencti-graphql/src/generated/graphql.ts b/opencti-platform/opencti-graphql/src/generated/graphql.ts index 1b354dcc4d25..fae54aa9c8cd 100644 --- a/opencti-platform/opencti-graphql/src/generated/graphql.ts +++ b/opencti-platform/opencti-graphql/src/generated/graphql.ts @@ -7502,6 +7502,13 @@ export type ExclusionList = BasicObject & InternalObject & { standard_id: Scalars['String']['output']; }; +export type ExclusionListCacheStatus = { + __typename?: 'ExclusionListCacheStatus'; + allNodeCacheUpdated: Scalars['Boolean']['output']; + cacheDate: Scalars['String']['output']; + refreshAskDate: Scalars['String']['output']; +}; + export type ExclusionListConnection = { __typename?: 'ExclusionListConnection'; edges?: Maybe>; @@ -19333,6 +19340,7 @@ export type Query = { event?: Maybe; events?: Maybe; exclusionList?: Maybe; + exclusionListCacheStatus?: Maybe; exclusionLists?: Maybe; externalReference?: Maybe; externalReferences?: Maybe; @@ -30961,6 +30969,7 @@ export type ResolversTypes = ResolversObject<{ EventEdge: ResolverTypeWrapper & { node: ResolversTypes['Event'] }>; EventsOrdering: EventsOrdering; ExclusionList: ResolverTypeWrapper; + ExclusionListCacheStatus: ResolverTypeWrapper; ExclusionListConnection: ResolverTypeWrapper & { edges?: Maybe> }>; ExclusionListContentAddInput: ExclusionListContentAddInput; ExclusionListEdge: ResolverTypeWrapper & { node: ResolversTypes['ExclusionList'] }>; @@ -31779,6 +31788,7 @@ export type ResolversParentTypes = ResolversObject<{ EventConnection: Omit & { edges?: Maybe>> }; EventEdge: Omit & { node: ResolversParentTypes['Event'] }; ExclusionList: BasicStoreEntityExclusionList; + ExclusionListCacheStatus: ExclusionListCacheStatus; ExclusionListConnection: Omit & { edges?: Maybe> }; ExclusionListContentAddInput: ExclusionListContentAddInput; ExclusionListEdge: Omit & { node: ResolversParentTypes['ExclusionList'] }; @@ -34783,6 +34793,13 @@ export type ExclusionListResolvers; }>; +export type ExclusionListCacheStatusResolvers = ResolversObject<{ + allNodeCacheUpdated?: Resolver; + cacheDate?: Resolver; + refreshAskDate?: Resolver; + __isTypeOf?: IsTypeOfResolverFn; +}>; + export type ExclusionListConnectionResolvers = ResolversObject<{ edges?: Resolver>, ParentType, ContextType>; pageInfo?: Resolver; @@ -38393,6 +38410,7 @@ export type QueryResolvers, ParentType, ContextType, RequireFields>; events?: Resolver, ParentType, ContextType, Partial>; exclusionList?: Resolver, ParentType, ContextType, RequireFields>; + exclusionListCacheStatus?: Resolver, ParentType, ContextType>; exclusionLists?: Resolver, ParentType, ContextType, Partial>; externalReference?: Resolver, ParentType, ContextType, RequireFields>; externalReferences?: Resolver, ParentType, ContextType, Partial>; @@ -41735,6 +41753,7 @@ export type Resolvers = ResolversObject<{ EventConnection?: EventConnectionResolvers; EventEdge?: EventEdgeResolvers; ExclusionList?: ExclusionListResolvers; + ExclusionListCacheStatus?: ExclusionListCacheStatusResolvers; ExclusionListConnection?: ExclusionListConnectionResolvers; ExclusionListEdge?: ExclusionListEdgeResolvers; ExternalReference?: ExternalReferenceResolvers; diff --git a/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-domain.ts b/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-domain.ts index cccb2174349b..5704a589e7ae 100644 --- a/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-domain.ts +++ b/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-domain.ts @@ -7,7 +7,7 @@ import { listEntitiesPaginated, storeLoadById } from '../../database/middleware- import type { AuthContext, AuthUser } from '../../types/user'; import { type BasicStoreEntityExclusionList, ENTITY_TYPE_EXCLUSION_LIST, type StoreEntityExclusionList } from './exclusionList-types'; import { type ExclusionListContentAddInput, type ExclusionListFileAddInput, type MutationExclusionListFieldPatchArgs, type QueryExclusionListsArgs } from '../../generated/graphql'; -import { notify, redisUpdateExclusionListStatus } from '../../database/redis'; +import { getClusterInstances, notify, redisGetExclusionListStatus, redisUpdateExclusionListStatus } from '../../database/redis'; import { FunctionalError } from '../../config/errors'; import { updateAttribute } from '../../database/middleware'; import { publishUserAction } from '../../listener/UserActionListener'; @@ -25,6 +25,21 @@ export const findAll = (context: AuthContext, user: AuthUser, args: QueryExclusi return listEntitiesPaginated(context, user, [ENTITY_TYPE_EXCLUSION_LIST], args); }; +export const getCacheStatus = async () => { + const redisCacheStatus = await redisGetExclusionListStatus(); + const refreshAskDate = redisCacheStatus.last_refresh_ask_date ?? ''; + const cacheDate = redisCacheStatus.last_cache_date ?? ''; + const clusterConfig = await getClusterInstances(); + const allNodeIds = clusterConfig.map((c) => c.platform_id.split(':')[2]); + let allNodeCacheUpdated = refreshAskDate === cacheDate; + for (let i = 0; i < allNodeIds.length; i += 1) { + const nodeId = allNodeIds[i]; + allNodeCacheUpdated = allNodeCacheUpdated && refreshAskDate === redisCacheStatus[nodeId]; + } + + return { refreshAskDate, cacheDate, allNodeCacheUpdated }; +}; + const refreshExclusionListStatus = async () => { await redisUpdateExclusionListStatus({ last_refresh_ask_date: (new Date()).toString() }); }; diff --git a/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-resolver.ts b/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-resolver.ts index 170eb4b17c1f..36070e5b633d 100644 --- a/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-resolver.ts +++ b/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList-resolver.ts @@ -1,10 +1,11 @@ import type { Resolvers } from '../../generated/graphql'; -import { findById, findAll, addExclusionListContent, addExclusionListFile, deleteExclusionList, fieldPatchExclusionList } from './exclusionList-domain'; +import { findById, findAll, addExclusionListContent, addExclusionListFile, deleteExclusionList, fieldPatchExclusionList, getCacheStatus } from './exclusionList-domain'; const exclusionListResolver: Resolvers = { Query: { exclusionList: (_, { id }, context) => findById(context, context.user, id), exclusionLists: (_, args, context) => findAll(context, context.user, args), + exclusionListCacheStatus: () => getCacheStatus(), }, Mutation: { exclusionListContentAdd: (_, { input }, context) => { diff --git a/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList.graphql b/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList.graphql index 0f0f8097bd3f..553d923a8deb 100644 --- a/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList.graphql +++ b/opencti-platform/opencti-graphql/src/modules/exclusionList/exclusionList.graphql @@ -22,8 +22,8 @@ type ExclusionListEdge { } type ExclusionListCacheStatus { - refreshAskDate: DateTime! - cacheDate: DateTime! + refreshAskDate: String! + cacheDate: String! allNodeCacheUpdated: Boolean! } @@ -58,7 +58,7 @@ type Query { filters: FilterGroup search: String ): ExclusionListConnection @auth(for: [SETTINGS_SETCUSTOMIZATION]) - exclusionListCacheStatus(): + exclusionListCacheStatus: ExclusionListCacheStatus @auth(for: [SETTINGS_SETCUSTOMIZATION]) } type Mutation {