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

Improve loading speed #7099

Open
wants to merge 32 commits into
base: 4.10.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1cb24f1
Refactor error response function and message handling
guidomodarelli Oct 15, 2024
bf5b711
Refactor code for fetching manager info in wazuh-api
guidomodarelli Oct 15, 2024
0fe0f44
Fix loading speed issue (#7099)
guidomodarelli Oct 15, 2024
a71486b
Add WAZUH_ERROR_DAEMONS_NOT_READY constant to error messages
guidomodarelli Oct 15, 2024
fcd0024
Add ERROR_CODES enum for error handling
guidomodarelli Oct 15, 2024
654ff15
Refactor API routes to use controller functions directly
guidomodarelli Oct 15, 2024
f1b4e46
Refactor getCookieValueByName to handle undefined input
guidomodarelli Oct 15, 2024
d9c7281
Update code to handle string error codes in ErrorResponse function
guidomodarelli Oct 15, 2024
5b81eb8
Update queue job run function to handle context error
guidomodarelli Oct 15, 2024
310856d
Update parameter type in getCookieValueByName function
guidomodarelli Oct 15, 2024
4ab0edf
Add error handling for missing API parameters
guidomodarelli Oct 15, 2024
8502812
Refactor error handling for consistency and readability
guidomodarelli Oct 15, 2024
91f253a
Update Wazuh API controller methods and parameters
guidomodarelli Oct 15, 2024
00867d0
Remove unnecessary code for checking API availability.- Remove redund…
guidomodarelli Oct 16, 2024
f5e8e8c
Refactor route handlers to use async/await functions
guidomodarelli Oct 16, 2024
51890e7
Refactor error handling to log messages as strings
guidomodarelli Oct 16, 2024
2cf4394
Update OpenSearchDashboardsRequest and response types
guidomodarelli Oct 16, 2024
32ef2ac
Update limit parameter type to Record<string, number>.
guidomodarelli Oct 16, 2024
75ea03e
Update json2csvParser fields mapping in WazuhApiCtrl class
guidomodarelli Oct 16, 2024
9d65d97
Refactor handling of Wazuh API requests
guidomodarelli Oct 16, 2024
a3caa44
Fix Prettier issue:
guidomodarelli Oct 16, 2024
fa8bea5
Add mock for API client's asInternalUser endpoint
guidomodarelli Oct 16, 2024
8c6e364
Update error handling in WazuhApiCtrl class
guidomodarelli Oct 16, 2024
90421cf
Update WazuhCorePluginStart type in kibana-services.ts
guidomodarelli Oct 16, 2024
efe7ac1
Add WzToken interface and adjust cookie value retrieval
guidomodarelli Oct 16, 2024
74ca6d1
Refactor route decorators for administrator & configuration API
guidomodarelli Oct 16, 2024
3880d7b
Update import path for PluginInitializerContext
guidomodarelli Oct 16, 2024
865253a
Add resolveJsonModule to compilerOptions in tsconfig.json
guidomodarelli Oct 16, 2024
7af27d5
Add types and interfaces for WazuhCore and configuration
guidomodarelli Oct 16, 2024
e152749
Fix Prettier issue
guidomodarelli Oct 17, 2024
ca0c339
Merge branch '4.10.0' into enhancement/7084-improve-loading-speed
guidomodarelli Oct 17, 2024
5ff77bf
Merge branch '4.10.0' into enhancement/7084-improve-loading-speed
guidomodarelli Oct 18, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Fixed export formatted csv data with special characters from tables [#7048](https:/wazuh/wazuh-dashboard-plugins/pull/7048)
- Fixed column reordering feature [#7072](https:/wazuh/wazuh-dashboard-plugins/pull/7072)
- Fixed filter management to prevent hiding when adding multiple filters [#7077](https:/wazuh/wazuh-dashboard-plugins/pull/7077)
- Fixed loading speed [#7099](https:/wazuh/wazuh-dashboard-plugins/pull/7099)

### Removed

Expand Down
5 changes: 5 additions & 0 deletions plugins/main/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,8 @@ export const OSD_URL_STATE_STORAGE_ID = 'state:storeInSessionStorage';

export const APP_STATE_URL_KEY = '_a';
export const GLOBAL_STATE_URL_KEY = '_g';

export enum ERROR_CODES {
EPROTO = 'EPROTO',
ECONNREFUSED = 'ECONNREFUSED',
}
199 changes: 199 additions & 0 deletions plugins/main/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import { RequestHandlerContext } from 'opensearch-dashboards/server';
import type { ManageHosts } from '../../wazuh-core/server/services';
import { OpenSearchDashboardsRequest } from 'src/core/server/http';

export type UserAuthenticate = (apiHostID: string) => Promise<string>;

export type UserRequestOptions = { apiHostID: string; forceRefresh?: boolean };
export type UserRequest = (
method: string,
path: string,
data: any,
options: UserRequestOptions,
) => Promise<any>;

export type AsUser = {
authenticate: UserAuthenticate;
request: UserRequest;
};

export type ApiClient = {
asInternalUser: AsUser;
asCurrentUser: AsUser;
};

type CurrentUser = {
username?: string;
authContext: { [key: string]: any };
};

export interface ISecurityFactory {
platform?: string;
getCurrentUser(
request: OpenSearchDashboardsRequest,
context?: RequestHandlerContext,
): Promise<CurrentUser>;
isAdministratorUser(
context: RequestHandlerContext,
request: OpenSearchDashboardsRequest,
): Promise<{ administrator: any; administrator_requirements: any }>;
}

export enum EpluginSettingType {
text = 'text',
password = 'password',
textarea = 'textarea',
switch = 'switch',
number = 'number',
editor = 'editor',
select = 'select',
filepicker = 'filepicker',
}

type TConfigurationSettingOptionsPassword = {
password: {
dual?: 'text' | 'password' | 'dual';
};
};

type TConfigurationSettingOptionsTextArea = {
maxRows?: number;
minRows?: number;
maxLength?: number;
};

type TConfigurationSettingOptionsSelect = {
select: { text: string; value: any }[];
};

type TConfigurationSettingOptionsEditor = {
editor: {
language: string;
};
};

type TConfigurationSettingOptionsFile = {
file: {
type: 'image';
extensions?: string[];
size?: {
maxBytes?: number;
minBytes?: number;
};
recommended?: {
dimensions?: {
width: number;
height: number;
unit: string;
};
};
store?: {
relativePathFileSystem: string;
filename: string;
resolveStaticURL: (filename: string) => string;
};
};
};

type TConfigurationSettingOptionsNumber = {
number: {
min?: number;
max?: number;
integer?: boolean;
};
};

type TConfigurationSettingOptionsSwitch = {
switch: {
values: {
disabled: { label?: string; value: any };
enabled: { label?: string; value: any };
};
};
};

export type TConfigurationSetting = {
// Define the text displayed in the UI.
title: string;
// Description.
description: string;
// Category.
category: number;
// Type.
type: EpluginSettingType;
// Default value.
defaultValue: any;
/* Special: This is used for the settings of customization to get the hidden default value, because the default value is empty to not to be displayed on the App Settings. */
defaultValueIfNotSet?: any;
// Configurable from the configuration file.
isConfigurableFromSettings: boolean;
// Modify the setting requires running the plugin health check (frontend).
requiresRunningHealthCheck?: boolean;
// Modify the setting requires reloading the browser tab (frontend).
requiresReloadingBrowserTab?: boolean;
// Modify the setting requires restarting the plugin platform to take effect.
requiresRestartingPluginPlatform?: boolean;
// Define options related to the `type`.
options?:
| TConfigurationSettingOptionsEditor
| TConfigurationSettingOptionsFile
| TConfigurationSettingOptionsNumber
| TConfigurationSettingOptionsPassword
| TConfigurationSettingOptionsSelect
| TConfigurationSettingOptionsSwitch
| TConfigurationSettingOptionsTextArea;
store?: {
file: {
// Define if the setting is managed by the ConfigurationStore service
configurableManaged?: boolean;
// Define a text to print as the default in the configuration block
defaultBlock?: string;
/* Transform the value defined in the configuration file to be consumed by the Configuration
service */
transformFrom?: (value: any) => any;
};
};
// Transform the input value. The result is saved in the form global state of Settings/Configuration
uiFormTransformChangedInputValue?: (value: any) => any;
// Transform the configuration value or default as initial value for the input in Settings/Configuration
uiFormTransformConfigurationValueToInputValue?: (value: any) => any;
// Transform the input value changed in the form of Settings/Configuration and returned in the `changed` property of the hook useForm
uiFormTransformInputValueToConfigurationValue?: (value: any) => any;
// Validate the value in the form of App Settings. It returns a string if there is some validation error.
validateUIForm?: (value: any) => string | undefined;
// Validate function creator to validate the setting in the backend.
validate?: (value: string) => string | undefined;
};

type TConfigurationSettings = { [key: string]: any };
export interface IConfigurationStore {
setup: () => Promise<any>;
start: () => Promise<any>;
stop: () => Promise<any>;
get: (...settings: string[]) => Promise<TConfigurationSettings>;
set: (settings: TConfigurationSettings) => Promise<any>;
clear: (...settings: string[]) => Promise<any>;
setConfiguration: (configuration: IConfiguration) => void;
}

export interface IConfiguration {
setStore(store: IConfigurationStore): void;
setup(): Promise<any>;
start(): Promise<any>;
stop(): Promise<any>;
register(id: string, value: any): void;
get(...settings: string[]): Promise<TConfigurationSettings>;
set(settings: TConfigurationSettings): Promise<any>;
clear(...settings: string[]): Promise<any>;
reset(...settings: string[]): Promise<any>;
_settings: Map<string, TConfigurationSetting>;
getSettingValue(settingKey: string, value?: any): any;
getSettingValueIfNotSet(settingKey: string, value?: any): any;
}

export type WazuhCore = {
api: { client: ApiClient };
dashboardSecurity: ISecurityFactory;
configuration: IConfiguration;
manageHosts: ManageHosts;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { CheckLogger } from '../types/check_logger';
import {
PLUGIN_PLATFORM_WAZUH_DOCUMENTATION_URL_PATH_TROUBLESHOOTING,
PLUGIN_APP_NAME,
WAZUH_ERROR_DAEMONS_NOT_READY,
} from '../../../../common/constants';
import { webDocumentationLink } from '../../../../common/services/web_documentation';

Expand Down Expand Up @@ -52,7 +53,11 @@ const trySetDefault = async (checkLogger: CheckLogger) => {
}
if (errors.length) {
for (var j = 0; j < errors.length; j++) {
if (errors[j].includes('ERROR3099 - 405: Method Not Allowed')) {
if (
errors[j].includes(
`${WAZUH_ERROR_DAEMONS_NOT_READY} - 405: Method Not Allowed`,
)
) {
return Promise.reject(
`No API available to connect. This may be related to a version mismatch between server and ${PLUGIN_APP_NAME}. Please check the versions and try again. Read more about this in our troubleshooting guide: ${webDocumentationLink(
PLUGIN_PLATFORM_WAZUH_DOCUMENTATION_URL_PATH_TROUBLESHOOTING,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import { WzRequest } from '../../../../../../react-services/wz-request';
import { replaceIllegalXML } from './xml';
import { getToasts } from '../../../../../../kibana-services';
import { delayAsPromise } from '../../../../../../../common/utils';
import { AGENT_SYNCED_STATUS } from '../../../../../../../common/constants';
import {
AGENT_SYNCED_STATUS,
WAZUH_ERROR_DAEMONS_NOT_READY,
} from '../../../../../../../common/constants';

/**
* Get configuration for an agent/manager of request sections
Expand Down Expand Up @@ -144,7 +147,7 @@ export const handleError = async (
const message = extractMessage(error);
const messageIsString = typeof message === 'string';
try {
if (messageIsString && message.includes('ERROR3099')) {
if (messageIsString && message.includes(WAZUH_ERROR_DAEMONS_NOT_READY)) {
updateWazuhNotReadyYet('Server not ready yet.');
await makePing(updateWazuhNotReadyYet, isCluster);
return;
Expand Down
3 changes: 2 additions & 1 deletion plugins/main/public/kibana-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { VisualizationsStart } from '../../../src/plugins/visualizations/public'
import { NavigationPublicPluginStart } from '../../../src/plugins/navigation/public';
import { AppPluginStartDependencies } from './types';
import { WazuhCheckUpdatesPluginStart } from '../../wazuh-check-updates/public';
import { WazuhCorePluginStart } from 'plugins/wazuh-core/public';

let angularModule: any = null;
let discoverModule: any = null;
Expand Down Expand Up @@ -46,7 +47,7 @@ export const [getWzCurrentAppID, setWzCurrentAppID] =
export const [getWazuhCheckUpdatesPlugin, setWazuhCheckUpdatesPlugin] =
createGetterSetter<WazuhCheckUpdatesPluginStart>('WazuhCheckUpdatesPlugin');
export const [getWazuhCorePlugin, setWazuhCorePlugin] =
createGetterSetter<WazuhCheckUpdatesPluginStart>('WazuhCorePlugin');
createGetterSetter<WazuhCorePluginStart>('WazuhCorePlugin');
export const [getHeaderActionMenuMounter, setHeaderActionMenuMounter] =
createGetterSetter<AppMountParameters['setHeaderActionMenu']>(
'headerActionMenuMounter',
Expand Down
3 changes: 2 additions & 1 deletion plugins/main/public/react-services/error-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import store from '../redux/store';
import { updateWazuhNotReadyYet } from '../redux/actions/appStateActions';
import { WzMisc } from '../factories/misc';
import { CheckDaemonsStatus } from './check-daemons-status';
import { WAZUH_ERROR_DAEMONS_NOT_READY } from '../../common/constants';

interface IHistoryItem {
text: string;
Expand Down Expand Up @@ -142,7 +143,7 @@ export class ErrorHandler {
static handle(error, location, params = { warning: false, silent: false }) {
const message = ErrorHandler.extractMessage(error);
const messageIsString = typeof message === 'string';
if (messageIsString && message.includes('ERROR3099')) {
if (messageIsString && message.includes(WAZUH_ERROR_DAEMONS_NOT_READY)) {
const updateNotReadyYet = updateWazuhNotReadyYet('Server not ready yet.');
store.dispatch(updateNotReadyYet);
CheckDaemonsStatus.makePing().catch(error => {});
Expand Down
2 changes: 2 additions & 0 deletions plugins/main/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { WazuhCheckUpdatesPluginStart } from '../../wazuh-check-updates/public';
import { WazuhCorePluginStart } from '../../wazuh-core/public';
import { DashboardStart } from '../../../src/plugins/dashboard/public';
import { WazuhCore } from '../common/types';

export interface AppPluginStartDependencies {
navigation: NavigationPublicPluginStart;
Expand All @@ -46,6 +47,7 @@ export type WazuhSetupPlugins = {
data: DataPublicPluginSetup;
navigation: NavigationPublicPluginStart;
telemetry: TelemetryPluginSetup;
wazuhCore: WazuhCore;
};

export type WazuhStartPlugins = AppPluginStartDependencies;
Expand Down
35 changes: 30 additions & 5 deletions plugins/main/server/controllers/decorators.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import {
OpenSearchDashboardsRequest,
OpenSearchDashboardsResponseFactory,
RequestHandlerContext,
} from 'opensearch-dashboards/server';
import { ErrorResponse } from '../lib/error-response';

export function routeDecoratorProtectedAdministrator(errorCode: number) {
return handler => {
return async (context, request, response) => {
return (
handler: (
context: RequestHandlerContext,
request: OpenSearchDashboardsRequest,
response: OpenSearchDashboardsResponseFactory,
) => Promise<unknown>,
) => {
return async (
context: RequestHandlerContext,
request: OpenSearchDashboardsRequest,
response: OpenSearchDashboardsResponseFactory,
) => {
try {
const { administrator, administrator_requirements } =
await context.wazuh_core.dashboardSecurity.isAdministratorUser(
Expand All @@ -20,9 +35,19 @@ export function routeDecoratorProtectedAdministrator(errorCode: number) {
};
}

export function routeDecoratorConfigurationAPIEditable(errorCode) {
return handler => {
return async (context, request, response) => {
export function routeDecoratorConfigurationAPIEditable(errorCode: number) {
return (
handler: (
context: RequestHandlerContext,
request: OpenSearchDashboardsRequest,
response: OpenSearchDashboardsResponseFactory,
) => Promise<unknown>,
) => {
return async (
context: RequestHandlerContext,
request: OpenSearchDashboardsRequest,
response: OpenSearchDashboardsResponseFactory,
) => {
try {
const canEditConfiguration = await context.wazuh_core.configuration.get(
'configuration.ui_api_editable',
Expand Down
10 changes: 10 additions & 0 deletions plugins/main/server/controllers/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface WzToken {
iss: string;
aud: string;
nbf: number;
exp: number;
sub: string;
run_as: boolean;
rbac_roles: number[];
rbac_mode: string;
}
Loading
Loading