Skip to content

Commit

Permalink
Client side update
Browse files Browse the repository at this point in the history
- Updated the client to not get es host from injected metadata.
  Instead use the new endpoint created server side that returns
  this value
- Added a small README.md regarding the hooks lib and need to
  refactor use of jQuery in console
- Write code to init the es host value on the client once at start
  up in a non-blocking way. If this fails we just use the default
  value of http://localhost:9200 as this powers non-essential
  console functionality (i.e., copy as cURL).
  • Loading branch information
jloleysens committed Aug 19, 2020
1 parent 8ed80e3 commit 06e6396
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,8 @@ const inputId = 'ConAppInputTextarea';

function EditorUI({ initialTextValue }: EditorProps) {
const {
services: { history, notifications, settings: settingsService },
services: { history, notifications, settings: settingsService, esHostService },
docLinkVersion,
elasticsearchUrl,
} = useServicesContext();

const { settings } = useEditorReadContext();
Expand Down Expand Up @@ -232,7 +231,7 @@ function EditorUI({ initialTextValue }: EditorProps) {
<EuiFlexItem>
<ConsoleMenu
getCurl={() => {
return editorInstanceRef.current!.getRequestsAsCURL(elasticsearchUrl);
return editorInstanceRef.current!.getRequestsAsCURL(esHostService.getHost());
}}
getDocumentation={() => {
return getDocumentation(editorInstanceRef.current!, docLinkVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,27 @@
* under the License.
*/
import { notificationServiceMock } from '../../../../../core/public/mocks';
import { httpServiceMock } from '../../../../../core/public/mocks';

import { HistoryMock } from '../../services/history.mock';
import { SettingsMock } from '../../services/settings.mock';
import { StorageMock } from '../../services/storage.mock';
import { createApi, createEsHostService } from '../lib';

import { ContextValue } from './services_context';

export const serviceContextMock = {
create: (): ContextValue => {
const storage = new StorageMock({} as any, 'test');
const http = httpServiceMock.createSetupContract();
const api = createApi({ http });
const esHostService = createEsHostService({ api });
(storage.keys as jest.Mock).mockImplementation(() => []);
return {
elasticsearchUrl: 'test',
services: {
trackUiMetric: { count: () => {}, load: () => {} },
storage,
esHostService,
settings: new SettingsMock(storage),
history: new HistoryMock(storage),
notifications: notificationServiceMock.createSetupContract(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@
* under the License.
*/

import React, { createContext, useContext } from 'react';
import React, { createContext, useContext, useEffect } from 'react';
import { NotificationsSetup } from 'kibana/public';
import { History, Storage, Settings } from '../../services';
import { History, Settings, Storage } from '../../services';
import { ObjectStorageClient } from '../../../common/types';
import { MetricsTracker } from '../../types';
import { EsHostService } from '../lib';

interface ContextServices {
history: History;
storage: Storage;
settings: Settings;
notifications: NotificationsSetup;
objectStorageClient: ObjectStorageClient;
trackUiMetric: MetricsTracker;
esHostService: EsHostService;
}

export interface ContextValue {
services: {
history: History;
storage: Storage;
settings: Settings;
notifications: NotificationsSetup;
objectStorageClient: ObjectStorageClient;
trackUiMetric: MetricsTracker;
};
elasticsearchUrl: string;
services: ContextServices;
docLinkVersion: string;
}

Expand All @@ -44,6 +47,11 @@ interface ContextProps {
const ServicesContext = createContext<ContextValue>(null as any);

export function ServicesContextProvider({ children, value }: ContextProps) {
useEffect(() => {
// Fire and forget, we attempt to init the host service once.
value.services.esHostService.init();
}, [value.services.esHostService]);

return <ServicesContext.Provider value={value}>{children}</ServicesContext.Provider>;
}

Expand Down
5 changes: 5 additions & 0 deletions src/plugins/console/public/application/hooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Notes

* Do not add any code directly to this directory. This code should be moved to the neighbouring `lib` directory to be in line with future ES UI plugin patterns.

* The `es.send` method uses $.ajax under the hood and needs to be refactored to use the new platform-provided http client.
11 changes: 7 additions & 4 deletions src/plugins/console/public/application/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@

import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { NotificationsSetup } from 'src/core/public';
import { HttpSetup, NotificationsSetup } from 'src/core/public';
import { ServicesContextProvider, EditorContextProvider, RequestContextProvider } from './contexts';
import { Main } from './containers';
import { createStorage, createHistory, createSettings } from '../services';
import * as localStorageObjectClient from '../lib/local_storage_object_client';
import { createUsageTracker } from '../services/tracker';
import { UsageCollectionSetup } from '../../../usage_collection/public';
import { createApi, createEsHostService } from './lib';

export interface BootDependencies {
http: HttpSetup;
docLinkVersion: string;
I18nContext: any;
notifications: NotificationsSetup;
elasticsearchUrl: string;
usageCollection?: UsageCollectionSetup;
element: HTMLElement;
}
Expand All @@ -40,9 +41,9 @@ export function renderApp({
I18nContext,
notifications,
docLinkVersion,
elasticsearchUrl,
usageCollection,
element,
http,
}: BootDependencies) {
const trackUiMetric = createUsageTracker(usageCollection);
trackUiMetric.load('opened_app');
Expand All @@ -54,14 +55,16 @@ export function renderApp({
const history = createHistory({ storage });
const settings = createSettings({ storage });
const objectStorageClient = localStorageObjectClient.create(storage);
const api = createApi({ http });
const esHostService = createEsHostService({ api });

render(
<I18nContext>
<ServicesContextProvider
value={{
elasticsearchUrl,
docLinkVersion,
services: {
esHostService,
storage,
history,
settings,
Expand Down
39 changes: 39 additions & 0 deletions src/plugins/console/public/application/lib/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License 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 { HttpSetup } from 'kibana/public';
import { EsConfigApiResponse } from '../../../common/types/api_responses';
import { sendRequest } from '../../shared_imports';

interface Dependencies {
http: HttpSetup;
}

export type Api = ReturnType<typeof createApi>;

export const createApi = ({ http }: Dependencies) => {
return {
getEsConfig: () => {
return sendRequest<EsConfigApiResponse>(http, {
path: '/api/console/es_config',
method: 'get',
});
},
};
};
54 changes: 54 additions & 0 deletions src/plugins/console/public/application/lib/es_host_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License 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 { Api } from './api';

/**
* Very simple state for holding the current ES host.
*
* This is used to power the copy as cURL functionality.
*/
export class EsHostService {
private host = 'http://localhost:9200';

constructor(private readonly api: Api) {}

private setHost(host: string): void {
this.host = host;
}

/**
* Initialize the host value based on the value set on the server.
*
* This call is necessary because this value can only be retrieved at
* runtime.
*/
public async init() {
const { data } = await this.api.getEsConfig();
if (data && data.host) {
this.setHost(data.host);
}
}

public getHost(): string {
return this.host;
}
}

export const createEsHostService = ({ api }: { api: Api }) => new EsHostService(api);
21 changes: 21 additions & 0 deletions src/plugins/console/public/application/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License 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.
*/

export { createApi, Api } from './api';
export { createEsHostService, EsHostService } from './es_host_service';
10 changes: 2 additions & 8 deletions src/plugins/console/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { AppSetupUIPluginDependencies } from './types';

export class ConsoleUIPlugin implements Plugin<void, void, AppSetupUIPluginDependencies> {
public setup(
{ notifications, getStartServices }: CoreSetup,
{ notifications, getStartServices, http }: CoreSetup,
{ devTools, home, usageCollection }: AppSetupUIPluginDependencies
) {
home.featureCatalogue.register({
Expand Down Expand Up @@ -53,23 +53,17 @@ export class ConsoleUIPlugin implements Plugin<void, void, AppSetupUIPluginDepen
const [core] = await getStartServices();

const {
injectedMetadata,
i18n: { Context: I18nContext },
docLinks: { DOC_LINK_VERSION },
} = core;

const { renderApp } = await import('./application');

const elasticsearchUrl = injectedMetadata.getInjectedVar(
'elasticsearchUrl',
'http://localhost:9200'
) as string;

return renderApp({
http,
docLinkVersion: DOC_LINK_VERSION,
I18nContext,
notifications,
elasticsearchUrl,
usageCollection,
element,
});
Expand Down
22 changes: 22 additions & 0 deletions src/plugins/console/public/shared_imports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License 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 { sendRequest } from '../../es_ui_shared/public';

export { sendRequest };

0 comments on commit 06e6396

Please sign in to comment.