1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-17 01:17:29 +02:00

feat: start capturing onboarded status also from register endpoint

This commit is contained in:
sjaanus 2024-10-08 12:24:11 +03:00
parent 9c22658b5d
commit c42093b7b3
No known key found for this signature in database
GPG Key ID: 20E007C0248BA7FF
14 changed files with 73 additions and 15 deletions

View File

@ -18,7 +18,6 @@ public class Program
{
AppName = "unleash-onboarding-dotnet",
UnleashApi = new Uri("<YOUR_API_URL>"),
SendMetricsInterval = TimeSpan.FromSeconds(1), // in production remove this or increase to >=15s
CustomHttpHeaders = new Dictionary<string, string>()
{
{"Authorization","<YOUR_API_TOKEN>"} // in production use environment variable

View File

@ -19,7 +19,6 @@ func init() {
unleash.WithAppName("unleash-onboarding-golang"),
unleash.WithUrl("<YOUR_API_URL>"),
unleash.WithCustomHeaders(http.Header{"Authorization": {"<YOUR_API_TOKEN>"}}), // in production use environment variable
unleash.WithMetricsInterval(1*time.Second), // in production remove this or increase to >=15s
)
}

View File

@ -14,7 +14,6 @@ UnleashConfig config = UnleashConfig.builder()
.instanceId("unleash-onboarding-instance")
.unleashAPI("<YOUR_API_URL>")
.apiKey("<YOUR_API_TOKEN>") // in production use environment variable
.sendMetricsInterval(1) // in production remove this or increase to >=15
.build();
Unleash unleash = new DefaultUnleash(config);

View File

@ -11,7 +11,6 @@ const unleash = new UnleashClient({
url: '<YOUR_API_URL>',
clientKey: '<YOUR_API_TOKEN>', // in production use environment variable
appName: 'unleash-onboarding-javascript',
metricsInterval: 1000, // in production remove this or increase to >=15000
});
unleash.start();

View File

@ -13,7 +13,6 @@ const unleash = initialize({
customHeaders: {
Authorization: '<YOUR_API_TOKEN>' // in production use environment variable
},
metricsInterval: 1000, // in production remove this or increase to >=15000
});
setInterval(() => {

View File

@ -16,7 +16,6 @@ $unleash = UnleashBuilder::create()
->withAppUrl('<YOUR_API_URL>')
->withHeader('Authorization', '<YOUR_API_TOKEN>') // in production use environment variable
->withInstanceId('unleash-onboarding-instance')
->withMetricsInterval(1000) // in production remove this or increase to >=15000
->build();
while (true) {

View File

@ -11,7 +11,6 @@ import asyncio
client = UnleashClient(
url="<YOUR_API_URL>",
app_name="unleash-onboarding-python",
metrics_interval=1, # in production remove this or increase to >=15
custom_headers={'Authorization': '<YOUR_API_TOKEN>'}) # in production use environment variable
client.initialize_client()

View File

@ -11,7 +11,6 @@ import { FlagProvider } from '@unleash/proxy-client-react';
const config = {
url: '<YOUR_API_URL>',
clientKey: '<YOUR_API_TOKEN>', // in production use environment variable
metricsInterval: 1, // In production use interval of >15s
appName: 'unleash-onboarding-react',
};

View File

@ -12,7 +12,6 @@ require 'unleash'
custom_http_headers: { 'Authorization': "<YOUR_API_TOKEN>" }, # in production use environment variable
app_name: 'unleash-onboarding-ruby',
instance_id: 'unleash-onboarding-ruby',
metrics_interval: 3, # In production use interval of >15s
)
while true

View File

@ -26,7 +26,6 @@ enum Flags {
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let client: Client<Flags, reqwest::Client> = ClientBuilder::default()
.interval(1000) // in production remove this or increase to >=15000
.into_client(
"<YOUR_API_URL>",
"unleash-onboarding-rust",
@ -55,7 +54,6 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let api_token = env::var("UNLEASH_API_TOKEN").expect("UNLEASH_API_TOKEN environment variable not set");
let client: Client<Flags, reqwest::Client> = ClientBuilder::default()
.interval(1000) // Polling & metrics interval - default 15000 (ms)
.into_client(
"<YOUR_API_URL>",
"unleash-onboarding-rust",

View File

@ -12,7 +12,6 @@ npm install @unleash/proxy-client-svelte
url: '<YOUR_API_URL>',
clientKey: '<YOUR_API_TOKEN>', // in production use environment variable
appName: 'unleash-onboarding-svelte',
metricsInterval: 1, // in production remove this or increase to >=15
};
</script>

View File

@ -12,7 +12,6 @@ npm install @unleash/proxy-client-vue
url: '<YOUR_API_URL>',
clientKey: '<YOUR_API_TOKEN>', // in production use environment variable
appName: 'unleash-onboarding-vue',
metricsInterval: 1, // in production remove this or increase to >=15
}
</script>

View File

@ -7,21 +7,43 @@ import {
SYSTEM_USER,
} from '../../types';
import type { IOnboardingReadModel } from './onboarding-read-model-type';
import type ClientInstanceService from '../metrics/instance/instance-service';
import {
type IUnleashTest,
setupAppWithCustomConfig,
} from '../../../test/e2e/helpers/test-helper';
import { ApiTokenType } from '../../types/models/api-token';
let db: ITestDb;
let onboardingReadModel: IOnboardingReadModel;
let onBoardingStore: IOnboardingStore;
let featureToggleStore: IFeatureToggleStore;
let lastSeenStore: ILastSeenStore;
let instanceService: ClientInstanceService;
let app: IUnleashTest;
beforeAll(async () => {
db = await dbInit('onboarding_read_model', getLogger, {
experimental: { flags: { onboardingMetrics: true } },
});
app = await setupAppWithCustomConfig(
db.stores,
{
experimental: {
flags: {
strictSchemaValidation: true,
},
},
},
db.rawDatabase,
);
onboardingReadModel = db.stores.onboardingReadModel;
onBoardingStore = db.stores.onboardingStore;
featureToggleStore = db.stores.featureToggleStore;
lastSeenStore = db.stores.lastSeenStore;
instanceService = app.services.clientInstanceService;
});
afterAll(async () => {
@ -178,3 +200,38 @@ test('archived feature counts as onboarded', async () => {
status: 'onboarded',
});
});
test('sdk register also onboards a project', async () => {
await featureToggleStore.create('default', {
name: 'my-flag',
createdByUserId: SYSTEM_USER.id,
});
const defaultProjectToken =
await app.services.apiTokenService.createApiTokenWithProjects({
type: ApiTokenType.CLIENT,
projects: ['default'],
environment: 'default',
tokenName: 'tester',
});
await app.request
.post('/api/client/register')
.set('Authorization', defaultProjectToken.secret)
.send({
appName: 'multi-project-app',
instanceId: 'instance-1',
strategies: ['default'],
started: Date.now(),
interval: 10,
});
await instanceService.bulkAdd();
const onboardedResult =
await onboardingReadModel.getOnboardingStatusForProject('default');
expect(onboardedResult).toMatchObject({
status: 'onboarded',
});
});

View File

@ -101,11 +101,25 @@ export class OnboardingReadModel implements IOnboardingReadModel {
return { status: 'onboarding-started' };
}
const lastSeen = await this.db('last_seen_at_metrics as lsm')
.select('lsm.feature_name')
// const lastSeen = await this.db('last_seen_at_metrics as lsm')
// .select('lsm.feature_name')
// .innerJoin('features as f', 'f.name', 'lsm.feature_name')
// .innerJoin('projects as p', 'p.id', 'f.project')
// .where('p.id', projectId)
// .first();
const db = this.db;
const lastSeen = await db
.select(db.raw('1'))
.from('last_seen_at_metrics as lsm')
.innerJoin('features as f', 'f.name', 'lsm.feature_name')
.innerJoin('projects as p', 'p.id', 'f.project')
.where('p.id', projectId)
.union((qb) => {
qb.select(db.raw('1'))
.from('client_applications_usage as cau')
.where('cau.project', projectId);
})
.first();
if (lastSeen) {