Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import getMetricsToCustomerRoutes from '@/routes/routes';
import { NAMESPACES } from '@/MetricsToCustomer.translations';

import { DashboardProvider, MetricsToCustomerProvider } from '@/contexts';
import { useIamResourceLocation } from '@/data/hooks';
import { useIamRegionsAndCapabilitiesMetrics } from '@/data/hooks';
import { Spinner, SPINNER_SIZE } from '@ovhcloud/ods-react';

export function MetricsToCustomerModule(
Expand All @@ -28,21 +28,14 @@ export function MetricsToCustomerModule(
enableConfigurationManagement,
} = moduleProps;

const {
isPending,
isSuccess,
regions,
capabilitiesMetrics,
} = useIamRegionsAndCapabilitiesMetrics(resourceURN);

const {
isLoading,
isSuccess,
data,
} = useIamResourceLocation(resourceURN);

const regions = [
{
code: data?.name ?? "",
label: data?.location ?? ""
}
];

if (isLoading) {
if (isPending) {
return <Spinner size={SPINNER_SIZE.xs} />
}

Expand All @@ -51,6 +44,7 @@ export function MetricsToCustomerModule(
resourceName,
resourceURN,
regions,
capabilitiesMetrics,
};

const context = enableConfigurationManagement
Expand All @@ -64,7 +58,7 @@ export function MetricsToCustomerModule(
};

return (
<Suspense fallback={<div className="flex py-8">{t('loading_metrics_module')}</div>}>
<Suspense fallback={<div className="flex py-8">{t('loading_metrics_module')}</div>}>
{
isSuccess && (
<MetricsToCustomerProvider context={context}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import { MetricData } from '@/types/observability.type';

export const fetchChartData = async <TData>(
params: ObservabilityMetricDataParams,
regionCode: string,
metricToken: string,
): Promise<MetricData<TData>> => {
const isMockEnabled = apiConfig['metrics-for-manager'] === 'mock';
console.info('[MOCK-ADAPTER][fetchChartData] Mock enabled -> ', isMockEnabled);
return isMockEnabled
? fetchChartDataFromMock<TData>(params)
: fetchChartDataFromApi<TData>(params, metricToken);
: fetchChartDataFromApi<TData>(params, regionCode, metricToken);
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ vi.mock('@/routes/routes', () => ({
getObservabilityRoute: getObservabilityRouteMock,
}));

// Mock useIamResourceLocation hook
// Mock data hooks
vi.mock('@/data/hooks', () => ({
useIamResourceLocation: () => ({
isLoading: false,
Expand All @@ -64,6 +64,12 @@ vi.mock('@/data/hooks', () => ({
},
error: null,
}),
useIamRegionsAndCapabilitiesMetrics: () => ({
isPending: false,
isSuccess: true,
regions: [],
capabilitiesMetrics: [],
}),
}));

// Mock react-i18next
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const TenantsSubscriptionsDrawer = ({

const { regionCodes, regionLabels } = useMemo(
() => ({
regionCodes: regions.map(({ code }) => code),
regionCodes: regions.map(({ name }) => name),
regionLabels: regions.map(({ label }) => label),
}),
[regions]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { DashboardContextType } from '@/contexts/Dashboard.context.type';
import { useMetricsToCustomerContext } from '@/contexts/MetricsToCustomer.context';
import { TimeRangeOption } from '@/types/TimeRangeOption.type';
import { calculateDateTimeRange } from '@/utils/dateTimeUtils';
import { isRegionAvailable } from '@/utils/metrics.utils';

export interface DashboardState {
isLoading: string | undefined;
Expand Down Expand Up @@ -37,11 +36,10 @@ export const DashboardProvider = ({ children, context = {} }: DashboardProviderP
selectedTimeOption,
startDateTime,
endDateTime,
regionAvailable,
} = context;

const {
state: { regions },
state: { capabilitiesMetrics },
} = useMetricsToCustomerContext();

const initialSelectedTimeOption =
Expand All @@ -57,11 +55,6 @@ export const DashboardProvider = ({ children, context = {} }: DashboardProviderP
endDateTime: initialEndDateTime,
});

const computedRegionAvailable = useMemo(
() => regionAvailable ?? isRegionAvailable(regions),
[regionAvailable, regions],
);

const { startDateTime: derivedStartDateTime, endDateTime: derivedEndDateTime } = useMemo(() => {
if (state.selectedTimeOption.value === 'custom') {
return {
Expand All @@ -80,7 +73,7 @@ export const DashboardProvider = ({ children, context = {} }: DashboardProviderP
...state,
startDateTime: derivedStartDateTime,
endDateTime: derivedEndDateTime,
regionAvailable: computedRegionAvailable,
regionAvailable: capabilitiesMetrics,
},
setState,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type SubscriptionManagementConfig =

type BaseMetricsToCustomerState = BaseM2CProperties & {
regions: Region[];
capabilitiesMetrics: boolean;
};

export type MetricsToCustomerState = BaseMetricsToCustomerState & SubscriptionManagementConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const getMetricKindByName = async ({

export async function fetchChartData<TData>(
payload: ObservabilityMetricDataParams,
regionCode: string,
metricToken: string,
): Promise<MetricData<TData>> {
const { query, start, end, step } = payload;
Expand All @@ -44,6 +45,7 @@ export async function fetchChartData<TData>(
start,
end,
step,
regionCode,
metricToken,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ export interface PrometheusResult {
};
}


const getMetricForManagerBaseUrl = (regionCode: string) =>
`https://metrics-for-manager.${regionCode}.technicalapis.ovh.net/m4m-single-endpoint-proxy/api/v1`;

// Create prometheus axios instance similar to v2 client
const metricForManagerClient = axios.create({
baseURL: 'https://metrics-for-manager.gra.technicalapis.ovh.net/m4m-single-endpoint-proxy/api/v1',
});
// NOTE: baseURL is set per-request to support dynamic regions.
const metricForManagerClient = axios.create();

// Add request interceptor for headers (same pattern as v2 client)
metricForManagerClient.interceptors.request.use((config: InternalAxiosRequestConfig) => {
Expand Down Expand Up @@ -85,6 +88,7 @@ export const prometheusApiClient = {
};

export interface FetchPrometheusDataParams extends PrometheusQueryParams {
regionCode: string;
metricToken: string;
signal?: AbortSignal;
}
Expand All @@ -94,10 +98,11 @@ export const fetchPrometheusData = async ({
start,
end,
step,
regionCode,
metricToken,
signal,
}: FetchPrometheusDataParams): Promise<PrometheusResult> => {

const baseURL = getMetricForManagerBaseUrl(regionCode);
const { data } = await prometheusApiClient.get<PrometheusResult>(
'/query_range',
{
Expand All @@ -108,9 +113,10 @@ export const fetchPrometheusData = async ({
step,
},
signal,
baseURL,
headers: {
Authorization: `Bearer ${metricToken}`
}
Authorization: `Bearer ${metricToken}`,
},
},
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import { MetricData } from '@/types/observability.type';
export const getChartDataOptions = <TData>(
payload: RequestPayload,
refreshInterval: number,
regionCode: string,
metricToken: string,
enabled = true,
) => {
return queryOptions({
queryKey: getChartDataQueryKey(payload, metricToken),
queryFn: (): Promise<MetricData<TData>> => fetchChartData<TData>(payload, metricToken),
queryKey: getChartDataQueryKey(payload, regionCode, metricToken),
queryFn: (): Promise<MetricData<TData>> => fetchChartData<TData>(payload, regionCode, metricToken),
refetchInterval: refreshInterval > 0 ? refreshInterval * 1000 : false,
enabled,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RequestPayload } from '@/types/RequestPayload.type';

export const getChartDataQueryKey = (payload: RequestPayload, metricToken: string) =>
export const getChartDataQueryKey = (payload: RequestPayload, regionCode: string, metricToken: string) =>
[
'chartData',
'type',
Expand All @@ -13,6 +13,8 @@ export const getChartDataQueryKey = (payload: RequestPayload, metricToken: strin
payload.end,
'step',
payload.step,
'regionCode',
regionCode,
'metricToken',
metricToken,
] as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { RequestPayload } from '@/types/RequestPayload.type';
export const useChartData = <TData>(
payload: RequestPayload,
refreshInterval: number,
regionCode: string,
metricToken: string,
fetchData = true,
) => {
return useQuery(getChartDataOptions<TData>(payload, refreshInterval, metricToken));
return useQuery(getChartDataOptions<TData>(payload, refreshInterval, regionCode, metricToken, fetchData));
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ type UseChartWithDataParams = {
endDateTime?: number;
selectedTimeOption: TimeRangeOption;
refreshInterval: number;
regionCode: string;
metricToken: string;
fetchData?: boolean;
};

export const useChartWithData = <TData>({
Expand All @@ -31,7 +33,9 @@ export const useChartWithData = <TData>({
endDateTime,
selectedTimeOption,
refreshInterval,
regionCode,
metricToken,
fetchData = true,
}: UseChartWithDataParams) => {

const queryClient = useQueryClient();
Expand Down Expand Up @@ -66,10 +70,10 @@ export const useChartWithData = <TData>({
error: dataError,
isError: isDataError,
refetch,
} = useChartData<TData>(requestPayload, refreshInterval, metricToken);
} = useChartData<TData>(requestPayload, refreshInterval, regionCode, metricToken, fetchData);

const cancel = () => queryClient.cancelQueries({
queryKey: getChartDataQueryKey(requestPayload, metricToken),
queryKey: getChartDataQueryKey(requestPayload, regionCode, metricToken),
exact: true,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type UseMultipleChartDataParams = {
endDateTime?: number;
selectedTimeOption: TimeRangeOption;
refreshInterval: number;
regionCode: string;
metricToken: string;
fetchData?: boolean;
};
Expand All @@ -23,6 +24,7 @@ export const useMultipleChartData = <TData>({
endDateTime,
selectedTimeOption,
refreshInterval,
regionCode,
metricToken,
fetchData = true,
}: UseMultipleChartDataParams): ChartQueryResult<TData>[] => {
Expand All @@ -42,7 +44,7 @@ export const useMultipleChartData = <TData>({
step,
type: 'query_range',
};
const query = getChartDataOptions<TData>(payload, refreshInterval, metricToken, fetchData);
const query = getChartDataOptions<TData>(payload, refreshInterval, regionCode, metricToken, fetchData);

return {
...query,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useLocation } from '@/data/hooks/locations/useLocations.hook';
import { useIamResourceTags } from '@/data/hooks/iam/useIamResourceTags.hook';

export const useIamRegionsAndCapabilitiesMetrics = (resourceURN: string) => {
const {
data: iamTags,
isLoading: isIamTagsLoading,
isSuccess: isIamTagsSuccess,
} = useIamResourceTags(resourceURN, [
'ovh:region',
'ovh:capabilities:metrics',
]);

const regionName = iamTags?.['ovh:region'];

const {
data: location,
isLoading: isLocationLoading,
isSuccess: isLocationSuccess,
} = useLocation(regionName ?? '');

const regions = [
{
code: location?.code ?? '',
name: location?.name ?? '',
label: location?.location ?? '',
},
];

const capabilitiesMetrics =
iamTags?.['ovh:capabilities:metrics'] === 'true';

return {
isPending: isIamTagsLoading || isLocationLoading,
isSuccess: isIamTagsSuccess && isLocationSuccess,
regions,
capabilitiesMetrics,
tags: iamTags,
};
};

Loading
Loading