console: add control plane ws url to endpoints; minor refactor

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7233
GitOrigin-RevId: 62d92c9021030d6ae23116f9ef8f5a664e5750ff
This commit is contained in:
Rishichandra Wawhal 2022-12-14 14:43:17 +05:30 committed by hasura-bot
parent acf5ea4c7e
commit 82be6f0b3b
14 changed files with 148 additions and 54 deletions

View File

@ -0,0 +1,52 @@
import { getEndpoints } from './Endpoints';
import globals from './Globals';
describe('Endpoints > luxDataGraphQL', () => {
beforeEach(() => {
jest.clearAllMocks();
});
afterAll(() => {
jest.clearAllMocks();
});
it('when https domain is set, uses an HTTPS protocol', () => {
// expect right values without SSL
Object.defineProperty(window, 'location', {
value: {
protocol: 'https:',
},
writable: true,
});
const endpoints = getEndpoints({
...globals,
luxDataHost: 'data.hasura.io',
});
expect(endpoints.luxDataGraphql).toEqual(
'https://data.hasura.io/v1/graphql'
);
expect(endpoints.luxDataGraphqlWs).toEqual(
'wss://data.hasura.io/v1/graphql'
);
});
it('when http domain is set, uses an HTTP protocol', () => {
// expect right values without SSL
Object.defineProperty(window, 'location', {
value: {
protocol: 'http:',
},
});
const endpoints = getEndpoints({
...globals,
luxDataHost: 'data.lux-dev.hasura.me',
});
expect(endpoints.luxDataGraphql).toEqual(
'http://data.lux-dev.hasura.me/v1/graphql'
);
expect(endpoints.luxDataGraphqlWs).toEqual(
'ws://data.lux-dev.hasura.me/v1/graphql'
);
});
});

View File

@ -1,35 +1,39 @@
import globals from './Globals';
import { getWebsocketProtocol } from '@/helpers/protocol';
import consoleGlobals from './Globals';
const baseUrl = globals.dataApiUrl;
const hasuractlApiHost = globals.apiHost;
const hasuractlApiPort = globals.apiPort;
export const globalCookiePolicy = 'same-origin';
const hasuractlUrl = `${hasuractlApiHost}:${hasuractlApiPort}`;
export const baseUrl = consoleGlobals.dataApiUrl;
const Endpoints = {
serverConfig: `${baseUrl}/v1alpha1/config`,
graphQLUrl: `${baseUrl}/v1/graphql`,
relayURL: `${baseUrl}/v1beta1/relay`,
query: `${baseUrl}/v2/query`,
metadata: `${baseUrl}/v1/metadata`,
// metadata: `${baseUrl}/v1/query`,
queryV2: `${baseUrl}/v2/query`,
version: `${baseUrl}/v1/version`,
updateCheck: 'https://releases.hasura.io/graphql-engine',
hasuractlMigrate: `${hasuractlUrl}/apis/migrate`,
hasuractlMetadata: `${hasuractlUrl}/apis/metadata`,
hasuractlMigrateSettings: `${hasuractlUrl}/apis/migrate/settings`,
telemetryServer: 'wss://telemetry.hasura.io/v1/ws',
consoleNotificationsStg:
'https://notifications.hasura-stg.hasura-app.io/v1/graphql',
consoleNotificationsProd: 'https://notifications.hasura.io/v1/graphql',
luxDataGraphql: globals.luxDataHost
? `${window.location.protocol}//${globals.luxDataHost}/v1/graphql`
: `${globals.cloudDataApiUrl}/v1/graphql`,
prometheusUrl: `${baseUrl}/v1/metrics`,
export const getEndpoints = (globals: typeof consoleGlobals) => {
const hasuraCliServerUrl = `${globals.apiHost}:${globals.apiPort}`;
const endpoints = {
serverConfig: `${baseUrl}/v1alpha1/config`,
graphQLUrl: `${baseUrl}/v1/graphql`,
relayURL: `${baseUrl}/v1beta1/relay`,
query: `${baseUrl}/v2/query`,
metadata: `${baseUrl}/v1/metadata`,
// metadata: `${baseUrl}/v1/query`,
queryV2: `${baseUrl}/v2/query`,
version: `${baseUrl}/v1/version`,
updateCheck: 'https://releases.hasura.io/graphql-engine',
hasuraCliServerMigrate: `${hasuraCliServerUrl}/apis/migrate`,
hasuraCliServerMetadata: `${hasuraCliServerUrl}/apis/metadata`,
hasuraCliServerMigrateSettings: `${hasuraCliServerUrl}/apis/migrate/settings`,
telemetryServer: 'wss://telemetry.hasura.io/v1/ws',
consoleNotificationsStg:
'https://notifications.hasura-stg.hasura-app.io/v1/graphql',
consoleNotificationsProd: 'https://notifications.hasura.io/v1/graphql',
luxDataGraphql: `${window.location.protocol}//${globals.luxDataHost}/v1/graphql`,
luxDataGraphqlWs: `${getWebsocketProtocol(window.location.protocol)}//${
globals.luxDataHost
}/v1/graphql`,
prometheusUrl: `${baseUrl}/v1/metrics`,
};
return endpoints;
};
const globalCookiePolicy = 'same-origin';
export default Endpoints;
export { globalCookiePolicy, baseUrl, hasuractlUrl };
const endpoints = getEndpoints(consoleGlobals);
export default endpoints;

View File

@ -211,8 +211,10 @@ const globals = {
neonOAuthClientId: window.__env?.neonOAuthClientId,
neonRootDomain: window.__env?.neonRootDomain,
allowedLuxFeatures: window.__env?.allowedLuxFeatures || [],
cloudDataApiUrl: `${window.location?.protocol}//data.${window.__env?.cloudRootDomain}`,
luxDataHost: window.__env?.luxDataHost,
luxDataHost: window.__env?.luxDataHost
? stripTrailingSlash(window.__env.luxDataHost)
: // stripTrailingSlash is used to ensure correctness in Endpoints because we append /v1/graphql to luxDataHost in endpoints.
undefined,
userRole: window.__env?.userRole || undefined,
userId: window.__env?.userId || undefined,
consoleType: window.__env?.consoleType // FIXME : this check can be removed when the all CLI environments are set with the console type, some CLI environments could have empty consoleType

View File

@ -22,7 +22,7 @@ const SET_LATEST_SERVER_VERSION_SUCCESS =
const SET_LATEST_SERVER_VERSION_ERROR = 'Main/SET_LATEST_SERVER_VERSION_ERROR';
const UPDATE_MIGRATION_STATUS_SUCCESS = 'Main/UPDATE_MIGRATION_STATUS_SUCCESS';
const UPDATE_MIGRATION_STATUS_ERROR = 'Main/UPDATE_MIGRATION_STATUS_ERROR';
const HASURACTL_URL_ENV = 'Main/HASURACTL_URL_ENV';
const HASURA_CLI_SERVER_URL_ENV = 'Main/HASURA_CLI_SERVER_URL_ENV';
const UPDATE_MIGRATION_MODE = 'Main/UPDATE_MIGRATION_MODE';
const UPDATE_MIGRATION_MODE_PROGRESS = 'Main/UPDATE_MIGRATION_MODE_PROGRESS';
const EXPORT_METADATA_SUCCESS = 'Main/EXPORT_METADATA_SUCCESS';
@ -323,7 +323,7 @@ const featureCompatibilityInit = () => {
};
const loadMigrationStatus = () => dispatch => {
const url = Endpoints.hasuractlMigrateSettings;
const url = Endpoints.hasuraCliServerMigrateSettings;
const options = {
method: 'GET',
credentials: globalCookiePolicy,
@ -426,7 +426,7 @@ const loadLatestServerVersion = () => (dispatch, getState) => {
const updateMigrationModeStatus = () => (dispatch, getState) => {
// make req to hasura cli to update migration mode
dispatch({ type: UPDATE_MIGRATION_MODE_PROGRESS, data: true });
const url = Endpoints.hasuractlMigrateSettings;
const url = Endpoints.hasuraCliServerMigrateSettings;
const putBody = {
name: 'migration_mode',
value: (!getState().main.migrationMode).toString(),
@ -448,7 +448,7 @@ const updateMigrationModeStatus = () => (dispatch, getState) => {
credentials: globalCookiePolicy,
headers: { 'content-type': 'application/json' },
};
const metadataUrl = `${Endpoints.hasuractlMetadata}?export=true`;
const metadataUrl = `${Endpoints.hasuraCliServerMetadata}?export=true`;
return dispatch(
requestAction(
metadataUrl,
@ -573,8 +573,8 @@ const mainReducer = (state = defaultState, action) => {
readOnlyMode: action.data,
migrationMode: !action.data, // HACK
};
case HASURACTL_URL_ENV:
return { ...state, hasuractlEnv: action.data };
case HASURA_CLI_SERVER_URL_ENV:
return { ...state, hasuraCliServerEnv: action.data };
case UPDATE_MIGRATION_MODE:
const currentMode = state.migrationMode;
return { ...state, migrationMode: !currentMode };
@ -676,7 +676,7 @@ const mainReducer = (state = defaultState, action) => {
export default mainReducer;
export {
HASURACTL_URL_ENV,
HASURA_CLI_SERVER_URL_ENV,
UPDATE_MIGRATION_STATUS_SUCCESS,
UPDATE_MIGRATION_STATUS_ERROR,
UPDATE_ADMIN_SECRET_INPUT,

View File

@ -29,7 +29,7 @@ export type CloudProjectInfo = {
export interface MainState {
migrationError: unknown | null;
hasuractlEnv: unknown | null;
hasuraCliServerEnv: unknown | null;
migrationMode: boolean;
readOnlyMode: boolean;
migrationModeProgress: boolean;
@ -73,7 +73,7 @@ export interface MainState {
const defaultState: MainState = {
migrationError: null,
hasuractlEnv: null,
hasuraCliServerEnv: null,
migrationMode: true,
readOnlyMode: false,
migrationModeProgress: false,

View File

@ -14,6 +14,7 @@ import { saveAppState, clearState } from '../../AppState';
import { ADMIN_SECRET_HEADER_KEY } from '../../../constants';
import requestActionPlain from '../../../utils/requestActionPlain';
import { showErrorNotification } from '../Common/Notification';
import { getWebsocketProtocol } from '@/helpers/protocol';
const CHANGE_TAB = 'ApiExplorer/CHANGE_TAB';
const CHANGE_API_SELECTION = 'ApiExplorer/CHANGE_API_SELECTION';
@ -189,10 +190,9 @@ const changeRequestParams = newParams => {
};
const createWsClient = (url, headers) => {
const gqlUrl = new URL(url);
const websocketProtocol = gqlUrl.protocol === 'https:' ? 'wss' : 'ws';
const websocketProtocol = getWebsocketProtocol(url);
const headersFinal = getHeadersAsJSON(headers);
const graphqlUrl = `${websocketProtocol}://${url.split('//')[1]}`;
const graphqlUrl = `${websocketProtocol}//${url.split('//')[1]}`;
if (!websocketSubscriptionClient) {
websocketSubscriptionClient = getSubscriptionInstance(

View File

@ -23,8 +23,8 @@ type Query = {
const returnMigrateUrl = (migrationMode: boolean, upQueries?: Query[]) => {
if (globals.consoleMode === CLI_CONSOLE_MODE) {
return migrationMode
? Endpoints.hasuractlMigrate
: Endpoints.hasuractlMetadata;
? Endpoints.hasuraCliServerMigrate
: Endpoints.hasuraCliServerMetadata;
}
if (!upQueries) {
return Endpoints.query;

View File

@ -80,8 +80,8 @@ const trackAllItems =
if (isMigration) {
if (globals.consoleMode === CLI_CONSOLE_MODE) {
url = currMigrationMode
? Endpoints.hasuractlMigrate
: Endpoints.hasuractlMetadata;
? Endpoints.hasuraCliServerMigrate
: Endpoints.hasuraCliServerMetadata;
}
request = {
name: migrationName,
@ -157,7 +157,7 @@ const executeSQL =
args: schemaChangesUp,
};
// check if its a migration and send to hasuractl migrate
// check if its a migration and send to hasuraCliServer migrate
if (isMigration) {
url = migrateUrl;
requestBody = {

View File

@ -55,7 +55,7 @@ export function useMetadataMigration(
queryClient.fetchQuery({
queryKey: 'cliExport',
queryFn: () => {
const cliMetadataExportUrl = `${Endpoints.hasuractlMetadata}?export=true`;
const cliMetadataExportUrl = `${Endpoints.hasuraCliServerMetadata}?export=true`;
return Api.get<MetadataResponse>({
headers,
url: cliMetadataExportUrl,

View File

@ -25,8 +25,8 @@ export const returnMigrateUrl = (
) => {
if (globals.consoleMode === CLI_CONSOLE_MODE && !overrideCliMode) {
return migrationMode
? Endpoints.hasuractlMigrate
: Endpoints.hasuractlMetadata;
? Endpoints.hasuraCliServerMigrate
: Endpoints.hasuraCliServerMetadata;
}
if (!upQueries) {
return Endpoints.query;

View File

@ -0,0 +1,26 @@
import { getWebsocketProtocol } from './protocol';
describe('getWebsocketProtocol', () => {
const testCases = [
{
name: 'when invalid url is passed, returns default (ws) ',
input: '',
output: 'ws:',
},
{
name: 'when http url is passed, returns ws',
input: 'http:',
output: 'ws:',
},
{
name: 'when https url is passed, returns wss',
input: 'https:',
output: 'wss:',
},
];
testCases.forEach(({ input, output, name }) => {
it(name, () => {
expect(getWebsocketProtocol(input)).toEqual(output);
});
});
});

View File

@ -0,0 +1,10 @@
/*
Returns the right websocket protocol for the given URL protocol
Pass window.location.protocol to this function
*/
export const getWebsocketProtocol = (windowLocationProtocol: string) => {
if (windowLocationProtocol === 'https:') {
return 'wss:';
}
return 'ws:';
};

View File

@ -14,7 +14,7 @@ export function useMigrationMode(
queryOptions?: UseQueryOptions<{ migration_mode: boolean }, Error, boolean>
): UseQueryResult<boolean> {
const headers = useAppSelector(s => s.tables.dataHeaders);
const migrationUrl = Endpoints.hasuractlMigrateSettings;
const migrationUrl = Endpoints.hasuraCliServerMigrateSettings;
const { mode } = useConsoleConfig();
return useQuery({
queryKey: 'migrationMode',

View File

@ -42,7 +42,7 @@ import { FeatureFlags } from './features/FeatureFlags';
import { AllowListDetail } from './components/Services/AllowList';
const routes = store => {
// load hasuractl migration status
// load hasuraCliServer migration status
const requireMigrationStatus = (nextState, replaceState, cb) => {
const { dispatch } = store;