Skip to content

Commit

Permalink
[ML] Typescripting client side endpoint functions (#59928)
Browse files Browse the repository at this point in the history
* [ML] Typescripting client side endpoint functions

* type clean up

* cleaning up http requests

* remove http generics

* better use of generics and type clean up

* removes some generics

* update comment

* updating data frame analytics types

* fixing type errors
  • Loading branch information
jgowdyelastic committed Mar 12, 2020
1 parent 078ff55 commit bacc746
Show file tree
Hide file tree
Showing 27 changed files with 1,282 additions and 1,336 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class AnnotationFlyoutUI extends Component<CommonProps & Props> {
const { annotation } = this.props;
const toastNotifications = getToastNotifications();

if (annotation === null) {
if (annotation === null || annotation._id === undefined) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ import { IIndexPattern } from '../../../../../../../../../../../src/plugins/data
import { newJobCapsService } from '../../../../../services/new_job_capabilities_service';
import { useMlContext } from '../../../../../contexts/ml';

interface GetDataFrameAnalyticsResponse {
count: number;
data_frame_analytics: DataFrameAnalyticsConfig[];
}

export const ExplorationTitle: React.FC<{ jobId: string }> = ({ jobId }) => (
<EuiTitle size="xs">
<span>
Expand Down Expand Up @@ -69,9 +64,7 @@ export const ClassificationExploration: FC<Props> = ({ jobId, jobStatus }) => {
const loadJobConfig = async () => {
setIsLoadingJobConfig(true);
try {
const analyticsConfigs: GetDataFrameAnalyticsResponse = await ml.dataFrameAnalytics.getDataFrameAnalytics(
jobId
);
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId);
if (
Array.isArray(analyticsConfigs.data_frame_analytics) &&
analyticsConfigs.data_frame_analytics.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ import { useMlContext } from '../../../../../contexts/ml';

const FEATURE_INFLUENCE = 'feature_influence';

interface GetDataFrameAnalyticsResponse {
count: number;
data_frame_analytics: DataFrameAnalyticsConfig[];
}

const PAGE_SIZE_OPTIONS = [5, 10, 25, 50];

const ExplorationTitle: React.FC<{ jobId: string }> = ({ jobId }) => (
Expand Down Expand Up @@ -130,9 +125,7 @@ export const Exploration: FC<Props> = React.memo(({ jobId, jobStatus }) => {

useEffect(() => {
(async function() {
const analyticsConfigs: GetDataFrameAnalyticsResponse = await ml.dataFrameAnalytics.getDataFrameAnalytics(
jobId
);
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId);
if (
Array.isArray(analyticsConfigs.data_frame_analytics) &&
analyticsConfigs.data_frame_analytics.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ import { IIndexPattern } from '../../../../../../../../../../../src/plugins/data
import { newJobCapsService } from '../../../../../services/new_job_capabilities_service';
import { useMlContext } from '../../../../../contexts/ml';

interface GetDataFrameAnalyticsResponse {
count: number;
data_frame_analytics: DataFrameAnalyticsConfig[];
}

export const ExplorationTitle: React.FC<{ jobId: string }> = ({ jobId }) => (
<EuiTitle size="xs">
<span>
Expand Down Expand Up @@ -69,9 +64,7 @@ export const RegressionExploration: FC<Props> = ({ jobId, jobStatus }) => {
const loadJobConfig = async () => {
setIsLoadingJobConfig(true);
try {
const analyticsConfigs: GetDataFrameAnalyticsResponse = await ml.dataFrameAnalytics.getDataFrameAnalytics(
jobId
);
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId);
if (
Array.isArray(analyticsConfigs.data_frame_analytics) &&
analyticsConfigs.data_frame_analytics.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const deleteAnalytics = async (d: DataFrameAnalyticsListRow) => {
const toastNotifications = getToastNotifications();
try {
if (isDataFrameAnalyticsFailed(d.stats.state)) {
await ml.dataFrameAnalytics.stopDataFrameAnalytics(d.config.id, true, true);
await ml.dataFrameAnalytics.stopDataFrameAnalytics(d.config.id, true);
}
await ml.dataFrameAnalytics.deleteDataFrameAnalytics(d.config.id);
toastNotifications.addSuccess(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { GetDataFrameAnalyticsStatsResponseOk } from '../../../../../services/ml_api_service';
import { GetDataFrameAnalyticsStatsResponseOk } from '../../../../../services/ml_api_service/data_frame_analytics';
import { getAnalyticsJobsStats } from './get_analytics';
import { DATA_FRAME_TASK_STATE } from '../../components/analytics_list/common';

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

import { i18n } from '@kbn/i18n';
import { ml } from '../../../../../services/ml_api_service';
import {
GetDataFrameAnalyticsStatsResponse,
GetDataFrameAnalyticsStatsResponseError,
GetDataFrameAnalyticsStatsResponseOk,
ml,
} from '../../../../../services/ml_api_service';
import {
DataFrameAnalyticsConfig,
REFRESH_ANALYTICS_LIST_STATE,
refreshAnalyticsList$,
} from '../../../../common';
} from '../../../../../services/ml_api_service/data_frame_analytics';
import { REFRESH_ANALYTICS_LIST_STATE, refreshAnalyticsList$ } from '../../../../common';

import {
DATA_FRAME_MODE,
Expand All @@ -27,11 +22,6 @@ import {
} from '../../components/analytics_list/common';
import { AnalyticStatsBarStats } from '../../../../../components/stats_bar';

interface GetDataFrameAnalyticsResponse {
count: number;
data_frame_analytics: DataFrameAnalyticsConfig[];
}

export const isGetDataFrameAnalyticsStatsResponseOk = (
arg: any
): arg is GetDataFrameAnalyticsStatsResponseOk => {
Expand Down Expand Up @@ -125,8 +115,8 @@ export const getAnalyticsFactory = (
}

try {
const analyticsConfigs: GetDataFrameAnalyticsResponse = await ml.dataFrameAnalytics.getDataFrameAnalytics();
const analyticsStats: GetDataFrameAnalyticsStatsResponse = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats();
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics();
const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats();

const analyticsStatsResult = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats)
? getAnalyticsJobsStats(analyticsStats)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ export const stopAnalytics = async (d: DataFrameAnalyticsListRow) => {
try {
await ml.dataFrameAnalytics.stopDataFrameAnalytics(
d.config.id,
isDataFrameAnalyticsFailed(d.stats.state),
true
isDataFrameAnalyticsFailed(d.stats.state)
);
toastNotifications.addSuccess(
i18n.translate('xpack.ml.dataframe.analyticsList.stopAnalyticsSuccessMessage', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@ function randomNumber(min, max) {
}

function saveWatch(watchModel) {
const path = '/api/watcher';
const url = `${path}/watch/${watchModel.id}`;
const path = `/api/watcher/watch/${watchModel.id}`;

return http({
url,
path,
method: 'PUT',
data: watchModel.upstreamJSON,
body: JSON.stringify(watchModel.upstreamJSON),
});
}

Expand Down Expand Up @@ -187,10 +186,9 @@ class CreateWatchService {

loadWatch(jobId) {
const id = `ml-${jobId}`;
const path = '/api/watcher';
const url = `${path}/watch/${id}`;
const path = `/api/watcher/watch/${id}`;
return http({
url,
path,
method: 'GET',
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ml,
} from '../../../../services/ml_api_service';
import { JobCreator } from '../job_creator';
import { CombinedJob } from '../../../../../../common/types/anomaly_detection_jobs';

export enum VALIDATOR_SEVERITY {
ERROR,
Expand Down Expand Up @@ -57,7 +58,7 @@ export function cardinalityValidator(
return ml.validateCardinality$({
...jobCreator.jobConfig,
datafeed_config: jobCreator.datafeedConfig,
});
} as CombinedJob);
}),
map(validationResults => {
for (const validationResult of validationResults) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ import { ml } from '../../../services/ml_api_service';
import { useMlContext } from '../../../contexts/ml';
import {
DatafeedResponse,
DataRecognizerConfigResponse,
JobOverride,
JobResponse,
KibanaObject,
KibanaObjectResponse,
Module,
ModuleJob,
} from '../../../../../common/types/modules';
import { mlJobService } from '../../../services/job_service';
Expand Down Expand Up @@ -106,7 +104,7 @@ export const Page: FC<PageProps> = ({ moduleId, existingGroupIds }) => {
*/
const loadModule = async () => {
try {
const response: Module = await ml.getDataRecognizerModule({ moduleId });
const response = await ml.getDataRecognizerModule({ moduleId });
setJobs(response.jobs);

const kibanaObjectsResult = await checkForSavedObjects(response.kibana as KibanaObjects);
Expand Down Expand Up @@ -165,7 +163,7 @@ export const Page: FC<PageProps> = ({ moduleId, existingGroupIds }) => {
let jobOverridesPayload: JobOverride[] | null = Object.values(jobOverrides);
jobOverridesPayload = jobOverridesPayload.length > 0 ? jobOverridesPayload : null;

const response: DataRecognizerConfigResponse = await ml.setupDataRecognizerConfig({
const response = await ml.setupDataRecognizerConfig({
moduleId,
prefix: resultJobPrefix,
query: tempQuery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { Observable } from 'rxjs';

import { HttpFetchOptionsWithPath, HttpFetchOptions } from 'kibana/public';
import { getHttp } from '../util/dependency_cache';

function getResultHeaders(headers: HeadersInit): HeadersInit {
Expand All @@ -16,64 +16,40 @@ function getResultHeaders(headers: HeadersInit): HeadersInit {
} as HeadersInit;
}

interface HttpOptions {
url: string;
method: string;
headers?: any;
data?: any;
function getFetchOptions(
options: HttpFetchOptionsWithPath
): { path: string; fetchOptions: HttpFetchOptions } {
if (!options.path) {
throw new Error('URL path is missing');
}
return {
path: options.path,
fetchOptions: {
credentials: 'same-origin',
method: options.method || 'GET',
...(options.body ? { body: options.body } : {}),
...(options.query ? { query: options.query } : {}),
headers: getResultHeaders(options.headers ?? {}),
},
};
}

/**
* Function for making HTTP requests to Kibana's backend.
* Wrapper for Kibana's HttpHandler.
*/
export async function http(options: HttpOptions) {
if (!options?.url) {
throw new Error('URL is missing');
}

try {
let url = '';
url = url + (options.url || '');
const headers = getResultHeaders(options.headers ?? {});

const allHeaders = options.headers === undefined ? headers : { ...options.headers, ...headers };
const body = options.data === undefined ? null : JSON.stringify(options.data);

const payload: RequestInit = {
method: options.method || 'GET',
headers: allHeaders,
credentials: 'same-origin',
};

if (body !== null) {
payload.body = body;
}

return await getHttp().fetch(url, payload);
} catch (e) {
throw new Error(e);
}
}

interface RequestOptions extends RequestInit {
body: BodyInit | any;
export async function http<T>(options: HttpFetchOptionsWithPath): Promise<T> {
const { path, fetchOptions } = getFetchOptions(options);
return getHttp().fetch<T>(path, fetchOptions);
}

/**
* Function for making HTTP requests to Kibana's backend which returns an Observable
* with request cancellation support.
*/
export function http$<T>(url: string, options: RequestOptions): Observable<T> {
const requestInit: RequestInit = {
...options,
credentials: 'same-origin',
method: options.method || 'GET',
...(options.body ? { body: JSON.stringify(options.body) as string } : {}),
headers: getResultHeaders(options.headers ?? {}),
};

return fromHttpHandler<T>(url, requestInit);
export function http$<T>(options: HttpFetchOptionsWithPath): Observable<T> {
const { path, fetchOptions } = getFetchOptions(options);
return fromHttpHandler<T>(path, fetchOptions);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,24 @@ export const annotations = {
latestMs: number;
maxAnnotations: number;
}) {
return http$<{ annotations: Record<string, Annotation[]> }>(`${basePath()}/annotations`, {
const body = JSON.stringify(obj);
return http$<{ annotations: Record<string, Annotation[]> }>({
path: `${basePath()}/annotations`,
method: 'POST',
body: obj,
body,
});
},
indexAnnotation(obj: any) {
return http({
url: `${basePath()}/annotations/index`,
const body = JSON.stringify(obj);
return http<any>({
path: `${basePath()}/annotations/index`,
method: 'PUT',
data: obj,
body,
});
},
deleteAnnotation(id: string) {
return http({
url: `${basePath()}/annotations/delete/${id}`,
return http<any>({
path: `${basePath()}/annotations/delete/${id}`,
method: 'DELETE',
});
},
Expand Down
Loading

0 comments on commit bacc746

Please sign in to comment.