Skip to content

Commit

Permalink
Fix API tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar committed Apr 13, 2021
1 parent 2832e18 commit b578fa7
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 74 deletions.
1 change: 1 addition & 0 deletions x-pack/plugins/observability/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
],
"requiredPlugins": [
"data",
"alerting",
"ruleRegistry"
],
"ui": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
* 2.0.
*/

import { CoreSetup, PluginInitializerContext, KibanaRequest } from 'kibana/server';
import {
CoreSetup,
PluginInitializerContext,
KibanaRequest,
RequestHandlerContext,
} from 'kibana/server';
import { LicensingApiRequestHandlerContext } from '../../../../licensing/server';
import { PromiseReturnType } from '../../../typings/common';
import { createAnnotationsClient } from './create_annotations_client';
import { registerAnnotationAPIs } from './register_annotation_apis';
import type { ObservabilityRequestHandlerContext } from '../../types';

interface Params {
index: string;
Expand All @@ -35,7 +40,7 @@ export async function bootstrapAnnotations({ index, core, context }: Params) {

return {
getScopedAnnotationsClient: (
requestContext: ObservabilityRequestHandlerContext,
requestContext: RequestHandlerContext & { licensing: LicensingApiRequestHandlerContext },
request: KibanaRequest
) => {
return createAnnotationsClient({
Expand Down
6 changes: 4 additions & 2 deletions x-pack/plugins/observability/server/routes/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ const alertsListRoute = createObservabilityServerRoute({
]),
}),
handler: async ({ ruleRegistry, context, params }) => {
const ruleRegistryClient = ruleRegistry.createScopedRuleRegistryClient({
const ruleRegistryClient = await ruleRegistry.createScopedRuleRegistryClient({
context,
alertsClient: context.alerting.getAlertsClient(),
});

if (!ruleRegistryClient) {
Expand All @@ -57,8 +58,9 @@ const alertsDynamicIndexPatternRoute = createObservabilityServerRoute({
tags: [],
},
handler: async ({ ruleRegistry, context }) => {
const ruleRegistryClient = ruleRegistry.createScopedRuleRegistryClient({
const ruleRegistryClient = await ruleRegistry.createScopedRuleRegistryClient({
context,
alertsClient: context.alerting.getAlertsClient(),
});

if (!ruleRegistryClient) {
Expand Down
5 changes: 3 additions & 2 deletions x-pack/plugins/observability/server/routes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import type {
ServerRoute,
ServerRouteRepository,
} from '@kbn/server-route-repository';
import { CoreSetup, CoreStart, KibanaRequest, Logger, RequestHandlerContext } from 'kibana/server';
import { CoreSetup, CoreStart, KibanaRequest, Logger } from 'kibana/server';
import { ObservabilityRuleRegistry } from '../plugin';

import { ObservabilityServerRouteRepository } from './get_global_observability_server_route_repository';
import { ObservabilityRequestHandlerContext } from '../types';

export { ObservabilityServerRouteRepository };

Expand All @@ -25,7 +26,7 @@ export interface ObservabilityRouteHandlerResources {
};
ruleRegistry: ObservabilityRuleRegistry;
request: KibanaRequest;
context: RequestHandlerContext;
context: ObservabilityRequestHandlerContext;
logger: Logger;
}

Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/observability/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import type { IRouter, RequestHandlerContext } from 'src/core/server';
import type { AlertingApiRequestHandlerContext } from '../../alerting/server';
import type { ScopedRuleRegistryClient, FieldMapOf } from '../../rule_registry/server';
import type { LicensingApiRequestHandlerContext } from '../../licensing/server';
import type { ObservabilityRuleRegistry } from './plugin';
Expand All @@ -23,6 +24,7 @@ export type {
*/
export interface ObservabilityRequestHandlerContext extends RequestHandlerContext {
licensing: LicensingApiRequestHandlerContext;
alerting: AlertingApiRequestHandlerContext;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import { Either, isLeft, isRight } from 'fp-ts/lib/Either';
import { Errors } from 'io-ts';
import { PathReporter } from 'io-ts/lib/PathReporter';
import { Logger, SavedObjectsClientContract } from 'kibana/server';
import { Logger } from 'kibana/server';
import { IScopedClusterClient as ScopedClusterClient } from 'src/core/server';
import { castArray, compact } from 'lodash';
import { ESSearchRequest } from 'typings/elasticsearch';
Expand All @@ -18,53 +18,24 @@ import { ScopedRuleRegistryClient, EventsOf } from './types';
import { BaseRuleFieldMap } from '../../../common';
import { RuleRegistry } from '..';

const getRuleUuids = async ({
savedObjectsClient,
namespace,
}: {
savedObjectsClient: SavedObjectsClientContract;
namespace?: string;
}) => {
const options = {
type: 'alert',
...(namespace ? { namespace } : {}),
};

const pitFinder = savedObjectsClient.createPointInTimeFinder({
...options,
});

const ruleUuids: string[] = [];

for await (const response of pitFinder.find()) {
ruleUuids.push(...response.saved_objects.map((object) => object.id));
}

await pitFinder.close();

return ruleUuids;
};

const createPathReporterError = (either: Either<Errors, unknown>) => {
const error = new Error(`Failed to validate alert event`);
error.stack += '\n' + PathReporter.report(either).join('\n');
return error;
};

export function createScopedRuleRegistryClient<TFieldMap extends BaseRuleFieldMap>({
ruleUuids,
scopedClusterClient,
savedObjectsClient,
namespace,
clusterClientAdapter,
indexAliasName,
indexTarget,
logger,
registry,
ruleData,
}: {
ruleUuids: string[];
scopedClusterClient: ScopedClusterClient;
savedObjectsClient: SavedObjectsClientContract;
namespace?: string;
clusterClientAdapter: ClusterClientAdapter<{
body: TypeOfFieldMap<TFieldMap>;
index: string;
Expand Down Expand Up @@ -99,11 +70,6 @@ export function createScopedRuleRegistryClient<TFieldMap extends BaseRuleFieldMa

const client: ScopedRuleRegistryClient<BaseRuleFieldMap> = {
search: async (searchRequest) => {
const ruleUuids = await getRuleUuids({
savedObjectsClient,
namespace,
});

const fields = [
'rule.id',
...(searchRequest.body?.fields ? castArray(searchRequest.body.fields) : []),
Expand Down
22 changes: 16 additions & 6 deletions x-pack/plugins/rule_registry/server/rule_registry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { CoreSetup, Logger, RequestHandlerContext } from 'kibana/server';
import { inspect } from 'util';
import { AlertsClient } from '../../../alerting/server';
import { SpacesServiceStart } from '../../../spaces/server';
import {
ActionVariable,
Expand Down Expand Up @@ -207,18 +208,28 @@ export class RuleRegistry<TFieldMap extends BaseRuleFieldMap> {
return this.children.find((child) => child.getRegistryByRuleTypeId(ruleTypeId));
}

createScopedRuleRegistryClient({
async createScopedRuleRegistryClient({
context,
alertsClient,
}: {
context: RequestHandlerContext;
}): ScopedRuleRegistryClient<TFieldMap> | undefined {
alertsClient: AlertsClient;
}): Promise<ScopedRuleRegistryClient<TFieldMap> | undefined> {
if (!this.options.writeEnabled) {
return undefined;
}
const { indexAliasName, indexTarget } = this.getEsNames();

const frameworkAlerts = (
await alertsClient.find({
options: {
perPage: 1000,
},
})
).data;

return createScopedRuleRegistryClient({
savedObjectsClient: context.core.savedObjects.getClient({ includedHiddenTypes: ['alert'] }),
ruleUuids: frameworkAlerts.map((frameworkAlert) => frameworkAlert.id),
scopedClusterClient: context.core.elasticsearch.client,
clusterClientAdapter: this.esAdapter,
registry: this,
Expand Down Expand Up @@ -246,7 +257,7 @@ export class RuleRegistry<TFieldMap extends BaseRuleFieldMap> {
>({
...type,
executor: async (executorOptions) => {
const { services, namespace, alertId, name, tags } = executorOptions;
const { services, alertId, name, tags } = executorOptions;

const rule = {
id: type.id,
Expand All @@ -267,13 +278,12 @@ export class RuleRegistry<TFieldMap extends BaseRuleFieldMap> {
...(this.options.writeEnabled
? {
scopedRuleRegistryClient: createScopedRuleRegistryClient({
savedObjectsClient: services.savedObjectsClient,
scopedClusterClient: services.scopedClusterClient,
ruleUuids: [rule.uuid],
clusterClientAdapter: this.esAdapter,
registry: this,
indexAliasName,
indexTarget,
namespace,
ruleData: {
producer,
rule,
Expand Down
70 changes: 46 additions & 24 deletions x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import expect from '@kbn/expect';
import { get, merge, omit } from 'lodash';
import { format } from 'url';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { registry } from '../../common/registry';

Expand Down Expand Up @@ -335,33 +336,54 @@ export default function ApiTest({ getService }: FtrProviderContext) {
any
>;

const toCompare = omit(
alertEvent,
expect(alertEvent['event.action']);

const exclude = [
'@timestamp',
'kibana.rac.alert.start',
'kibana.rac.alert.uuid',
'rule.uuid'
);

expectSnapshot(toCompare).toMatchInline(`
Object {
"event.action": "open",
"event.kind": "state",
"kibana.rac.alert.duration.us": 0,
"kibana.rac.alert.id": "apm.transaction_error_rate_opbeans-go_request",
"kibana.rac.alert.status": "open",
"kibana.rac.producer": "apm",
"rule.category": "Transaction error rate threshold",
"rule.id": "apm.transaction_error_rate",
"rule.name": "Transaction error rate threshold | opbeans-go",
"service.name": "opbeans-go",
"tags": Array [
"apm",
"service.name:opbeans-go",
],
"transaction.type": "request",
}
`);
'rule.uuid',
];

const toCompare = omit(alertEvent, exclude);

expect(toCompare).to.eql({
'event.action': 'open',
'event.kind': 'state',
'kibana.rac.alert.duration.us': 0,
'kibana.rac.alert.id': 'apm.transaction_error_rate_opbeans-go_request',
'kibana.rac.alert.status': 'open',
'kibana.rac.producer': 'apm',
'kibana.observability.evaluation.threshold': 30,
'kibana.observability.evaluation.value': 50,
'processor.event': 'transaction',
'rule.category': 'Transaction error rate threshold',
'rule.id': 'apm.transaction_error_rate',
'rule.name': 'Transaction error rate threshold | opbeans-go',
'service.name': 'opbeans-go',
tags: ['apm', 'service.name:opbeans-go'],
'transaction.type': 'request',
});

const now = new Date().getTime();

const { body: topAlerts, status: topAlertStatus } = await supertest
.get(
format({
pathname: '/api/observability/rules/alerts/top',
query: {
start: new Date(now - 30 * 60 * 1000).toISOString(),
end: new Date(now).toISOString(),
},
})
)
.set('kbn-xsrf', 'foo');

expect(topAlertStatus).to.eql(200);

expect(topAlerts.length).to.be.greaterThan(0);

expect(omit(topAlerts[0], exclude)).to.eql(toCompare);
});
});
});
Expand Down

0 comments on commit b578fa7

Please sign in to comment.