mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
refactor(core): Send active workflow IDs during license renewal (#9804)
This commit is contained in:
parent
de3981cbde
commit
cfc4db00e3
|
@ -99,7 +99,7 @@
|
||||||
"@n8n/n8n-nodes-langchain": "workspace:*",
|
"@n8n/n8n-nodes-langchain": "workspace:*",
|
||||||
"@n8n/permissions": "workspace:*",
|
"@n8n/permissions": "workspace:*",
|
||||||
"@n8n/typeorm": "0.3.20-10",
|
"@n8n/typeorm": "0.3.20-10",
|
||||||
"@n8n_io/license-sdk": "2.12.0",
|
"@n8n_io/license-sdk": "2.13.0",
|
||||||
"@oclif/core": "3.26.6",
|
"@oclif/core": "3.26.6",
|
||||||
"@pinecone-database/pinecone": "2.1.0",
|
"@pinecone-database/pinecone": "2.1.0",
|
||||||
"@rudderstack/rudder-sdk-node": "2.0.7",
|
"@rudderstack/rudder-sdk-node": "2.0.7",
|
||||||
|
|
|
@ -84,6 +84,9 @@ export class License {
|
||||||
const collectUsageMetrics = isMainInstance
|
const collectUsageMetrics = isMainInstance
|
||||||
? async () => await this.usageMetricsService.collectUsageMetrics()
|
? async () => await this.usageMetricsService.collectUsageMetrics()
|
||||||
: async () => [];
|
: async () => [];
|
||||||
|
const collectPassthroughData = isMainInstance
|
||||||
|
? async () => await this.usageMetricsService.getActiveWorkflowIds()
|
||||||
|
: async () => ({});
|
||||||
|
|
||||||
const renewalEnabled = this.renewalEnabled(instanceType);
|
const renewalEnabled = this.renewalEnabled(instanceType);
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ export class License {
|
||||||
saveCertStr,
|
saveCertStr,
|
||||||
deviceFingerprint: () => this.instanceSettings.instanceId,
|
deviceFingerprint: () => this.instanceSettings.instanceId,
|
||||||
collectUsageMetrics,
|
collectUsageMetrics,
|
||||||
|
collectPassthroughData,
|
||||||
onFeatureChange,
|
onFeatureChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
import { UsageMetricsRepository } from '@/databases/repositories/usageMetrics.repository';
|
import { UsageMetricsRepository } from '@/databases/repositories/usageMetrics.repository';
|
||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
|
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class UsageMetricsService {
|
export class UsageMetricsService {
|
||||||
constructor(private readonly usageMetricsRepository: UsageMetricsRepository) {}
|
constructor(
|
||||||
|
private readonly usageMetricsRepository: UsageMetricsRepository,
|
||||||
|
private readonly workflowRepository: WorkflowRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
async collectUsageMetrics() {
|
async collectUsageMetrics() {
|
||||||
const {
|
const {
|
||||||
|
@ -26,4 +30,10 @@ export class UsageMetricsService {
|
||||||
{ name: 'manualExecutions', value: manualExecutions },
|
{ name: 'manualExecutions', value: manualExecutions },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getActiveWorkflowIds() {
|
||||||
|
return {
|
||||||
|
activeWorkflowIds: await this.workflowRepository.getActiveIds(),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,11 @@ import Container from 'typedi';
|
||||||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||||
|
|
||||||
import * as testDb from '../../shared/testDb';
|
import * as testDb from '../../shared/testDb';
|
||||||
import { createWorkflowWithTrigger, getAllWorkflows } from '../../shared/db/workflows';
|
import {
|
||||||
|
createWorkflowWithTrigger,
|
||||||
|
createWorkflow,
|
||||||
|
getAllWorkflows,
|
||||||
|
} from '../../shared/db/workflows';
|
||||||
|
|
||||||
describe('WorkflowRepository', () => {
|
describe('WorkflowRepository', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
@ -67,4 +71,27 @@ describe('WorkflowRepository', () => {
|
||||||
expect(after).toMatchObject([{ active: false }, { active: false }]);
|
expect(after).toMatchObject([{ active: false }, { active: false }]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getActiveIds', () => {
|
||||||
|
it('should return active workflow IDs', async () => {
|
||||||
|
//
|
||||||
|
// ARRANGE
|
||||||
|
//
|
||||||
|
const workflows = await Promise.all([
|
||||||
|
createWorkflow({ active: true }),
|
||||||
|
createWorkflow({ active: false }),
|
||||||
|
createWorkflow({ active: false }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ACT
|
||||||
|
//
|
||||||
|
const activeIds = await Container.get(WorkflowRepository).getActiveIds();
|
||||||
|
|
||||||
|
//
|
||||||
|
// ASSERT
|
||||||
|
//
|
||||||
|
expect(activeIds).toEqual([workflows[0].id]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
32
packages/cli/test/integration/usage-metrics.service.test.ts
Normal file
32
packages/cli/test/integration/usage-metrics.service.test.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { mock } from 'jest-mock-extended';
|
||||||
|
import { UsageMetricsService } from '@/services/usageMetrics.service';
|
||||||
|
import type { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||||
|
import type { UsageMetricsRepository } from '@/databases/repositories/usageMetrics.repository';
|
||||||
|
|
||||||
|
describe('UsageMetricsService', () => {
|
||||||
|
const workflowRepository = mock<WorkflowRepository>();
|
||||||
|
const usageMetricsService = new UsageMetricsService(
|
||||||
|
mock<UsageMetricsRepository>(),
|
||||||
|
workflowRepository,
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('getActiveWorkflowIds', () => {
|
||||||
|
test('should return active workflow IDs', async () => {
|
||||||
|
/**
|
||||||
|
* Arrange
|
||||||
|
*/
|
||||||
|
const activeWorkflowIds = ['1', '2'];
|
||||||
|
workflowRepository.getActiveIds.mockResolvedValue(activeWorkflowIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Act
|
||||||
|
*/
|
||||||
|
const result = await usageMetricsService.getActiveWorkflowIds();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert
|
||||||
|
*/
|
||||||
|
expect(result).toEqual({ activeWorkflowIds });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -48,6 +48,7 @@ describe('License', () => {
|
||||||
saveCertStr: expect.any(Function),
|
saveCertStr: expect.any(Function),
|
||||||
onFeatureChange: expect.any(Function),
|
onFeatureChange: expect.any(Function),
|
||||||
collectUsageMetrics: expect.any(Function),
|
collectUsageMetrics: expect.any(Function),
|
||||||
|
collectPassthroughData: expect.any(Function),
|
||||||
server: MOCK_SERVER_URL,
|
server: MOCK_SERVER_URL,
|
||||||
tenantId: 1,
|
tenantId: 1,
|
||||||
});
|
});
|
||||||
|
@ -68,6 +69,7 @@ describe('License', () => {
|
||||||
saveCertStr: expect.any(Function),
|
saveCertStr: expect.any(Function),
|
||||||
onFeatureChange: expect.any(Function),
|
onFeatureChange: expect.any(Function),
|
||||||
collectUsageMetrics: expect.any(Function),
|
collectUsageMetrics: expect.any(Function),
|
||||||
|
collectPassthroughData: expect.any(Function),
|
||||||
server: MOCK_SERVER_URL,
|
server: MOCK_SERVER_URL,
|
||||||
tenantId: 1,
|
tenantId: 1,
|
||||||
});
|
});
|
||||||
|
|
|
@ -550,8 +550,8 @@ importers:
|
||||||
specifier: 0.3.20-10
|
specifier: 0.3.20-10
|
||||||
version: 0.3.20-10(@sentry/node@7.87.0)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.10.0)(pg@8.11.3)(redis@4.6.13)(sqlite3@5.1.7)
|
version: 0.3.20-10(@sentry/node@7.87.0)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.10.0)(pg@8.11.3)(redis@4.6.13)(sqlite3@5.1.7)
|
||||||
'@n8n_io/license-sdk':
|
'@n8n_io/license-sdk':
|
||||||
specifier: 2.12.0
|
specifier: 2.13.0
|
||||||
version: 2.12.0
|
version: 2.13.0
|
||||||
'@oclif/core':
|
'@oclif/core':
|
||||||
specifier: 3.26.6
|
specifier: 3.26.6
|
||||||
version: 3.26.6
|
version: 3.26.6
|
||||||
|
@ -4124,8 +4124,8 @@ packages:
|
||||||
engines: {node: '>=18.10', pnpm: '>=8.6.12'}
|
engines: {node: '>=18.10', pnpm: '>=8.6.12'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
'@n8n_io/license-sdk@2.12.0':
|
'@n8n_io/license-sdk@2.13.0':
|
||||||
resolution: {integrity: sha512-hxXdaFlzd1moR5NWPCdGiKHyIuDTuiM8AYcH5qo2/Cbu93C8za8a0x19q5gZ1ahADRPfO48k9eYMTjxGhqNkBg==}
|
resolution: {integrity: sha512-iVER9RjR6pP4ujceG7rSMoHU0IMI5HvwNHhC8ezq1VwbRq8W1ecYQpTbIrUTgK6gNMyeLRfySkNlVGejKXJ3MQ==}
|
||||||
engines: {node: '>=18.12.1'}
|
engines: {node: '>=18.12.1'}
|
||||||
|
|
||||||
'@n8n_io/riot-tmpl@4.0.0':
|
'@n8n_io/riot-tmpl@4.0.0':
|
||||||
|
@ -17121,7 +17121,7 @@ snapshots:
|
||||||
acorn: 8.11.2
|
acorn: 8.11.2
|
||||||
acorn-walk: 8.2.0
|
acorn-walk: 8.2.0
|
||||||
|
|
||||||
'@n8n_io/license-sdk@2.12.0':
|
'@n8n_io/license-sdk@2.13.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
crypto-js: 4.2.0
|
crypto-js: 4.2.0
|
||||||
node-machine-id: 1.1.12
|
node-machine-id: 1.1.12
|
||||||
|
|
Loading…
Reference in a new issue