Container.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. import { ControllerContainer, ControllerContainerInterface, MapperInterface } from '@standardnotes/domain-core'
  2. import { Container, interfaces } from 'inversify'
  3. import { MongoRepository, Repository } from 'typeorm'
  4. import * as winston from 'winston'
  5. import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns'
  6. import { Revision } from '../Domain/Revision/Revision'
  7. import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
  8. import { RevisionRepositoryInterface } from '../Domain/Revision/RevisionRepositoryInterface'
  9. import { SQLLegacyRevisionRepository } from '../Infra/TypeORM/SQL/SQLLegacyRevisionRepository'
  10. import { SQLLegacyRevision } from '../Infra/TypeORM/SQL/SQLLegacyRevision'
  11. import { AppDataSource } from './DataSource'
  12. import { Env } from './Env'
  13. import TYPES from './Types'
  14. import { TokenDecoderInterface, CrossServiceTokenData, TokenDecoder } from '@standardnotes/security'
  15. import { TimerInterface, Timer } from '@standardnotes/time'
  16. import { ApiGatewayAuthMiddleware } from '../Infra/InversifyExpress/Middleware/ApiGatewayAuthMiddleware'
  17. import { DeleteRevision } from '../Domain/UseCase/DeleteRevision/DeleteRevision'
  18. import { GetRequiredRoleToViewRevision } from '../Domain/UseCase/GetRequiredRoleToViewRevision/GetRequiredRoleToViewRevision'
  19. import { GetRevision } from '../Domain/UseCase/GetRevision/GetRevision'
  20. import { GetRevisionsMetada } from '../Domain/UseCase/GetRevisionsMetada/GetRevisionsMetada'
  21. import { RevisionMetadataHttpMapper } from '../Mapping/Http/RevisionMetadataHttpMapper'
  22. import { S3Client } from '@aws-sdk/client-s3'
  23. import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
  24. import {
  25. DomainEventMessageHandlerInterface,
  26. DomainEventHandlerInterface,
  27. DomainEventSubscriberFactoryInterface,
  28. DomainEventPublisherInterface,
  29. } from '@standardnotes/domain-events'
  30. import {
  31. SQSNewRelicEventMessageHandler,
  32. SQSEventMessageHandler,
  33. SQSDomainEventSubscriberFactory,
  34. DirectCallEventMessageHandler,
  35. DirectCallDomainEventPublisher,
  36. SNSDomainEventPublisher,
  37. } from '@standardnotes/domain-events-infra'
  38. import { DumpRepositoryInterface } from '../Domain/Dump/DumpRepositoryInterface'
  39. import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
  40. import { ItemDumpedEventHandler } from '../Domain/Handler/ItemDumpedEventHandler'
  41. import { RevisionsCopyRequestedEventHandler } from '../Domain/Handler/RevisionsCopyRequestedEventHandler'
  42. import { CopyRevisions } from '../Domain/UseCase/CopyRevisions/CopyRevisions'
  43. import { FSDumpRepository } from '../Infra/FS/FSDumpRepository'
  44. import { S3DumpRepository } from '../Infra/S3/S3ItemDumpRepository'
  45. import { RevisionItemStringMapper } from '../Mapping/Backup/RevisionItemStringMapper'
  46. import { BaseRevisionsController } from '../Infra/InversifyExpress/Base/BaseRevisionsController'
  47. import { Transform } from 'stream'
  48. import { MongoDBRevision } from '../Infra/TypeORM/MongoDB/MongoDBRevision'
  49. import { MongoDBRevisionRepository } from '../Infra/TypeORM/MongoDB/MongoDBRevisionRepository'
  50. import { SQLLegacyRevisionMetadataPersistenceMapper } from '../Mapping/Persistence/SQL/SQLLegacyRevisionMetadataPersistenceMapper'
  51. import { SQLLegacyRevisionPersistenceMapper } from '../Mapping/Persistence/SQL/SQLLegacyRevisionPersistenceMapper'
  52. import { MongoDBRevisionMetadataPersistenceMapper } from '../Mapping/Persistence/MongoDB/MongoDBRevisionMetadataPersistenceMapper'
  53. import { MongoDBRevisionPersistenceMapper } from '../Mapping/Persistence/MongoDB/MongoDBRevisionPersistenceMapper'
  54. import { RevisionHttpMapper } from '../Mapping/Http/RevisionHttpMapper'
  55. import { RevisionRepositoryResolverInterface } from '../Domain/Revision/RevisionRepositoryResolverInterface'
  56. import { TypeORMRevisionRepositoryResolver } from '../Infra/TypeORM/TypeORMRevisionRepositoryResolver'
  57. import { RevisionMetadataHttpRepresentation } from '../Mapping/Http/RevisionMetadataHttpRepresentation'
  58. import { RevisionHttpRepresentation } from '../Mapping/Http/RevisionHttpRepresentation'
  59. import { TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser } from '../Domain/UseCase/Transition/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser/TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser'
  60. import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
  61. import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
  62. import { TransitionStatusUpdatedEventHandler } from '../Domain/Handler/TransitionStatusUpdatedEventHandler'
  63. import { TriggerTransitionFromPrimaryToSecondaryDatabaseForUser } from '../Domain/UseCase/Transition/TriggerTransitionFromPrimaryToSecondaryDatabaseForUser/TriggerTransitionFromPrimaryToSecondaryDatabaseForUser'
  64. import { SQLRevision } from '../Infra/TypeORM/SQL/SQLRevision'
  65. import { SQLRevisionRepository } from '../Infra/TypeORM/SQL/SQLRevisionRepository'
  66. import { SQLRevisionMetadataPersistenceMapper } from '../Mapping/Persistence/SQL/SQLRevisionMetadataPersistenceMapper'
  67. import { SQLRevisionPersistenceMapper } from '../Mapping/Persistence/SQL/SQLRevisionPersistenceMapper'
  68. import { RemoveRevisionsFromSharedVault } from '../Domain/UseCase/RemoveRevisionsFromSharedVault/RemoveRevisionsFromSharedVault'
  69. import { ItemRemovedFromSharedVaultEventHandler } from '../Domain/Handler/ItemRemovedFromSharedVaultEventHandler'
  70. export class ContainerConfigLoader {
  71. async load(configuration?: {
  72. controllerConatiner?: ControllerContainerInterface
  73. directCallDomainEventPublisher?: DirectCallDomainEventPublisher
  74. logger?: Transform
  75. environmentOverrides?: { [name: string]: string }
  76. }): Promise<Container> {
  77. const directCallDomainEventPublisher =
  78. configuration?.directCallDomainEventPublisher ?? new DirectCallDomainEventPublisher()
  79. const env: Env = new Env(configuration?.environmentOverrides)
  80. env.load()
  81. const isConfiguredForHomeServer = env.get('MODE', true) === 'home-server'
  82. const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted'
  83. const isConfiguredForHomeServerOrSelfHosting = isConfiguredForHomeServer || isConfiguredForSelfHosting
  84. const isSecondaryDatabaseEnabled = env.get('SECONDARY_DB_ENABLED', true) === 'true'
  85. const container = new Container({
  86. defaultScope: 'Singleton',
  87. })
  88. let logger: winston.Logger
  89. if (configuration?.logger) {
  90. logger = configuration.logger as winston.Logger
  91. } else {
  92. const winstonFormatters = [winston.format.splat(), winston.format.json()]
  93. if (env.get('NEW_RELIC_ENABLED', true) === 'true') {
  94. await import('newrelic')
  95. // eslint-disable-next-line @typescript-eslint/no-var-requires
  96. const newrelicFormatter = require('@newrelic/winston-enricher')
  97. const newrelicWinstonFormatter = newrelicFormatter(winston)
  98. winstonFormatters.push(newrelicWinstonFormatter())
  99. }
  100. logger = winston.createLogger({
  101. level: env.get('LOG_LEVEL', true) || 'info',
  102. format: winston.format.combine(...winstonFormatters),
  103. transports: [new winston.transports.Console({ level: env.get('LOG_LEVEL', true) || 'info' })],
  104. defaultMeta: { service: 'revisions' },
  105. })
  106. }
  107. container.bind<winston.Logger>(TYPES.Revisions_Logger).toConstantValue(logger)
  108. container.bind<TimerInterface>(TYPES.Revisions_Timer).toDynamicValue(() => new Timer())
  109. const appDataSource = new AppDataSource(env)
  110. await appDataSource.initialize()
  111. logger.debug('Database initialized')
  112. container.bind<Env>(TYPES.Revisions_Env).toConstantValue(env)
  113. container.bind(TYPES.Revisions_NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
  114. container.bind(TYPES.Revisions_VERSION).toConstantValue(env.get('VERSION', true) ?? 'development')
  115. if (!isConfiguredForHomeServer) {
  116. // env vars
  117. container.bind(TYPES.Revisions_SNS_TOPIC_ARN).toConstantValue(env.get('SNS_TOPIC_ARN'))
  118. container.bind(TYPES.Revisions_SNS_AWS_REGION).toConstantValue(env.get('SNS_AWS_REGION', true))
  119. container.bind(TYPES.Revisions_SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL'))
  120. container.bind(TYPES.Revisions_S3_AWS_REGION).toConstantValue(env.get('S3_AWS_REGION', true))
  121. container.bind(TYPES.Revisions_S3_BACKUP_BUCKET_NAME).toConstantValue(env.get('S3_BACKUP_BUCKET_NAME', true))
  122. container.bind<SNSClient>(TYPES.Revisions_SNS).toDynamicValue((context: interfaces.Context) => {
  123. const env: Env = context.container.get(TYPES.Revisions_Env)
  124. const snsConfig: SNSClientConfig = {
  125. apiVersion: 'latest',
  126. region: env.get('SNS_AWS_REGION', true),
  127. }
  128. if (env.get('SNS_ENDPOINT', true)) {
  129. snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
  130. }
  131. if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
  132. snsConfig.credentials = {
  133. accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
  134. secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
  135. }
  136. }
  137. return new SNSClient(snsConfig)
  138. })
  139. container
  140. .bind<DomainEventPublisherInterface>(TYPES.Revisions_DomainEventPublisher)
  141. .toDynamicValue((context: interfaces.Context) => {
  142. return new SNSDomainEventPublisher(
  143. context.container.get(TYPES.Revisions_SNS),
  144. context.container.get(TYPES.Revisions_SNS_TOPIC_ARN),
  145. )
  146. })
  147. container.bind<SQSClient>(TYPES.Revisions_SQS).toDynamicValue((context: interfaces.Context) => {
  148. const env: Env = context.container.get(TYPES.Revisions_Env)
  149. const sqsConfig: SQSClientConfig = {
  150. region: env.get('SQS_AWS_REGION'),
  151. }
  152. if (env.get('SQS_ENDPOINT', true)) {
  153. sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
  154. }
  155. if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
  156. sqsConfig.credentials = {
  157. accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
  158. secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
  159. }
  160. }
  161. return new SQSClient(sqsConfig)
  162. })
  163. container.bind<S3Client | undefined>(TYPES.Revisions_S3).toDynamicValue((context: interfaces.Context) => {
  164. const env: Env = context.container.get(TYPES.Revisions_Env)
  165. let s3Client = undefined
  166. if (env.get('S3_AWS_REGION', true)) {
  167. s3Client = new S3Client({
  168. apiVersion: 'latest',
  169. region: env.get('S3_AWS_REGION', true),
  170. })
  171. }
  172. return s3Client
  173. })
  174. } else {
  175. container
  176. .bind<DomainEventPublisherInterface>(TYPES.Revisions_DomainEventPublisher)
  177. .toConstantValue(directCallDomainEventPublisher)
  178. }
  179. container
  180. .bind<DomainEventFactoryInterface>(TYPES.Revisions_DomainEventFactory)
  181. .toConstantValue(new DomainEventFactory(container.get(TYPES.Revisions_Timer)))
  182. // Map
  183. container
  184. .bind<MapperInterface<RevisionMetadata, SQLLegacyRevision>>(
  185. TYPES.Revisions_SQLLegacyRevisionMetadataPersistenceMapper,
  186. )
  187. .toConstantValue(new SQLLegacyRevisionMetadataPersistenceMapper())
  188. container
  189. .bind<MapperInterface<RevisionMetadata, SQLRevision>>(TYPES.Revisions_SQLRevisionMetadataPersistenceMapper)
  190. .toConstantValue(new SQLRevisionMetadataPersistenceMapper())
  191. container
  192. .bind<MapperInterface<Revision, SQLLegacyRevision>>(TYPES.Revisions_SQLLegacyRevisionPersistenceMapper)
  193. .toConstantValue(new SQLLegacyRevisionPersistenceMapper())
  194. container
  195. .bind<MapperInterface<Revision, SQLRevision>>(TYPES.Revisions_SQLRevisionPersistenceMapper)
  196. .toConstantValue(new SQLRevisionPersistenceMapper())
  197. container
  198. .bind<MapperInterface<RevisionMetadata, MongoDBRevision>>(
  199. TYPES.Revisions_MongoDBRevisionMetadataPersistenceMapper,
  200. )
  201. .toConstantValue(new MongoDBRevisionMetadataPersistenceMapper())
  202. container
  203. .bind<MapperInterface<Revision, MongoDBRevision>>(TYPES.Revisions_MongoDBRevisionPersistenceMapper)
  204. .toConstantValue(new MongoDBRevisionPersistenceMapper())
  205. // ORM
  206. container
  207. .bind<Repository<SQLLegacyRevision>>(TYPES.Revisions_ORMLegacyRevisionRepository)
  208. .toDynamicValue(() => appDataSource.getRepository(SQLLegacyRevision))
  209. container
  210. .bind<Repository<SQLRevision>>(TYPES.Revisions_ORMRevisionRepository)
  211. .toConstantValue(appDataSource.getRepository(SQLRevision))
  212. // Repositories
  213. container
  214. .bind<RevisionRepositoryInterface>(TYPES.Revisions_SQLRevisionRepository)
  215. .toConstantValue(
  216. isConfiguredForHomeServerOrSelfHosting
  217. ? new SQLRevisionRepository(
  218. container.get<Repository<SQLRevision>>(TYPES.Revisions_ORMRevisionRepository),
  219. container.get<MapperInterface<RevisionMetadata, SQLRevision>>(
  220. TYPES.Revisions_SQLRevisionMetadataPersistenceMapper,
  221. ),
  222. container.get<MapperInterface<Revision, SQLRevision>>(TYPES.Revisions_SQLRevisionPersistenceMapper),
  223. container.get<winston.Logger>(TYPES.Revisions_Logger),
  224. )
  225. : new SQLLegacyRevisionRepository(
  226. container.get<Repository<SQLLegacyRevision>>(TYPES.Revisions_ORMLegacyRevisionRepository),
  227. container.get<MapperInterface<RevisionMetadata, SQLLegacyRevision>>(
  228. TYPES.Revisions_SQLLegacyRevisionMetadataPersistenceMapper,
  229. ),
  230. container.get<MapperInterface<Revision, SQLLegacyRevision>>(
  231. TYPES.Revisions_SQLLegacyRevisionPersistenceMapper,
  232. ),
  233. container.get<winston.Logger>(TYPES.Revisions_Logger),
  234. ),
  235. )
  236. if (isSecondaryDatabaseEnabled) {
  237. container
  238. .bind<MongoRepository<MongoDBRevision>>(TYPES.Revisions_ORMMongoRevisionRepository)
  239. .toConstantValue(appDataSource.getMongoRepository(MongoDBRevision))
  240. container
  241. .bind<RevisionRepositoryInterface>(TYPES.Revisions_MongoDBRevisionRepository)
  242. .toConstantValue(
  243. new MongoDBRevisionRepository(
  244. container.get<MongoRepository<MongoDBRevision>>(TYPES.Revisions_ORMMongoRevisionRepository),
  245. container.get<MapperInterface<RevisionMetadata, MongoDBRevision>>(
  246. TYPES.Revisions_MongoDBRevisionMetadataPersistenceMapper,
  247. ),
  248. container.get<MapperInterface<Revision, MongoDBRevision>>(TYPES.Revisions_MongoDBRevisionPersistenceMapper),
  249. container.get<winston.Logger>(TYPES.Revisions_Logger),
  250. ),
  251. )
  252. }
  253. container
  254. .bind<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver)
  255. .toConstantValue(
  256. new TypeORMRevisionRepositoryResolver(
  257. container.get<RevisionRepositoryInterface>(TYPES.Revisions_SQLRevisionRepository),
  258. isSecondaryDatabaseEnabled
  259. ? container.get<RevisionRepositoryInterface>(TYPES.Revisions_MongoDBRevisionRepository)
  260. : null,
  261. ),
  262. )
  263. container
  264. .bind<GetRequiredRoleToViewRevision>(TYPES.Revisions_GetRequiredRoleToViewRevision)
  265. .toDynamicValue((context: interfaces.Context) => {
  266. return new GetRequiredRoleToViewRevision(context.container.get(TYPES.Revisions_Timer))
  267. })
  268. // Map
  269. container
  270. .bind<MapperInterface<Revision, RevisionHttpRepresentation>>(TYPES.Revisions_RevisionHttpMapper)
  271. .toDynamicValue(() => new RevisionHttpMapper())
  272. container
  273. .bind<MapperInterface<RevisionMetadata, RevisionMetadataHttpRepresentation>>(
  274. TYPES.Revisions_RevisionMetadataHttpMapper,
  275. )
  276. .toDynamicValue((context: interfaces.Context) => {
  277. return new RevisionMetadataHttpMapper(context.container.get(TYPES.Revisions_GetRequiredRoleToViewRevision))
  278. })
  279. // use cases
  280. container
  281. .bind<GetRevisionsMetada>(TYPES.Revisions_GetRevisionsMetada)
  282. .toConstantValue(
  283. new GetRevisionsMetada(
  284. container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver),
  285. ),
  286. )
  287. container
  288. .bind<GetRevision>(TYPES.Revisions_GetRevision)
  289. .toConstantValue(
  290. new GetRevision(container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver)),
  291. )
  292. container
  293. .bind<DeleteRevision>(TYPES.Revisions_DeleteRevision)
  294. .toConstantValue(
  295. new DeleteRevision(
  296. container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver),
  297. ),
  298. )
  299. container
  300. .bind<CopyRevisions>(TYPES.Revisions_CopyRevisions)
  301. .toConstantValue(
  302. new CopyRevisions(
  303. container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver),
  304. ),
  305. )
  306. container
  307. .bind<TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser>(
  308. TYPES.Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser,
  309. )
  310. .toConstantValue(
  311. new TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser(
  312. container.get<RevisionRepositoryInterface>(TYPES.Revisions_SQLRevisionRepository),
  313. isSecondaryDatabaseEnabled
  314. ? container.get<RevisionRepositoryInterface>(TYPES.Revisions_MongoDBRevisionRepository)
  315. : null,
  316. container.get<TimerInterface>(TYPES.Revisions_Timer),
  317. container.get<winston.Logger>(TYPES.Revisions_Logger),
  318. ),
  319. )
  320. container
  321. .bind<TriggerTransitionFromPrimaryToSecondaryDatabaseForUser>(
  322. TYPES.Revisions_TriggerTransitionFromPrimaryToSecondaryDatabaseForUser,
  323. )
  324. .toConstantValue(
  325. new TriggerTransitionFromPrimaryToSecondaryDatabaseForUser(
  326. container.get<DomainEventPublisherInterface>(TYPES.Revisions_DomainEventPublisher),
  327. container.get<DomainEventFactoryInterface>(TYPES.Revisions_DomainEventFactory),
  328. ),
  329. )
  330. container
  331. .bind<RemoveRevisionsFromSharedVault>(TYPES.Revisions_RemoveRevisionsFromSharedVault)
  332. .toConstantValue(
  333. new RemoveRevisionsFromSharedVault(
  334. container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver),
  335. ),
  336. )
  337. // env vars
  338. container.bind(TYPES.Revisions_AUTH_JWT_SECRET).toConstantValue(env.get('AUTH_JWT_SECRET'))
  339. // Controller
  340. container
  341. .bind<ControllerContainerInterface>(TYPES.Revisions_ControllerContainer)
  342. .toConstantValue(configuration?.controllerConatiner ?? new ControllerContainer())
  343. container
  344. .bind<TokenDecoderInterface<CrossServiceTokenData>>(TYPES.Revisions_CrossServiceTokenDecoder)
  345. .toDynamicValue((context: interfaces.Context) => {
  346. return new TokenDecoder<CrossServiceTokenData>(context.container.get(TYPES.Revisions_AUTH_JWT_SECRET))
  347. })
  348. container
  349. .bind<ApiGatewayAuthMiddleware>(TYPES.Revisions_ApiGatewayAuthMiddleware)
  350. .toDynamicValue((context: interfaces.Context) => {
  351. return new ApiGatewayAuthMiddleware(
  352. context.container.get(TYPES.Revisions_CrossServiceTokenDecoder),
  353. context.container.get(TYPES.Revisions_Logger),
  354. )
  355. })
  356. // Map
  357. container
  358. .bind<MapperInterface<Revision, string>>(TYPES.Revisions_RevisionItemStringMapper)
  359. .toDynamicValue(() => new RevisionItemStringMapper())
  360. container
  361. .bind<DumpRepositoryInterface>(TYPES.Revisions_DumpRepository)
  362. .toConstantValue(
  363. env.get('S3_AWS_REGION', true)
  364. ? new S3DumpRepository(
  365. container.get(TYPES.Revisions_S3_BACKUP_BUCKET_NAME),
  366. container.get(TYPES.Revisions_S3),
  367. container.get(TYPES.Revisions_RevisionItemStringMapper),
  368. container.get(TYPES.Revisions_Logger),
  369. )
  370. : new FSDumpRepository(container.get(TYPES.Revisions_RevisionItemStringMapper)),
  371. )
  372. // Handlers
  373. container
  374. .bind<ItemDumpedEventHandler>(TYPES.Revisions_ItemDumpedEventHandler)
  375. .toConstantValue(
  376. new ItemDumpedEventHandler(
  377. container.get<DumpRepositoryInterface>(TYPES.Revisions_DumpRepository),
  378. container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver),
  379. ),
  380. )
  381. container
  382. .bind<AccountDeletionRequestedEventHandler>(TYPES.Revisions_AccountDeletionRequestedEventHandler)
  383. .toConstantValue(
  384. new AccountDeletionRequestedEventHandler(
  385. container.get<RevisionRepositoryResolverInterface>(TYPES.Revisions_RevisionRepositoryResolver),
  386. container.get<winston.Logger>(TYPES.Revisions_Logger),
  387. ),
  388. )
  389. container
  390. .bind<RevisionsCopyRequestedEventHandler>(TYPES.Revisions_RevisionsCopyRequestedEventHandler)
  391. .toConstantValue(
  392. new RevisionsCopyRequestedEventHandler(
  393. container.get<CopyRevisions>(TYPES.Revisions_CopyRevisions),
  394. container.get<winston.Logger>(TYPES.Revisions_Logger),
  395. ),
  396. )
  397. container
  398. .bind<TransitionStatusUpdatedEventHandler>(TYPES.Revisions_TransitionStatusUpdatedEventHandler)
  399. .toConstantValue(
  400. new TransitionStatusUpdatedEventHandler(
  401. container.get<TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser>(
  402. TYPES.Revisions_TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser,
  403. ),
  404. container.get<DomainEventPublisherInterface>(TYPES.Revisions_DomainEventPublisher),
  405. container.get<DomainEventFactoryInterface>(TYPES.Revisions_DomainEventFactory),
  406. container.get<winston.Logger>(TYPES.Revisions_Logger),
  407. ),
  408. )
  409. container
  410. .bind<ItemRemovedFromSharedVaultEventHandler>(TYPES.Revisions_ItemRemovedFromSharedVaultEventHandler)
  411. .toConstantValue(
  412. new ItemRemovedFromSharedVaultEventHandler(
  413. container.get<RemoveRevisionsFromSharedVault>(TYPES.Revisions_RemoveRevisionsFromSharedVault),
  414. container.get<winston.Logger>(TYPES.Revisions_Logger),
  415. ),
  416. )
  417. const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
  418. ['ITEM_DUMPED', container.get(TYPES.Revisions_ItemDumpedEventHandler)],
  419. ['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.Revisions_AccountDeletionRequestedEventHandler)],
  420. ['REVISIONS_COPY_REQUESTED', container.get(TYPES.Revisions_RevisionsCopyRequestedEventHandler)],
  421. ['TRANSITION_STATUS_UPDATED', container.get(TYPES.Revisions_TransitionStatusUpdatedEventHandler)],
  422. ['ITEM_REMOVED_FROM_SHARED_VAULT', container.get(TYPES.Revisions_ItemRemovedFromSharedVaultEventHandler)],
  423. ])
  424. if (isConfiguredForHomeServer) {
  425. const directCallEventMessageHandler = new DirectCallEventMessageHandler(
  426. eventHandlers,
  427. container.get(TYPES.Revisions_Logger),
  428. )
  429. directCallDomainEventPublisher.register(directCallEventMessageHandler)
  430. container
  431. .bind<DomainEventMessageHandlerInterface>(TYPES.Revisions_DomainEventMessageHandler)
  432. .toConstantValue(directCallEventMessageHandler)
  433. } else {
  434. container
  435. .bind<DomainEventMessageHandlerInterface>(TYPES.Revisions_DomainEventMessageHandler)
  436. .toConstantValue(
  437. env.get('NEW_RELIC_ENABLED', true) === 'true'
  438. ? new SQSNewRelicEventMessageHandler(eventHandlers, container.get(TYPES.Revisions_Logger))
  439. : new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Revisions_Logger)),
  440. )
  441. container
  442. .bind<DomainEventSubscriberFactoryInterface>(TYPES.Revisions_DomainEventSubscriberFactory)
  443. .toDynamicValue((context: interfaces.Context) => {
  444. return new SQSDomainEventSubscriberFactory(
  445. context.container.get(TYPES.Revisions_SQS),
  446. context.container.get(TYPES.Revisions_SQS_QUEUE_URL),
  447. context.container.get(TYPES.Revisions_DomainEventMessageHandler),
  448. )
  449. })
  450. }
  451. // Inversify Controllers
  452. if (isConfiguredForHomeServer) {
  453. container
  454. .bind<BaseRevisionsController>(TYPES.Revisions_BaseRevisionsController)
  455. .toConstantValue(
  456. new BaseRevisionsController(
  457. container.get<GetRevisionsMetada>(TYPES.Revisions_GetRevisionsMetada),
  458. container.get<GetRevision>(TYPES.Revisions_GetRevision),
  459. container.get<DeleteRevision>(TYPES.Revisions_DeleteRevision),
  460. container.get<RevisionHttpMapper>(TYPES.Revisions_RevisionHttpMapper),
  461. container.get<RevisionMetadataHttpMapper>(TYPES.Revisions_RevisionMetadataHttpMapper),
  462. container.get<TriggerTransitionFromPrimaryToSecondaryDatabaseForUser>(
  463. TYPES.Revisions_TriggerTransitionFromPrimaryToSecondaryDatabaseForUser,
  464. ),
  465. container.get<ControllerContainerInterface>(TYPES.Revisions_ControllerContainer),
  466. ),
  467. )
  468. }
  469. logger.debug('Configuration complete')
  470. return container
  471. }
  472. }