mirror of
https://github.com/standardnotes/server
synced 2026-02-15 11:01:12 -05:00
Compare commits
5 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78b13261bf | ||
|
|
6356fcaeed | ||
|
|
443235a861 | ||
|
|
95fccb0822 | ||
|
|
1fa476d1f9 |
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [2.30.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.29.0...@standardnotes/analytics@2.30.0) (2023-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add opentelemetry for scheduled tasks ([443235a](https://github.com/standardnotes/server/commit/443235a861181acf708d98fba25ce6d79f198b56))
|
||||
|
||||
# [2.29.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.28.9...@standardnotes/analytics@2.29.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { EmailLevel, ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AnalyticsScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { EmailLevel } from '@standardnotes/domain-core'
|
||||
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
|
||||
import { AnalyticsActivity } from '../src/Domain/Analytics/AnalyticsActivity'
|
||||
import { Period } from '../src/Domain/Time/Period'
|
||||
@@ -270,6 +275,9 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info(`Sending report to following admins: ${adminEmails}`)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.AnalyticsScheduledTask, 'report')
|
||||
|
||||
Promise.resolve(
|
||||
requestReport(
|
||||
analyticsStore,
|
||||
@@ -285,11 +293,15 @@ void container.load().then((container) => {
|
||||
.then(() => {
|
||||
logger.info('Usage report generation complete')
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Could not finish usage report generation: ${error.message}`)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.29.0",
|
||||
"version": "2.30.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.79.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.0...@standardnotes/api-gateway@1.79.1) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
# [1.79.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.78.6...@standardnotes/api-gateway@1.79.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.79.0",
|
||||
"version": "1.79.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.157.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.156.0...@standardnotes/auth-server@1.157.0) (2023-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add opentelemetry for scheduled tasks ([443235a](https://github.com/standardnotes/server/commit/443235a861181acf708d98fba25ce6d79f198b56))
|
||||
|
||||
# [1.156.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.155.1...@standardnotes/auth-server@1.156.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Stream } from 'stream'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
@@ -91,15 +97,22 @@ void container.load().then((container) => {
|
||||
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
|
||||
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'backup')
|
||||
|
||||
Promise.resolve(requestBackups(settingRepository, roleService, domainEventFactory, domainEventPublisher))
|
||||
.then(() => {
|
||||
logger.info(`${backupFrequency} ${backupProvider} backup requesting complete`)
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Could not finish ${backupFrequency} ${backupProvider} backup requesting: ${error.message}`)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
@@ -30,15 +36,22 @@ void container.load().then((container) => {
|
||||
const cleanupSessionTraces: CleanupSessionTraces = container.get(TYPES.Auth_CleanupSessionTraces)
|
||||
const cleanupExpiredSessions: CleanupExpiredSessions = container.get(TYPES.Auth_CleanupExpiredSessions)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'cleanup')
|
||||
|
||||
Promise.resolve(cleanup(cleanupSessionTraces, cleanupExpiredSessions))
|
||||
.then(() => {
|
||||
logger.info('Expired sessions and session traces cleaned.')
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Could not clean sessions and session traces: ${error.message}`)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
@@ -15,11 +21,14 @@ void container.load().then((container) => {
|
||||
|
||||
const logger: Logger = container.get(TYPES.Auth_Logger)
|
||||
|
||||
logger.info('Starting session traces cleanup')
|
||||
logger.info('Starting statistics persistence...')
|
||||
|
||||
const persistStats: PersistStatistics = container.get(TYPES.Auth_PersistStatistics)
|
||||
const timer: TimerInterface = container.get(TYPES.Auth_Timer)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'stats')
|
||||
|
||||
Promise.resolve(
|
||||
persistStats.execute({
|
||||
sessionsInADay: timer.getUTCDateNDaysAgo(1),
|
||||
@@ -28,11 +37,15 @@ void container.load().then((container) => {
|
||||
.then(() => {
|
||||
logger.info('Stats persisted.')
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Could not persist stats: ${error.message}`)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { ServiceIdentifier, RoleName, TransitionStatus } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
@@ -12,7 +18,6 @@ import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFact
|
||||
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { TransitionStatusRepositoryInterface } from '../src/Domain/Transition/TransitionStatusRepositoryInterface'
|
||||
import { RoleName, TransitionStatus } from '@standardnotes/domain-core'
|
||||
|
||||
const inputArgs = process.argv.slice(2)
|
||||
const startDateString = inputArgs[0]
|
||||
@@ -124,6 +129,9 @@ void container.load().then((container) => {
|
||||
TYPES.Auth_TransitionStatusRepository,
|
||||
)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'transition')
|
||||
|
||||
Promise.resolve(
|
||||
requestTransition(
|
||||
transitionStatusRepository,
|
||||
@@ -137,6 +145,8 @@ void container.load().then((container) => {
|
||||
.then(() => {
|
||||
logger.info(`Finished transition request for users created between ${startDateString} and ${endDateString}`)
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -144,6 +154,8 @@ void container.load().then((container) => {
|
||||
`Error while requesting transition for users created between ${startDateString} and ${endDateString}: ${error}`,
|
||||
)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { Email, ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.AuthScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
@@ -14,7 +20,6 @@ import { MuteFailedBackupsEmailsOption, SettingName } from '@standardnotes/setti
|
||||
import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface'
|
||||
import { PermissionName } from '@standardnotes/features'
|
||||
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
|
||||
import { Email } from '@standardnotes/domain-core'
|
||||
|
||||
const inputArgs = process.argv.slice(2)
|
||||
const backupEmail = inputArgs[0]
|
||||
@@ -80,17 +85,24 @@ void container.load().then((container) => {
|
||||
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory)
|
||||
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.Auth_DomainEventPublisher)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.AuthScheduledTask, 'user_email_backup')
|
||||
|
||||
Promise.resolve(
|
||||
requestBackups(userRepository, settingRepository, roleService, domainEventFactory, domainEventPublisher),
|
||||
)
|
||||
.then(() => {
|
||||
logger.info(`Email backup requesting complete for ${backupEmail}`)
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Could not finish email backup requesting for ${backupEmail}: ${error.message}`)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.156.0",
|
||||
"version": "1.157.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.36.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.35.0...@standardnotes/domain-core@1.36.0) (2023-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add opentelemetry for scheduled tasks ([443235a](https://github.com/standardnotes/server/commit/443235a861181acf708d98fba25ce6d79f198b56))
|
||||
* **domain-core:** add email bounce processor service identifier ([6356fca](https://github.com/standardnotes/server/commit/6356fcaeed012e7ea5d174b47aaebb94a4040d29))
|
||||
|
||||
# [1.35.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.34.2...@standardnotes/domain-core@1.35.0) (2023-10-06)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-core",
|
||||
"version": "1.35.0",
|
||||
"version": "1.36.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -5,9 +5,11 @@ import { ServiceIdentifierProps } from './ServiceIdentifierProps'
|
||||
export class ServiceIdentifier extends ValueObject<ServiceIdentifierProps> {
|
||||
static readonly NAMES = {
|
||||
AnalyticsWorker: 'AnalyticsWorker',
|
||||
AnalyticsScheduledTask: 'AnalyticsScheduledTask',
|
||||
ApiGateway: 'ApiGateway',
|
||||
Auth: 'Auth',
|
||||
AuthWorker: 'AuthWorker',
|
||||
AuthScheduledTask: 'AuthScheduledTask',
|
||||
SyncingServer: 'SyncingServer',
|
||||
SyncingServerWorker: 'SyncingServerWorker',
|
||||
Revisions: 'Revisions',
|
||||
@@ -15,8 +17,10 @@ export class ServiceIdentifier extends ValueObject<ServiceIdentifierProps> {
|
||||
Files: 'Files',
|
||||
FilesWorker: 'FilesWorker',
|
||||
SchedulerWorker: 'SchedulerWorker',
|
||||
SchedulerScheduledTask: 'SchedulerScheduledTask',
|
||||
Email: 'Email',
|
||||
EmailWorker: 'EmailWorker',
|
||||
EmailBounceProcessor: 'EmailBounceProcessor',
|
||||
Websockets: 'Websockets',
|
||||
WebsocketsWorker: 'WebsocketsWorker',
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.18.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.17.0...@standardnotes/domain-events-infra@1.18.0) (2023-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add opentelemetry for scheduled tasks ([443235a](https://github.com/standardnotes/server/commit/443235a861181acf708d98fba25ce6d79f198b56))
|
||||
|
||||
# [1.17.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.16.4...@standardnotes/domain-events-infra@1.17.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.17.0",
|
||||
"version": "1.18.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import * as OpenTelemetryApi from '@opentelemetry/api'
|
||||
|
||||
import { OpenTelemetryTracerInterface } from './OpenTelemetryTracerInterface'
|
||||
|
||||
export class OpenTelemetryTracer implements OpenTelemetryTracerInterface {
|
||||
private parentSpan: OpenTelemetryApi.Span | undefined
|
||||
private internalSpan: OpenTelemetryApi.Span | undefined
|
||||
|
||||
startSpan(parentSpanName: string, internalSpanName: string): void {
|
||||
const tracer = OpenTelemetryApi.trace.getTracer(`${parentSpanName}-handler`)
|
||||
|
||||
this.parentSpan = tracer.startSpan(parentSpanName, { kind: OpenTelemetryApi.SpanKind.CONSUMER })
|
||||
const ctx = OpenTelemetryApi.trace.setSpan(OpenTelemetryApi.context.active(), this.parentSpan)
|
||||
|
||||
this.internalSpan = tracer.startSpan(internalSpanName, { kind: OpenTelemetryApi.SpanKind.INTERNAL }, ctx)
|
||||
}
|
||||
|
||||
stopSpan(): void {
|
||||
if (this.internalSpan) {
|
||||
this.internalSpan.end()
|
||||
this.internalSpan = undefined
|
||||
}
|
||||
|
||||
if (this.parentSpan) {
|
||||
this.parentSpan.end()
|
||||
this.parentSpan = undefined
|
||||
}
|
||||
}
|
||||
|
||||
stopSpanWithError(error: Error): void {
|
||||
if (this.internalSpan) {
|
||||
this.internalSpan.recordException(error)
|
||||
this.internalSpan.end()
|
||||
this.internalSpan = undefined
|
||||
}
|
||||
|
||||
if (this.parentSpan) {
|
||||
this.parentSpan.end()
|
||||
this.parentSpan = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface OpenTelemetryTracerInterface {
|
||||
startSpan(parentSpanName: string, internalSpanName: string): void
|
||||
stopSpan(): void
|
||||
stopSpanWithError(error: Error): void
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { SQSDomainEventSubscriberFactory } from './SQSDomainEventSubscriberFactory'
|
||||
import { DomainEventMessageHandlerInterface } from '@standardnotes/domain-events'
|
||||
import { Consumer } from 'sqs-consumer'
|
||||
import { SQSClient } from '@aws-sdk/client-sqs'
|
||||
|
||||
describe('SQSDomainEventSubscriberFactory', () => {
|
||||
let sqs: SQSClient
|
||||
const queueUrl = 'https://queue-url'
|
||||
let domainEventMessageHandler: DomainEventMessageHandlerInterface
|
||||
|
||||
const createFactory = () => new SQSDomainEventSubscriberFactory(sqs, queueUrl, domainEventMessageHandler)
|
||||
|
||||
beforeEach(() => {
|
||||
sqs = {} as jest.Mocked<SQSClient>
|
||||
|
||||
domainEventMessageHandler = {} as jest.Mocked<DomainEventMessageHandlerInterface>
|
||||
domainEventMessageHandler.handleMessage = jest.fn()
|
||||
domainEventMessageHandler.handleError = jest.fn()
|
||||
})
|
||||
|
||||
it('should create a domain event subscriber', () => {
|
||||
const subscriber = createFactory().create()
|
||||
|
||||
expect(subscriber).toBeInstanceOf(Consumer)
|
||||
})
|
||||
})
|
||||
@@ -1,60 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { DomainEventHandlerInterface } from '@standardnotes/domain-events'
|
||||
|
||||
import { SQSEventMessageHandler } from './SQSEventMessageHandler'
|
||||
|
||||
describe('SQSEventMessageHandler', () => {
|
||||
let handler: DomainEventHandlerInterface
|
||||
let handlers: Map<string, DomainEventHandlerInterface>
|
||||
let logger: Logger
|
||||
|
||||
const createHandler = () => new SQSEventMessageHandler(handlers, logger)
|
||||
|
||||
beforeEach(() => {
|
||||
handler = {} as jest.Mocked<DomainEventHandlerInterface>
|
||||
handler.handle = jest.fn()
|
||||
|
||||
handlers = new Map([['TEST', handler]])
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.debug = jest.fn()
|
||||
logger.error = jest.fn()
|
||||
})
|
||||
|
||||
it('should handle messages', async () => {
|
||||
const sqsMessage = `{
|
||||
"Message" : "eJyrViqpLEhVslIKcQ0OUdJRKkiszMlPTFGyqlZKy88HiiclFinV6iglF6UmlqSmOJYAhQwtzQ10DQyBKMTAwAqM9AwMDKOUagGlWhXt"
|
||||
}`
|
||||
|
||||
await createHandler().handleMessage(sqsMessage)
|
||||
|
||||
expect(handler.handle).toHaveBeenCalledWith({
|
||||
payload: {
|
||||
foo: 'bar',
|
||||
},
|
||||
type: 'TEST',
|
||||
createdAt: new Date(1),
|
||||
})
|
||||
})
|
||||
|
||||
it('should handle errors', async () => {
|
||||
await createHandler().handleError(new Error('test'))
|
||||
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should tell if there is no handler for an event', async () => {
|
||||
const sqsMessage = `{
|
||||
"Message" : "eJyrViqpLEhVslIKcQ0OMVLSUSpIrMzJT0xRsqpWSsvPB0okJRYp1dYCAABHDLY="
|
||||
}`
|
||||
|
||||
await createHandler().handleMessage(sqsMessage)
|
||||
|
||||
expect(logger.debug).toHaveBeenCalledWith('Event handler for event type TEST2 does not exist')
|
||||
|
||||
expect(handler.handle).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -1,15 +1,15 @@
|
||||
import { Logger } from 'winston'
|
||||
import * as zlib from 'zlib'
|
||||
import * as OpenTelemetryApi from '@opentelemetry/api'
|
||||
import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { OpenTelemetryTracer } from '../OpenTelemetry/OpenTelemetryTracer'
|
||||
import { OpenTelemetryTracerInterface } from '../OpenTelemetry/OpenTelemetryTracerInterface'
|
||||
|
||||
export class SQSOpenTelemetryEventMessageHandler implements DomainEventMessageHandlerInterface {
|
||||
private currentSpan: OpenTelemetryApi.Span | undefined
|
||||
private internalSpan: OpenTelemetryApi.Span | undefined
|
||||
private tracer: OpenTelemetryTracerInterface | undefined
|
||||
|
||||
constructor(
|
||||
private serviceName: string,
|
||||
@@ -35,35 +35,22 @@ export class SQSOpenTelemetryEventMessageHandler implements DomainEventMessageHa
|
||||
|
||||
this.logger.debug(`Received event: ${domainEvent.type}`)
|
||||
|
||||
const tracer = OpenTelemetryApi.trace.getTracer('sqs-handler')
|
||||
this.tracer = new OpenTelemetryTracer()
|
||||
|
||||
this.currentSpan = tracer.startSpan(this.serviceName, { kind: OpenTelemetryApi.SpanKind.CONSUMER })
|
||||
const ctx = OpenTelemetryApi.trace.setSpan(OpenTelemetryApi.context.active(), this.currentSpan)
|
||||
this.tracer.startSpan(this.serviceName, domainEvent.type)
|
||||
|
||||
this.internalSpan = tracer.startSpan(domainEvent.type, { kind: OpenTelemetryApi.SpanKind.INTERNAL }, ctx)
|
||||
try {
|
||||
await handler.handle(domainEvent)
|
||||
} catch (error) {
|
||||
this.tracer.stopSpanWithError(error as Error)
|
||||
|
||||
await handler.handle(domainEvent)
|
||||
throw error
|
||||
}
|
||||
|
||||
this.internalSpan.end()
|
||||
|
||||
this.currentSpan.end()
|
||||
|
||||
this.internalSpan = undefined
|
||||
this.currentSpan = undefined
|
||||
this.tracer.stopSpan()
|
||||
}
|
||||
|
||||
async handleError(error: Error): Promise<void> {
|
||||
if (this.internalSpan) {
|
||||
this.internalSpan.recordException(error)
|
||||
this.internalSpan.end()
|
||||
this.internalSpan = undefined
|
||||
}
|
||||
|
||||
if (this.currentSpan) {
|
||||
this.currentSpan.end()
|
||||
this.currentSpan = undefined
|
||||
}
|
||||
|
||||
this.logger.error('Error occured while handling SQS message: %O', error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ export * from './DirectCall/DirectCallEventMessageHandler'
|
||||
|
||||
export * from './OpenTelemetry/OpenTelemetrySDK'
|
||||
export * from './OpenTelemetry/OpenTelemetrySDKInterface'
|
||||
export * from './OpenTelemetry/OpenTelemetryTracer'
|
||||
export * from './OpenTelemetry/OpenTelemetryTracerInterface'
|
||||
|
||||
export * from './Redis/RedisDomainEventPublisher'
|
||||
export * from './Redis/RedisDomainEventSubscriber'
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.13.1](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.0...@standardnotes/event-store@1.13.1) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
# [1.13.0](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.12.18...@standardnotes/event-store@1.13.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.13.0",
|
||||
"version": "1.13.1",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.29.1](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.29.0...@standardnotes/files-server@1.29.1) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
# [1.29.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.28.5...@standardnotes/files-server@1.29.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.29.0",
|
||||
"version": "1.29.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.17.2](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.1...@standardnotes/home-server@1.17.2) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.17.1](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.0...@standardnotes/home-server@1.17.1) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
# [1.17.0](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.16.48...@standardnotes/home-server@1.17.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/home-server",
|
||||
"version": "1.17.0",
|
||||
"version": "1.17.2",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.44.1](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.44.0...@standardnotes/revisions-server@1.44.1) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
# [1.44.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.43.5...@standardnotes/revisions-server@1.44.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.44.0",
|
||||
"version": "1.44.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.24.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.23.0...@standardnotes/scheduler-server@1.24.0) (2023-10-11)
|
||||
|
||||
### Features
|
||||
|
||||
* add opentelemetry for scheduled tasks ([443235a](https://github.com/standardnotes/server/commit/443235a861181acf708d98fba25ce6d79f198b56))
|
||||
|
||||
# [1.23.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.22.9...@standardnotes/scheduler-server@1.23.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { OpenTelemetrySDK, OpenTelemetryTracer } from '@standardnotes/domain-events-infra'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
const sdk = new OpenTelemetrySDK(ServiceIdentifier.NAMES.SchedulerScheduledTask)
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
@@ -29,15 +35,22 @@ void container.load().then((container) => {
|
||||
|
||||
const verifyPredicates: VerifyPredicates = container.get(TYPES.VerifyPredicates)
|
||||
|
||||
const tracer = new OpenTelemetryTracer()
|
||||
tracer.startSpan(ServiceIdentifier.NAMES.SchedulerScheduledTask, 'verify')
|
||||
|
||||
Promise.resolve(verifyJobs(now, verifyPredicates))
|
||||
.then(() => {
|
||||
logger.info('Verification of overdue jobs complete.')
|
||||
|
||||
tracer.stopSpan()
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(`Could not finish verification of overdue jobs: ${error.message}`)
|
||||
|
||||
tracer.stopSpanWithError(error)
|
||||
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.23.0",
|
||||
"version": "1.24.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.21.44](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.43...@standardnotes/settings@1.21.44) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
## [1.21.43](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.42...@standardnotes/settings@1.21.43) (2023-10-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/settings",
|
||||
"version": "1.21.43",
|
||||
"version": "1.21.44",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.116.2](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.116.1...@standardnotes/syncing-server@1.116.2) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/syncing-server
|
||||
|
||||
## [1.116.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.116.0...@standardnotes/syncing-server@1.116.1) (2023-10-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server:** reduce the amount of select queries for items ([1fa476d](https://github.com/standardnotes/syncing-server-js/commit/1fa476d1f9b6b49e5a510ad093ed24808fce7f05))
|
||||
|
||||
# [1.116.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.115.4...@standardnotes/syncing-server@1.116.0) (2023-10-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.116.0",
|
||||
"version": "1.116.2",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -17,7 +17,6 @@ export interface ItemRepositoryInterface {
|
||||
findByUuid(uuid: Uuid): Promise<Item | null>
|
||||
remove(item: Item): Promise<void>
|
||||
removeByUuid(uuid: Uuid): Promise<void>
|
||||
save(item: Item): Promise<void>
|
||||
insert(item: Item): Promise<void>
|
||||
update(item: Item): Promise<void>
|
||||
markItemsAsDeleted(itemUuids: Array<string>, updatedAtTimestamp: number): Promise<void>
|
||||
|
||||
@@ -62,7 +62,7 @@ describe('SaveNewItem', () => {
|
||||
}).getValue()
|
||||
|
||||
itemRepository = {} as jest.Mocked<ItemRepositoryInterface>
|
||||
itemRepository.save = jest.fn()
|
||||
itemRepository.insert = jest.fn()
|
||||
|
||||
itemRepositoryResolver = {} as jest.Mocked<ItemRepositoryResolverInterface>
|
||||
itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository)
|
||||
@@ -97,7 +97,7 @@ describe('SaveNewItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.insert).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('saves a new empty item', async () => {
|
||||
@@ -120,7 +120,7 @@ describe('SaveNewItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.insert).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('saves a new item with given timestamps', async () => {
|
||||
@@ -368,7 +368,7 @@ describe('SaveNewItem', () => {
|
||||
expect(result.getValue().props.sharedVaultAssociation?.props.lastEditedBy.value).toEqual(
|
||||
'00000000-0000-0000-0000-000000000000',
|
||||
)
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.insert).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should return a failure if it fails to create a shared vault association', async () => {
|
||||
@@ -416,7 +416,7 @@ describe('SaveNewItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.insert).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should return a failure if the item hash has an invalid key system identifier', async () => {
|
||||
|
||||
@@ -142,7 +142,7 @@ export class SaveNewItem implements UseCaseInterface<Item> {
|
||||
|
||||
const itemRepository = this.itemRepositoryResolver.resolve(roleNames)
|
||||
|
||||
await itemRepository.save(newItem)
|
||||
await itemRepository.insert(newItem)
|
||||
|
||||
if (contentType.value !== null && [ContentType.TYPES.Note, ContentType.TYPES.File].includes(contentType.value)) {
|
||||
if (!dto.onGoingRevisionsTransition) {
|
||||
|
||||
@@ -89,7 +89,7 @@ describe('UpdateExistingItem', () => {
|
||||
}).getValue()
|
||||
|
||||
itemRepository = {} as jest.Mocked<ItemRepositoryInterface>
|
||||
itemRepository.save = jest.fn()
|
||||
itemRepository.update = jest.fn()
|
||||
|
||||
itemRepositoryResolver = {} as jest.Mocked<ItemRepositoryResolverInterface>
|
||||
itemRepositoryResolver.resolve = jest.fn().mockReturnValue(itemRepository)
|
||||
@@ -148,7 +148,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not create a revision if user has an ongoin revisions transition', async () => {
|
||||
@@ -164,7 +164,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should return error if session uuid is invalid', async () => {
|
||||
@@ -231,7 +231,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
expect(item1.props.deleted).toBeTruthy()
|
||||
expect(item1.props.content).toBeNull()
|
||||
expect(item1.props.encItemKey).toBeNull()
|
||||
@@ -256,7 +256,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
expect(item1.props.duplicateOf?.value).toBe('00000000-0000-0000-0000-000000000001')
|
||||
})
|
||||
|
||||
@@ -295,7 +295,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fallback to updated at timestamp if created at time is not give in any form', async () => {
|
||||
@@ -316,7 +316,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fallback to updated at date if created at time is not give in any form', async () => {
|
||||
@@ -338,7 +338,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fallback to 0 if created at and update at time is not give in any form', async () => {
|
||||
@@ -360,7 +360,7 @@ describe('UpdateExistingItem', () => {
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBeFalsy()
|
||||
expect(itemRepository.save).toHaveBeenCalled()
|
||||
expect(itemRepository.update).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should return error if dates could not be created from timestamps', async () => {
|
||||
|
||||
@@ -176,7 +176,7 @@ export class UpdateExistingItem implements UseCaseInterface<Item> {
|
||||
|
||||
const itemRepository = this.itemRepositoryResolver.resolve(roleNames)
|
||||
|
||||
await itemRepository.save(dto.existingItem)
|
||||
await itemRepository.update(dto.existingItem)
|
||||
|
||||
if (secondsFromLastUpdate >= this.revisionFrequency) {
|
||||
if (
|
||||
|
||||
@@ -170,20 +170,6 @@ export class MongoDBItemRepository implements ItemRepositoryInterface {
|
||||
await this.mongoRepository.deleteOne({ _id: { $eq: BSON.UUID.createFromHexString(item.uuid.value) } })
|
||||
}
|
||||
|
||||
async save(item: Item): Promise<void> {
|
||||
const persistence = this.mapper.toProjection(item)
|
||||
|
||||
const { _id, ...rest } = persistence
|
||||
|
||||
await this.mongoRepository.updateOne(
|
||||
{ _id: { $eq: _id } },
|
||||
{
|
||||
$set: rest,
|
||||
},
|
||||
{ upsert: true },
|
||||
)
|
||||
}
|
||||
|
||||
async insert(item: Item): Promise<void> {
|
||||
const persistence = this.mapper.toProjection(item)
|
||||
|
||||
|
||||
@@ -37,12 +37,6 @@ export class SQLLegacyItemRepository implements ItemRepositoryInterface {
|
||||
.execute()
|
||||
}
|
||||
|
||||
async save(item: Item): Promise<void> {
|
||||
const persistence = this.mapper.toProjection(item)
|
||||
|
||||
await this.ormRepository.save(persistence)
|
||||
}
|
||||
|
||||
async insert(item: Item): Promise<void> {
|
||||
const projection = this.mapper.toProjection(item)
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.15.1](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.15.0...@standardnotes/websockets-server@1.15.1) (2023-10-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
# [1.15.0](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.14.5...@standardnotes/websockets-server@1.15.0) (2023-10-10)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/websockets-server",
|
||||
"version": "1.15.0",
|
||||
"version": "1.15.1",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user