Compare commits

..

5 Commits

47 changed files with 259 additions and 167 deletions

View File

@@ -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

View File

@@ -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)
})
})

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.29.0",
"version": "2.30.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.79.0",
"version": "1.79.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -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)
})
})

View File

@@ -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)
})
})

View File

@@ -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)
})
})

View File

@@ -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)
})
})

View File

@@ -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)
})
})

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.156.0",
"version": "1.157.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-core",
"version": "1.35.0",
"version": "1.36.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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',
}

View File

@@ -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

View File

@@ -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"
},

View File

@@ -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
}
}
}

View File

@@ -0,0 +1,5 @@
export interface OpenTelemetryTracerInterface {
startSpan(parentSpanName: string, internalSpanName: string): void
stopSpan(): void
stopSpanWithError(error: Error): void
}

View File

@@ -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)
})
})

View File

@@ -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()
})
})

View File

@@ -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)
}
}

View File

@@ -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'

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.29.0",
"version": "1.29.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/home-server",
"version": "1.17.0",
"version": "1.17.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/revisions-server",
"version": "1.44.0",
"version": "1.44.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -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)
})
})

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.23.0",
"version": "1.24.0",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/settings",
"version": "1.21.43",
"version": "1.21.44",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.116.0",
"version": "1.116.2",
"engines": {
"node": ">=18.0.0 <21.0.0"
},

View File

@@ -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>

View File

@@ -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 () => {

View File

@@ -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) {

View File

@@ -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 () => {

View File

@@ -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 (

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/websockets-server",
"version": "1.15.0",
"version": "1.15.1",
"engines": {
"node": ">=18.0.0 <21.0.0"
},