Skip to content
This repository has been archived by the owner on Aug 9, 2022. It is now read-only.

Migrate all Kibana server side APIs to call ES-reporting APIs #177

Merged
11 changes: 11 additions & 0 deletions kibana-reports/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,14 @@ export const REPORTS_SCHEDULER_API = {
export const NOTIFICATION_API = {
SEND: '/_opendistro/_notifications/send',
};

const BASE_REPORTS_URI = '/_opendistro/_reports';

export const ES_REPORTS_API = {
ON_DEMAND_REPORT: `${BASE_REPORTS_URI}/on_demand`,
REPORT_INSTANCE: `${BASE_REPORTS_URI}/instance`,
LIST_REPORT_INSTANCES: `${BASE_REPORTS_URI}/instances`,
REPORT_DEFINITION: `${BASE_REPORTS_URI}/definition`,
LIST_REPORT_DEFINITIONS: `${BASE_REPORTS_URI}/definitions`,
POLL_REPORT_INSTANCE: `${BASE_REPORTS_URI}/poll_instance`,
};
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const getTimeFieldsFromUrl = () => {
let toDateFormat = dateMath.parse(toDateString);

const timeDuration = moment.duration(
dateMath.parse(fromDateString).diff(dateMath.parse(toDateString))
dateMath.parse(toDateString).diff(dateMath.parse(fromDateString))
);

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export const EmailDelivery = (props: ReportDeliveryProps) => {

setEmailSubject(title);
reportDefinitionRequest.delivery.delivery_params.title = title;
reportDefinitionRequest.delivery.delivery_params.origin = location.origin;
handleEmailBody(textDescription);
}
};
Expand All @@ -114,8 +113,6 @@ export const EmailDelivery = (props: ReportDeliveryProps) => {
reportDefinitionRequest.delivery.delivery_params = {
recipients: selectedEmailRecipients.map((option) => option.label),
title: emailSubject,
origin: location.origin,
//TODO: need better render
textDescription: emailBody,
htmlDescription: converter.makeHtml(emailBody),
};
Expand Down
150 changes: 150 additions & 0 deletions kibana-reports/server/backend/opendistro-es-reports-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import { ES_REPORTS_API } from '../../common';

export default function (Client: any, config: any, components: any) {
const clientAction = components.clientAction.factory;

Client.prototype.es_reports = components.clientAction.namespaceFactory();
const esReports = Client.prototype.es_reports.prototype;

/**
* report related APIs
*/
esReports.createReport = clientAction({
url: {
fmt: `${ES_REPORTS_API.ON_DEMAND_REPORT}`,
},
method: 'PUT',
needBody: true,
});

esReports.updateReportInstanceStatus = clientAction({
url: {
fmt: `${ES_REPORTS_API.REPORT_INSTANCE}?id=<%=reportId%>`,
req: {
reportId: {
type: 'string',
required: true,
},
},
},
method: 'POST',
needBody: true,
});

esReports.getReportById = clientAction({
url: {
fmt: `${ES_REPORTS_API.REPORT_INSTANCE}?id=<%=reportId%>`,
req: {
reportId: {
type: 'string',
required: true,
},
},
},
method: 'GET',
});

esReports.getReports = clientAction({
url: {
fmt: `${ES_REPORTS_API.LIST_REPORT_INSTANCES}`,
//TODO: wrong format error thrown even required = false, need to figure it out the correct setting to make it truly optional
// req: {
// fromIndex: {
// type: 'string',
// required: false,
// },
// },
},
method: 'GET',
});

/**
* report definition related APIs
*/
esReports.createReportDefinition = clientAction({
url: {
fmt: `${ES_REPORTS_API.REPORT_DEFINITION}`,
},
method: 'POST',
needBody: true,
});

esReports.updateReportDefinitionById = clientAction({
url: {
fmt: `${ES_REPORTS_API.REPORT_DEFINITION}?id=<%=reportDefinitionId%>`,
req: {
reportDefinitionId: {
type: 'string',
required: true,
},
},
},
method: 'PUT',
needBody: true,
});

esReports.getReportDefinitionById = clientAction({
url: {
fmt: `${ES_REPORTS_API.REPORT_DEFINITION}?id=<%=reportDefinitionId%>`,
req: {
reportDefinitionId: {
type: 'string',
required: true,
},
},
},
method: 'GET',
});

esReports.getReportDefinitions = clientAction({
url: {
fmt: `${ES_REPORTS_API.LIST_REPORT_DEFINITIONS}`,
//TODO: wrong format error thrown even required = false, need to figure it out the correct setting to make it truly optional
// req: {
// fromIndex: {
// type: 'string',
// required: false,
// },
// },
},
method: 'GET',
});

esReports.deleteReportDefinitionById = clientAction({
url: {
fmt: `${ES_REPORTS_API.REPORT_DEFINITION}?id=<%=reportDefinitionId%>`,
req: {
reportDefinitionId: {
type: 'string',
required: true,
},
},
},
method: 'DELETE',
});

/**
* Poller API
*/
esReports.pollReportInstance = clientAction({
url: {
fmt: `${ES_REPORTS_API.POLL_REPORT_INSTANCE}`,
},
method: 'GET',
});
}
32 changes: 14 additions & 18 deletions kibana-reports/server/executor/createScheduledReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
REPORT_STATE,
LOCAL_HOST,
} from '../routes/utils/constants';
import { updateReportState, saveReport } from '../routes/utils/helpers';
import { updateReportState } from '../routes/utils/helpers';
import { ILegacyClusterClient, Logger } from '../../../../src/core/server';
import { createSavedSearchReport } from '../routes/utils/savedSearchReportHelper';
import { ReportSchemaType } from '../model';
Expand All @@ -27,25 +27,23 @@ import { createVisualReport } from '../routes/utils/visualReportHelper';
import { deliverReport } from '../routes/lib/deliverReport';

export const createScheduledReport = async (
reportId: string,
report: ReportSchemaType,
esClient: ILegacyClusterClient,
esReportsClient: ILegacyClusterClient,
notificationClient: ILegacyClusterClient,
logger: Logger
): Promise<CreateReportResultType> => {
const isScheduledTask = true;
let createReportResult: CreateReportResultType;
let reportId;
// create new report instance and set report state to "pending"

const esResp = await saveReport(isScheduledTask, report, esClient);
reportId = esResp._id;
const {
report_definition: { report_params: reportParams },
} = report;
const { report_source: reportSource } = reportParams;

const reportDefinition = report.report_definition;
const reportParams = reportDefinition.report_params;
const reportSource = reportParams.report_source;

// compose url
const queryUrl = `${LOCAL_HOST}${report.query_url}`;
// compose url with localhost
const completeQueryUrl = `${LOCAL_HOST}${report.query_url}`;
try {
// generate report
if (reportSource === REPORT_TYPE.savedSearch) {
Expand All @@ -58,37 +56,35 @@ export const createScheduledReport = async (
// report source can only be one of [saved search, visualization, dashboard]
createReportResult = await createVisualReport(
reportParams,
queryUrl,
completeQueryUrl,
logger
);
}

await updateReportState(
isScheduledTask,
reportId,
esClient,
REPORT_STATE.created,
createReportResult
esReportsClient,
REPORT_STATE.created
);

// deliver report
createReportResult = await deliverReport(
report,
createReportResult,
notificationClient,
esClient,
esReportsClient,
reportId,
isScheduledTask,
logger
);
} catch (error) {
// update report instance with "error" state
//TODO: save error detail and display on UI

await updateReportState(
isScheduledTask,
reportId,
esClient,
esReportsClient,
REPORT_STATE.error
);
throw error;
Expand Down
Loading