Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add featureUsage API to licensing context provider #69838

Merged
merged 4 commits into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion x-pack/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { licensingMock } from './plugins/licensing/server/mocks';
function createCoreRequestHandlerContextMock() {
return {
core: coreMock.createRequestHandlerContext(),
licensing: { license: licensingMock.createLicense() },
licensing: licensingMock.createRequestHandlerContext(),
};
}

Expand Down
4 changes: 1 addition & 3 deletions x-pack/plugins/features/server/routes/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import { FeatureConfig } from '../../common';
function createContextMock(licenseType: LicenseType = 'gold') {
return {
core: coreMock.createRequestHandlerContext(),
licensing: {
license: licensingMock.createLicense({ license: { type: licenseType } }),
},
licensing: licensingMock.createRequestHandlerContext({ license: { type: licenseType } }),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,27 @@
*/

import { BehaviorSubject } from 'rxjs';
import { licenseMock } from '../common/licensing.mock';

import { licenseMock } from '../common/licensing.mock';
import { createRouteHandlerContext } from './licensing_route_handler_context';
import { featureUsageMock } from './services/feature_usage_service.mock';
import { FeatureUsageServiceStart } from './services';
import { StartServicesAccessor } from 'src/core/server';
import { LicensingPluginStart } from './types';

const createStartServices = (
featureUsage: FeatureUsageServiceStart = featureUsageMock.createStart()
): StartServicesAccessor<{}, LicensingPluginStart> => {
return async () => [{} as any, {}, { featureUsage } as LicensingPluginStart];
};

describe('createRouteHandlerContext', () => {
it('returns a function providing the last license value', async () => {
const firstLicense = licenseMock.createLicense();
const secondLicense = licenseMock.createLicense();
const license$ = new BehaviorSubject(firstLicense);

const routeHandler = createRouteHandlerContext(license$);
const routeHandler = createRouteHandlerContext(license$, createStartServices());

const firstCtx = await routeHandler({} as any, {} as any, {} as any);
license$.next(secondLicense);
Expand All @@ -24,4 +34,14 @@ describe('createRouteHandlerContext', () => {
expect(firstCtx.license).toBe(firstLicense);
expect(secondCtx.license).toBe(secondLicense);
});

it('returns a the feature usage API', async () => {
const license$ = new BehaviorSubject(licenseMock.createLicense());
const featureUsage = featureUsageMock.createStart();

const routeHandler = createRouteHandlerContext(license$, createStartServices(featureUsage));
const ctx = await routeHandler({} as any, {} as any, {} as any);

expect(ctx.featureUsage).toBe(featureUsage);
});
});
14 changes: 11 additions & 3 deletions x-pack/plugins/licensing/server/licensing_route_handler_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,29 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { IContextProvider, RequestHandler } from 'src/core/server';
import { IContextProvider, RequestHandler, StartServicesAccessor } from 'src/core/server';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';

import { ILicense } from '../common/types';
import { LicensingPluginStart } from './types';

/**
* Create a route handler context for access to Kibana license information.
* @param license$ An observable of a License instance.
* @public
*/
export function createRouteHandlerContext(
license$: Observable<ILicense>
license$: Observable<ILicense>,
getStartServices: StartServicesAccessor<{}, LicensingPluginStart>
): IContextProvider<RequestHandler<any, any, any>, 'licensing'> {
return async function licensingRouteHandlerContext() {
return { license: await license$.pipe(take(1)).toPromise() };
const [, , { featureUsage }] = await getStartServices();
const license = await license$.pipe(take(1)).toPromise();

return {
featureUsage,
license,
};
};
}
18 changes: 17 additions & 1 deletion x-pack/plugins/licensing/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { BehaviorSubject } from 'rxjs';
import { LicensingPluginSetup, LicensingPluginStart } from './types';
import {
LicensingPluginSetup,
LicensingPluginStart,
LicensingRequestHandlerContext,
} from './types';
import { licenseMock } from '../common/licensing.mock';
import { featureUsageMock } from './services/feature_usage_service.mock';

Expand Down Expand Up @@ -43,8 +47,20 @@ const createStartMock = (): jest.Mocked<LicensingPluginStart> => {
return mock;
};

const createRequestHandlerContextMock = (
...options: Parameters<typeof licenseMock.createLicense>
): jest.Mocked<LicensingRequestHandlerContext> => {
const mock: jest.Mocked<LicensingRequestHandlerContext> = {
license: licenseMock.createLicense(...options),
featureUsage: featureUsageMock.createStart(),
};

return mock;
};

export const licensingMock = {
createSetup: createSetupMock,
createStart: createStartMock,
createRequestHandlerContext: createRequestHandlerContextMock,
...licenseMock,
};
5 changes: 4 additions & 1 deletion x-pack/plugins/licensing/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup, LicensingPl
pollingFrequency.asMilliseconds()
);

core.http.registerRouteHandlerContext('licensing', createRouteHandlerContext(license$));
core.http.registerRouteHandlerContext(
'licensing',
createRouteHandlerContext(license$, core.getStartServices)
);

registerRoutes(core.http.createRouter(), core.getStartServices);
core.http.registerOnPreResponse(createOnPreResponseHandler(refresh, license$));
Expand Down
13 changes: 10 additions & 3 deletions x-pack/plugins/licensing/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,18 @@ export interface RawLicense {
mode: LicenseType;
}

/**
* The APIs exposed on the `licensing` key of {@link RequestHandlerContext} for plugins that depend on licensing.
* @public
*/
export interface LicensingRequestHandlerContext {
featureUsage: FeatureUsageServiceStart;
license: ILicense;
}

declare module 'src/core/server' {
interface RequestHandlerContext {
licensing: {
license: ILicense;
};
licensing: LicensingRequestHandlerContext;
}
}

Expand Down