The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/migrate-to-cloud/mockAPI.ts

229 lines
7.1 KiB

import { BaseQueryFn, createApi } from '@reduxjs/toolkit/query/react';
import { lastValueFrom } from 'rxjs';
import { BackendSrvRequest, getBackendSrv } from '@grafana/runtime';
interface RequestOptions extends BackendSrvRequest {
manageError?: (err: unknown) => { error: unknown };
showErrorAlert?: boolean;
}
function createBackendSrvBaseQuery({ baseURL }: { baseURL: string }): BaseQueryFn<RequestOptions> {
async function backendSrvBaseQuery(requestOptions: RequestOptions) {
try {
const { data: responseData, ...meta } = await lastValueFrom(
getBackendSrv().fetch({
...requestOptions,
url: baseURL + requestOptions.url,
showErrorAlert: requestOptions.showErrorAlert,
})
);
return { data: responseData, meta };
} catch (error) {
return requestOptions.manageError ? requestOptions.manageError(error) : { error };
}
}
return backendSrvBaseQuery;
}
interface MigrateToCloudStatusDTO {
enabled: boolean;
stackURL?: string;
}
interface CreateMigrationTokenResponseDTO {
token: string;
}
export interface ConnectStackDTOMock {
stackURL: string;
token: string;
}
type MigrationResourceStatus = 'not-migrated' | 'migrated' | 'migrating' | 'failed';
export interface MigrationResourceDatasource {
uid: string;
status: MigrationResourceStatus;
statusMessage?: string;
type: 'datasource';
resource: {
uid: string;
name: string;
type: string;
icon?: string;
};
}
export interface MigrationResourceDashboard {
uid: string;
status: MigrationResourceStatus;
statusMessage?: string;
type: 'dashboard';
resource: {
uid: string;
name: string;
};
}
export type MigrationResourceDTOMock = MigrationResourceDatasource | MigrationResourceDashboard;
const mockApplications = ['auth-service', 'web server', 'backend'];
const mockEnvs = ['DEV', 'PROD'];
const mockRoles = ['db', 'load-balancer', 'server', 'logs'];
const mockDataSources = ['Prometheus', 'Loki', 'AWS Athena', 'AWS Cloudwatch', 'InfluxDB', 'Elasticsearch'];
const mockDataSourceMetadata: Record<string, { image: string }> = {
Prometheus: {
image: 'https://grafana.com/api/plugins/prometheus/versions/5.0.0/logos/small',
},
Loki: {
image: 'https://grafana.com/api/plugins/loki/versions/5.0.0/logos/small',
},
'AWS Athena': {
image: 'https://grafana.com/api/plugins/grafana-athena-datasource/versions/2.13.5/logos/small',
},
'AWS Cloudwatch': {
image: 'https://grafana.com/api/plugins/computest-cloudwatchalarm-datasource/versions/2.0.0/logos/small',
},
InfluxDB: {
image: 'https://grafana.com/api/plugins/influxdb/versions/5.0.0/logos/small',
},
Elasticsearch: {
image: 'https://grafana.com/api/plugins/elasticsearch/versions/5.0.0/logos/small',
},
};
const mockMigrationResources: MigrationResourceDTOMock[] = Array.from({ length: 500 }).map((_, index) => {
const dataSource = mockDataSources[index % mockDataSources.length];
const environment = mockEnvs[index % mockEnvs.length];
const application = mockApplications[index % mockApplications.length];
const role = mockRoles[index % mockRoles.length];
return {
status: 'not-migrated',
type: 'datasource',
uid: index.toString(16),
resource: {
uid: `${application}-${environment}-${role}-${index}`,
name: `${application} ${environment} ${role}`,
icon: mockDataSourceMetadata[dataSource]?.image,
type: dataSource,
},
};
});
mockMigrationResources[0].status = 'migrated';
mockMigrationResources[1].status = 'failed';
mockMigrationResources[1].statusMessage = `Source map error: Error: request failed with status 404
Resource URL: http://localhost:3000/public/build/app.f4d0c6a0daa6a5b14892.js
Source Map URL: app.f4d0c6a0daa6a5b14892.js.map`;
mockMigrationResources[2].status = 'migrated';
mockMigrationResources[3].status = 'migrated';
mockMigrationResources[4].status = 'migrating';
mockMigrationResources[5].status = 'migrating';
// TODO remove these mock properties/functions
const queryParams = new URLSearchParams(window.location.search);
const MOCK_DELAY_MS = 1000;
const MOCK_TOKEN = 'TODO_thisWillBeABigLongToken';
let HAS_MIGRATION_TOKEN = false;
let HAS_STACK_DETAILS = !!queryParams.get('mockStackURL');
let STACK_URL: string | undefined = queryParams.get('mockStackURL') || undefined;
function dataWithMockDelay<T>(data: T): Promise<{ data: T }> {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ data });
}, MOCK_DELAY_MS);
});
}
export const migrateToCloudMockAPI = createApi({
tagTypes: ['migrationToken', 'stackDetails', 'resource'],
reducerPath: 'migrateToCloudMockAPI',
baseQuery: createBackendSrvBaseQuery({ baseURL: '/api' }),
endpoints: (builder) => ({
// TODO :)
getStatus: builder.query<MigrateToCloudStatusDTO, void>({
providesTags: ['stackDetails'],
queryFn: () => {
const responseData: MigrateToCloudStatusDTO = { enabled: HAS_STACK_DETAILS };
if (STACK_URL) {
responseData.stackURL = STACK_URL;
}
return dataWithMockDelay(responseData);
},
}),
connectStack: builder.mutation<void, ConnectStackDTOMock>({
invalidatesTags: ['stackDetails'],
queryFn: async ({ stackURL }) => {
HAS_STACK_DETAILS = true;
STACK_URL = stackURL;
return dataWithMockDelay(undefined);
},
}),
disconnectStack: builder.mutation<void, void>({
invalidatesTags: ['stackDetails'],
queryFn: async () => {
HAS_STACK_DETAILS = false;
return dataWithMockDelay(undefined);
},
}),
createMigrationToken: builder.mutation<CreateMigrationTokenResponseDTO, void>({
invalidatesTags: ['migrationToken'],
queryFn: async () => {
HAS_MIGRATION_TOKEN = true;
return dataWithMockDelay({ token: MOCK_TOKEN });
},
}),
deleteMigrationToken: builder.mutation<void, void>({
invalidatesTags: ['migrationToken'],
queryFn: async () => {
HAS_MIGRATION_TOKEN = false;
return dataWithMockDelay(undefined);
},
}),
hasMigrationToken: builder.query<boolean, void>({
providesTags: ['migrationToken'],
queryFn: async () => {
return dataWithMockDelay(HAS_MIGRATION_TOKEN);
},
}),
startMigration: builder.mutation<void, void>({
queryFn: async () => {
return dataWithMockDelay(undefined);
},
}),
listResources: builder.query<MigrationResourceDTOMock[], void>({
providesTags: ['resource'],
queryFn: async () => {
return dataWithMockDelay(mockMigrationResources);
},
}),
}),
});
export const {
useGetStatusQuery: useGetStatusQueryMock,
useConnectStackMutation: useConnectStackMutationMock,
useDisconnectStackMutation: useDisconnectStackMutationMock,
useCreateMigrationTokenMutation: useCreateMigrationTokenMutationMock,
useDeleteMigrationTokenMutation: useDeleteMigrationTokenMutationMock,
useHasMigrationTokenQuery: useHasMigrationTokenQueryMock,
useListResourcesQuery: useListResourcesQueryMock,
useStartMigrationMutation: useStartMigrationMutationMock,
} = migrateToCloudMockAPI;