mirror of
https://github.com/SigNoz/signoz.git
synced 2026-02-09 19:22:21 +00:00
Compare commits
4 Commits
test/uplot
...
feat/gatew
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82b391af2c | ||
|
|
84bf240362 | ||
|
|
a26e28b048 | ||
|
|
8456d7f272 |
@@ -1,28 +1,43 @@
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import axios from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import {
|
||||
CreatedIngestionKeyProps,
|
||||
CreateIngestionKeyProps,
|
||||
IngestionKeyProps,
|
||||
} from 'types/api/ingestionKeys/types';
|
||||
import { ErrorStatusCode } from 'types/common';
|
||||
|
||||
const createIngestionKey = async (
|
||||
props: CreateIngestionKeyProps,
|
||||
): Promise<SuccessResponse<IngestionKeyProps> | ErrorResponse> => {
|
||||
): Promise<SuccessResponse<CreatedIngestionKeyProps> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await GatewayApiV1Instance.post('/workspaces/me/keys', {
|
||||
const response = await GatewayApiV2Instance.post('/ingestion_keys', {
|
||||
...props,
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
message: 'success',
|
||||
payload: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
if (axios.isAxiosError(error)) {
|
||||
const errResponse: ErrorResponse = {
|
||||
statusCode:
|
||||
(error.response?.status as ErrorStatusCode) || (500 as ErrorStatusCode),
|
||||
error: error.response?.data?.error?.message || 'Something went wrong',
|
||||
message: error.response?.data?.error?.message || 'An error occurred',
|
||||
payload: null,
|
||||
};
|
||||
throw errResponse;
|
||||
}
|
||||
throw {
|
||||
statusCode: 500,
|
||||
error: 'Unknown error',
|
||||
message: 'An unknown error occurred',
|
||||
payload: null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import axios from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { AllIngestionKeyProps } from 'types/api/ingestionKeys/types';
|
||||
import { ErrorStatusCode } from 'types/common';
|
||||
|
||||
const deleteIngestionKey = async (
|
||||
id: string,
|
||||
): Promise<SuccessResponse<AllIngestionKeyProps> | ErrorResponse> => {
|
||||
): Promise<SuccessResponse<void> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await GatewayApiV1Instance.delete(
|
||||
`/workspaces/me/keys/${id}`,
|
||||
);
|
||||
await GatewayApiV2Instance.delete(`/ingestion_keys/${id}`);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
message: 'success',
|
||||
payload: undefined,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
if (axios.isAxiosError(error)) {
|
||||
const errResponse: ErrorResponse = {
|
||||
statusCode:
|
||||
(error.response?.status as ErrorStatusCode) || (500 as ErrorStatusCode),
|
||||
error: error.response?.data?.error?.message || 'Something went wrong',
|
||||
message: error.response?.data?.error?.message || 'An error occurred',
|
||||
payload: null,
|
||||
};
|
||||
throw errResponse;
|
||||
}
|
||||
throw {
|
||||
statusCode: 500,
|
||||
error: 'Unknown error',
|
||||
message: 'An unknown error occurred',
|
||||
payload: null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import {
|
||||
AllIngestionKeyProps,
|
||||
@@ -11,11 +11,11 @@ export const getAllIngestionKeys = (
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { search, per_page, page } = props;
|
||||
|
||||
const BASE_URL = '/workspaces/me/keys';
|
||||
const BASE_URL = '/ingestion_keys';
|
||||
const URL_QUERY_PARAMS =
|
||||
search && search.length > 0
|
||||
? `/search?name=${search}&page=1&per_page=100`
|
||||
: `?page=${page}&per_page=${per_page}`;
|
||||
|
||||
return GatewayApiV1Instance.get(`${BASE_URL}${URL_QUERY_PARAMS}`);
|
||||
return GatewayApiV2Instance.get(`${BASE_URL}${URL_QUERY_PARAMS}`);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-throw-literal */
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import axios from 'axios';
|
||||
import {
|
||||
AddLimitProps,
|
||||
@@ -24,18 +24,20 @@ const createLimitForIngestionKey = async (
|
||||
props: AddLimitProps,
|
||||
): Promise<SuccessResponse<LimitSuccessProps> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await GatewayApiV1Instance.post(
|
||||
`/workspaces/me/keys/${props.keyID}/limits`,
|
||||
const response = await GatewayApiV2Instance.post(
|
||||
`/ingestion_keys/${props.keyID}/limits`,
|
||||
{
|
||||
...props,
|
||||
signal: props.signal,
|
||||
config: props.config,
|
||||
tags: props.tags,
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
statusCode: 201,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
message: 'success',
|
||||
payload: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import axios from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import { AllIngestionKeyProps } from 'types/api/ingestionKeys/types';
|
||||
import { ErrorStatusCode } from 'types/common';
|
||||
|
||||
const deleteLimitsForIngestionKey = async (
|
||||
id: string,
|
||||
): Promise<SuccessResponse<AllIngestionKeyProps> | ErrorResponse> => {
|
||||
): Promise<SuccessResponse<void> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await GatewayApiV1Instance.delete(
|
||||
`/workspaces/me/limits/${id}`,
|
||||
);
|
||||
await GatewayApiV2Instance.delete(`/ingestion_keys/limits/${id}`);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
message: 'success',
|
||||
payload: undefined,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
if (axios.isAxiosError(error)) {
|
||||
const errResponse: ErrorResponse = {
|
||||
statusCode:
|
||||
(error.response?.status as ErrorStatusCode) || (500 as ErrorStatusCode),
|
||||
error: error.response?.data?.error?.message || 'Something went wrong',
|
||||
message: error.response?.data?.error?.message || 'An error occurred',
|
||||
payload: null,
|
||||
};
|
||||
throw errResponse;
|
||||
}
|
||||
throw {
|
||||
statusCode: 500,
|
||||
error: 'Unknown error',
|
||||
message: 'An unknown error occurred',
|
||||
payload: null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-throw-literal */
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import axios from 'axios';
|
||||
import {
|
||||
LimitSuccessProps,
|
||||
@@ -22,20 +22,18 @@ interface ErrorResponse {
|
||||
|
||||
const updateLimitForIngestionKey = async (
|
||||
props: UpdateLimitProps,
|
||||
): Promise<SuccessResponse<LimitSuccessProps> | ErrorResponse> => {
|
||||
): Promise<SuccessResponse<void> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await GatewayApiV1Instance.patch(
|
||||
`/workspaces/me/limits/${props.limitID}`,
|
||||
{
|
||||
config: props.config,
|
||||
},
|
||||
);
|
||||
await GatewayApiV2Instance.patch(`/ingestion_keys/limits/${props.limitID}`, {
|
||||
config: props.config,
|
||||
tags: props.tags,
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
message: 'success',
|
||||
payload: undefined,
|
||||
};
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { GatewayApiV1Instance } from 'api';
|
||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||
import { AxiosError } from 'axios';
|
||||
import { GatewayApiV2Instance } from 'api';
|
||||
import axios from 'axios';
|
||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||
import {
|
||||
IngestionKeysPayloadProps,
|
||||
CreatedIngestionKeyProps,
|
||||
UpdateIngestionKeyProps,
|
||||
} from 'types/api/ingestionKeys/types';
|
||||
import { ErrorStatusCode } from 'types/common';
|
||||
|
||||
const updateIngestionKey = async (
|
||||
props: UpdateIngestionKeyProps,
|
||||
): Promise<SuccessResponse<IngestionKeysPayloadProps> | ErrorResponse> => {
|
||||
): Promise<SuccessResponse<CreatedIngestionKeyProps> | ErrorResponse> => {
|
||||
try {
|
||||
const response = await GatewayApiV1Instance.patch(
|
||||
`/workspaces/me/keys/${props.id}`,
|
||||
const response = await GatewayApiV2Instance.patch(
|
||||
`/ingestion_keys/${props.id}`,
|
||||
{
|
||||
...props.data,
|
||||
},
|
||||
@@ -21,11 +21,26 @@ const updateIngestionKey = async (
|
||||
return {
|
||||
statusCode: 200,
|
||||
error: null,
|
||||
message: response.data.status,
|
||||
payload: response.data.data,
|
||||
message: 'success',
|
||||
payload: response.data,
|
||||
};
|
||||
} catch (error) {
|
||||
return ErrorResponseHandler(error as AxiosError);
|
||||
if (axios.isAxiosError(error)) {
|
||||
const errResponse: ErrorResponse = {
|
||||
statusCode:
|
||||
(error.response?.status as ErrorStatusCode) || (500 as ErrorStatusCode),
|
||||
error: error.response?.data?.error?.message || 'Something went wrong',
|
||||
message: error.response?.data?.error?.message || 'An error occurred',
|
||||
payload: null,
|
||||
};
|
||||
throw errResponse;
|
||||
}
|
||||
throw {
|
||||
statusCode: 500,
|
||||
error: 'Unknown error',
|
||||
message: 'An unknown error occurred',
|
||||
payload: null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ export const apiV3 = '/api/v3/';
|
||||
export const apiV4 = '/api/v4/';
|
||||
export const apiV5 = '/api/v5/';
|
||||
export const gatewayApiV1 = '/api/gateway/v1/';
|
||||
export const gatewayApiV2 = '/api/gateway/v2/';
|
||||
export const gatewayApiV2 = '/api/v2/gateway/';
|
||||
export const apiAlertManager = '/api/alertmanager/';
|
||||
|
||||
export default apiV1;
|
||||
|
||||
@@ -107,11 +107,14 @@ export const disabledDate = (current: any): boolean =>
|
||||
|
||||
export const showErrorNotification = (
|
||||
notifications: NotificationInstance,
|
||||
err: Error,
|
||||
err: Error | ErrorResponse,
|
||||
): void => {
|
||||
notifications.error({
|
||||
message: err.message || SOMETHING_WENT_WRONG,
|
||||
});
|
||||
const message =
|
||||
(err as ErrorResponse)?.error ||
|
||||
(err as Error)?.message ||
|
||||
SOMETHING_WENT_WRONG;
|
||||
|
||||
notifications.error({ message });
|
||||
};
|
||||
|
||||
type ExpiryOption = {
|
||||
@@ -271,14 +274,14 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setActiveAPIKey(IngestionKeys?.data.data[0]);
|
||||
setActiveAPIKey(IngestionKeys?.data?.data?.keys[0]);
|
||||
}, [IngestionKeys]);
|
||||
|
||||
useEffect(() => {
|
||||
setDataSource(IngestionKeys?.data.data || []);
|
||||
setTotalIngestionKeys(IngestionKeys?.data?._pagination?.total || 0);
|
||||
setDataSource(IngestionKeys?.data?.data?.keys || []);
|
||||
setTotalIngestionKeys(IngestionKeys?.data?.data?._pagination?.total || 0);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [IngestionKeys?.data?.data]);
|
||||
}, [IngestionKeys?.data?.data?.keys]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isError) {
|
||||
@@ -310,8 +313,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
mutate: createIngestionKey,
|
||||
isLoading: isLoadingCreateAPIKey,
|
||||
} = useMutation(createIngestionKeyApi, {
|
||||
onSuccess: (data) => {
|
||||
setActiveAPIKey(data.payload);
|
||||
onSuccess: () => {
|
||||
setUpdatedTags([]);
|
||||
hideAddViewModal();
|
||||
refetchAPIKeys();
|
||||
@@ -592,7 +594,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
|
||||
const payload: UpdateLimitProps = {
|
||||
limitID: signal.id,
|
||||
signal: signal.signal,
|
||||
tags: [],
|
||||
config: {},
|
||||
};
|
||||
|
||||
|
||||
@@ -14,8 +14,12 @@ interface TestIngestionKeyProps extends Omit<IngestionKeyProps, 'limits'> {
|
||||
limits?: LimitProps[];
|
||||
}
|
||||
|
||||
interface TestAllIngestionKeyProps extends Omit<AllIngestionKeyProps, 'data'> {
|
||||
data: TestIngestionKeyProps[];
|
||||
interface TestAllIngestionKeyProps {
|
||||
status: string;
|
||||
data: {
|
||||
keys: TestIngestionKeyProps[];
|
||||
_pagination: { page: number; per_page: number; pages: number; total: number };
|
||||
};
|
||||
}
|
||||
|
||||
// Mock useHistory.push to capture navigation URL used by MultiIngestionSettings
|
||||
@@ -88,26 +92,28 @@ describe('MultiIngestionSettings Page', () => {
|
||||
// Arrange API response with a metrics daily count limit so the alert button is visible
|
||||
const response: TestAllIngestionKeyProps = {
|
||||
status: 'success',
|
||||
data: [
|
||||
{
|
||||
name: 'Key One',
|
||||
expires_at: TEST_EXPIRES_AT,
|
||||
value: 'secret',
|
||||
workspace_id: TEST_WORKSPACE_ID,
|
||||
id: 'k1',
|
||||
created_at: TEST_CREATED_UPDATED,
|
||||
updated_at: TEST_CREATED_UPDATED,
|
||||
tags: [],
|
||||
limits: [
|
||||
{
|
||||
id: 'l1',
|
||||
signal: 'metrics',
|
||||
config: { day: { count: 1000 } },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
_pagination: { page: 1, per_page: 10, pages: 1, total: 1 },
|
||||
data: {
|
||||
keys: [
|
||||
{
|
||||
name: 'Key One',
|
||||
expires_at: TEST_EXPIRES_AT,
|
||||
value: 'secret',
|
||||
workspace_id: TEST_WORKSPACE_ID,
|
||||
id: 'k1',
|
||||
created_at: TEST_CREATED_UPDATED,
|
||||
updated_at: TEST_CREATED_UPDATED,
|
||||
tags: [],
|
||||
limits: [
|
||||
{
|
||||
id: 'l1',
|
||||
signal: 'metrics',
|
||||
config: { day: { count: 1000 } },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
_pagination: { page: 1, per_page: 10, pages: 1, total: 1 },
|
||||
},
|
||||
};
|
||||
|
||||
server.use(
|
||||
@@ -177,26 +183,28 @@ describe('MultiIngestionSettings Page', () => {
|
||||
// Arrange API response with a logs daily size limit so the alert button is visible
|
||||
const response: TestAllIngestionKeyProps = {
|
||||
status: 'success',
|
||||
data: [
|
||||
{
|
||||
name: 'Key Two',
|
||||
expires_at: TEST_EXPIRES_AT,
|
||||
value: 'secret',
|
||||
workspace_id: TEST_WORKSPACE_ID,
|
||||
id: 'k2',
|
||||
created_at: TEST_CREATED_UPDATED,
|
||||
updated_at: TEST_CREATED_UPDATED,
|
||||
tags: [],
|
||||
limits: [
|
||||
{
|
||||
id: 'l2',
|
||||
signal: 'logs',
|
||||
config: { day: { size: 2048 } },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
_pagination: { page: 1, per_page: 10, pages: 1, total: 1 },
|
||||
data: {
|
||||
keys: [
|
||||
{
|
||||
name: 'Key Two',
|
||||
expires_at: TEST_EXPIRES_AT,
|
||||
value: 'secret',
|
||||
workspace_id: TEST_WORKSPACE_ID,
|
||||
id: 'k2',
|
||||
created_at: TEST_CREATED_UPDATED,
|
||||
updated_at: TEST_CREATED_UPDATED,
|
||||
tags: [],
|
||||
limits: [
|
||||
{
|
||||
id: 'l2',
|
||||
signal: 'logs',
|
||||
config: { day: { size: 2048 } },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
_pagination: { page: 1, per_page: 10, pages: 1, total: 1 },
|
||||
},
|
||||
};
|
||||
|
||||
server.use(
|
||||
|
||||
@@ -69,8 +69,11 @@ export default function OnboardingIngestionDetails(): JSX.Element {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (ingestionKeys?.data.data && ingestionKeys?.data.data.length > 0) {
|
||||
setFirstIngestionKey(ingestionKeys?.data.data[0]);
|
||||
if (
|
||||
ingestionKeys?.data.data?.keys &&
|
||||
ingestionKeys?.data.data.keys.length > 0
|
||||
) {
|
||||
setFirstIngestionKey(ingestionKeys?.data.data.keys[0]);
|
||||
}
|
||||
}, [ingestionKeys]);
|
||||
|
||||
|
||||
@@ -24,15 +24,20 @@ export interface AddLimitProps {
|
||||
keyID: string;
|
||||
signal: string;
|
||||
config: LimitSettings;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export interface UpdateLimitProps {
|
||||
limitID: string;
|
||||
signal: string;
|
||||
config: LimitSettings;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export interface LimitSuccessProps {
|
||||
status: string;
|
||||
response: unknown;
|
||||
}
|
||||
|
||||
export interface CreateLimitProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
@@ -53,13 +53,16 @@ export interface PaginationProps {
|
||||
}
|
||||
|
||||
export interface AllIngestionKeyProps {
|
||||
data: {
|
||||
keys: IngestionKeyProps[];
|
||||
_pagination: PaginationProps;
|
||||
};
|
||||
status: string;
|
||||
data: IngestionKeyProps[];
|
||||
_pagination: PaginationProps;
|
||||
}
|
||||
|
||||
export interface CreateIngestionKeyProp {
|
||||
data: IngestionKeyProps;
|
||||
export interface CreatedIngestionKeyProps {
|
||||
id: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface DeleteIngestionKeyPayloadProps {
|
||||
|
||||
Reference in New Issue
Block a user