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

Depreciate data-plane gateway authorization for shard and journal information #1264

Merged
merged 18 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
940af97
Depreciate use of gateway_auth_token rpc in useShardsList
kiahna-tucker Sep 20, 2024
8b11ec9
Store task authorization endpoints in env variables
kiahna-tucker Sep 20, 2024
bf44b58
Depreciate use of gateway_auth_token rpc in useJournalsForCollection
kiahna-tucker Sep 20, 2024
1e3309b
Placeholder: journal hook integration
kiahna-tucker Sep 20, 2024
c89c7ea
Depreciate use of gateway_auth_token rpc in useJournalData
kiahna-tucker Sep 23, 2024
3260fd9
Store collection authorization endpoints in env variables
kiahna-tucker Sep 23, 2024
1fd8162
Remove ops logs warning displayed in local environments
kiahna-tucker Sep 23, 2024
0cf086d
Update getAuthToken type annotation
kiahna-tucker Sep 23, 2024
9190abc
Reset journal store state when hydrator unmounts
kiahna-tucker Sep 23, 2024
a2766cb
Remove unused overloads of dataPlaneFetcher_list
kiahna-tucker Sep 23, 2024
97a80d6
Use fetch helper instead of standard fetch function
kiahna-tucker Sep 23, 2024
5f134dc
Merge branch 'main' into kiahna-tucker/depreciate-data-plane-gateway
kiahna-tucker Sep 23, 2024
b038f59
Prevent standard collections from hitting the task authorization endp…
kiahna-tucker Sep 23, 2024
92a852a
Add shard_template_id to the base live_spec_ext column array
kiahna-tucker Sep 24, 2024
775b573
Extend comment coverage
kiahna-tucker Sep 24, 2024
beffe6e
Use array length util when processing shard status
kiahna-tucker Sep 24, 2024
6d9c124
Merge branch 'main' into kiahna-tucker/depreciate-data-plane-gateway
kiahna-tucker Sep 24, 2024
4caf48d
Consolidate broker-related journal store selectors in useJournalData
kiahna-tucker Sep 24, 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
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFz

VITE_GATEWAY_AUTH_TOKEN_URL=https://eyrcnmuzzyriypdajwdk.supabase.co/rest/v1/rpc/gateway_auth_token

VITE_TASK_AUTHORIZATION_URL=https://agent-api-1084703453822.us-central1.run.app/authorize/user/task
VITE_COLLECTION_AUTHORIZATION_URL=https://agent-api-1084703453822.us-central1.run.app/authorize/user/collection

VITE_MARKETPLACE_VERIFY_URL=https://gcp-marketplace-verify-mo7rswd2xq-uc.a.run.app

# These settings require an application restart to enable right now
Expand Down
3 changes: 3 additions & 0 deletions .env.development.local
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFz

VITE_GATEWAY_AUTH_TOKEN_URL=http://localhost:5431/rest/v1/rpc/gateway_auth_token

VITE_TASK_AUTHORIZATION_URL=http://localhost:8675/authorize/user/task
VITE_COLLECTION_AUTHORIZATION_URL=http://localhost:8675/authorize/user/collection

VITE_MARKETPLACE_VERIFY_URL=http://example.com

VITE_SHOW_EMAIL_LOGIN=true
Expand Down
1 change: 1 addition & 0 deletions src/api/liveSpecsExt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const baseColumns = [
'spec_type',
'updated_at',
'last_pub_id',
'shard_template_id',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 🎉 🎉 🎉 🎉 🎉

];

const commonColumns = baseColumns.concat([
Expand Down
Binary file not shown.
4 changes: 2 additions & 2 deletions src/components/collection/DataPreview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export function DataPreview({ collectionName }: Props) {

// TODO (typing) we need to fix typing
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const journal = useMemo(() => journalsData?.journals?.[0], [journalsData]);
const journalData = useJournalData(journal?.name, collectionName, {
const journal = useMemo(() => journalsData?.journals[0], [journalsData]);
const journalData = useJournalData(journal?.spec?.name, {
desiredCount: 20,
});

Expand Down
55 changes: 24 additions & 31 deletions src/components/shared/Entity/Details/Ops/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { Box, Stack } from '@mui/material';
import useJournalNameForLogs from 'hooks/journals/useJournalNameForLogs';
import AlertBox from 'components/shared/AlertBox';
import Message from 'components/shared/Error/Message';
import LogsTable from 'components/tables/Logs';
import useGlobalSearchParams, {
GlobalSearchParams,
} from 'hooks/searchParams/useGlobalSearchParams';
import LogsTable from 'components/tables/Logs';
import JournalDataLogsHydrator from 'stores/JournalData/Logs/Hydrator';
import AlertBox from 'components/shared/AlertBox';
import { FormattedMessage } from 'react-intl';
import Message from 'components/shared/Error/Message';
import { BASE_ERROR } from 'services/supabase';
import JournalHydrator from 'stores/JournalData/Hydrator';
import JournalDataLogsHydrator from 'stores/JournalData/Logs/Hydrator';
import { useJournalDataLogsStore } from 'stores/JournalData/Logs/Store';
import { isProduction } from 'utils/env-utils';
import useEntityShouldShowLogs from '../useEntityShouldShowLogs';
import useDetailsEntityTaskTypes from '../useDetailsEntityTaskTypes';
import useEntityShouldShowLogs from '../useEntityShouldShowLogs';

// TODO: Display the logs table in a loading state until the initial journal
// data can be fetched.
function Ops() {
const taskTypes = useDetailsEntityTaskTypes();
const catalogName = useGlobalSearchParams(GlobalSearchParams.CATALOG_NAME);
const [name, collectionName] = useJournalNameForLogs(
catalogName,
taskTypes
);
const taskTypes = useDetailsEntityTaskTypes();

const hydrationError = useJournalDataLogsStore(
(state) => state.hydrationError
Expand All @@ -37,18 +34,14 @@ function Ops() {
}

return (
<JournalDataLogsHydrator name={name} collectionName={collectionName}>
<Stack spacing={2}>
<Box>
{hydrationError ? (
<>
{isProduction ? null : (
<AlertBox severity="warning" short>
With V2 of Control Plane logs in the UI will
not work due to an issue with the selector.
</AlertBox>
)}

<JournalHydrator
catalogName={catalogName}
isCollection={taskTypes.length === 0}
>
<JournalDataLogsHydrator>
<Stack spacing={2}>
<Box>
{hydrationError ? (
<AlertBox
severity="error"
title={
Expand All @@ -63,13 +56,13 @@ function Ops() {
}}
/>
</AlertBox>
</>
) : (
<LogsTable />
)}
</Box>
</Stack>
</JournalDataLogsHydrator>
) : (
<LogsTable />
)}
</Box>
</Stack>
</JournalDataLogsHydrator>
</JournalHydrator>
);
}

Expand Down
8 changes: 7 additions & 1 deletion src/components/shared/Entity/Details/Overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useGlobalSearchParams, {
} from 'hooks/searchParams/useGlobalSearchParams';
import { LiveSpecsQuery_details } from 'hooks/useLiveSpecs';
import { useMemo } from 'react';
import JournalHydrator from 'stores/JournalData/Hydrator';
import { hasLength } from 'utils/misc-utils';
import ShardInformation from '../../Shard/Information';
import Usage from '../Usage';
Expand Down Expand Up @@ -76,7 +77,12 @@ function Overview({ name }: Props) {

{isCollection && entityName ? (
<Grid item xs={12}>
<DataPreview collectionName={entityName} />
<JournalHydrator
catalogName={entityName}
isCollection={isCollection}
>
<DataPreview collectionName={entityName} />
</JournalHydrator>
</Grid>
) : null}
</Grid>
Expand Down
2 changes: 2 additions & 0 deletions src/components/shared/Entity/Details/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { useMemo } from 'react';
import { EditorStoreNames } from 'stores/names';
import ShardHydrator from '../Shard/Hydrator';

// TODO: Hydrate the journal store in a single location that satisfies
// the needs of components dependent on its state.
function EntityDetails() {
useBrowserTitle('routeTitle.details');

Expand Down
5 changes: 4 additions & 1 deletion src/components/shared/Entity/Shard/Hydrator.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import useShardHydration from 'hooks/shards/useShardHydration';
import { BaseComponentProps } from 'types';
import useDetailsEntityTaskTypes from '../Details/useDetailsEntityTaskTypes';

interface Props extends BaseComponentProps {
catalogName: string;
}

function ShardHydrator({ catalogName, children }: Props) {
useShardHydration([catalogName]);
const taskTypes = useDetailsEntityTaskTypes();

useShardHydration(taskTypes.length === 0 ? [] : [catalogName]);

// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{children}</>;
Expand Down
5 changes: 4 additions & 1 deletion src/components/tables/hooks/useRowsWithStatsState.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future change (cause my branch is not done yet) but I'll probably pull this filter into the entity-utils file.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ function useRowsWithStatsState(
data: Data
) {
const catalogNames = useMemo(
() => data.map((datum) => datum.catalog_name),
() =>
data
.filter((datum) => datum.shard_template_id)
.map((datum) => datum.catalog_name),
[data]
);

Expand Down
92 changes: 60 additions & 32 deletions src/hooks/journals/useJournalData.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { singleCallSettings } from 'context/SWR';
import { useUserStore } from 'context/User/useUserContextStore';
import { JournalClient, JournalSelector } from 'data-plane-gateway';
import useGatewayAuthToken from 'hooks/gatewayAuthToken/useGatewayAuthToken';
import { isEmpty } from 'lodash';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useCounter } from 'react-use';
import useJournalStore from 'stores/JournalData/Store';
import useSWR from 'swr';
import {
dataPlaneFetcher_list,
getJournals,
MAX_DOCUMENT_SIZE,
shouldRefreshToken,
} from 'utils/dataPlane-utils';
import { useUserStore } from 'context/User/useUserContextStore';
import { hasLength } from 'utils/misc-utils';
import { loadDocuments } from './shared';
import { LoadDocumentsOffsets } from './types';

Expand All @@ -21,54 +23,66 @@ const useJournalsForCollection = (collectionName: string | undefined) => {
const [attempts, { inc: incAttempts, reset: resetAttempts }] =
useCounter(0);

const { data: gatewayConfig, refresh: refreshAuthToken } =
useGatewayAuthToken(collectionName ? [collectionName] : []);
const refreshAuthToken = useJournalStore((state) => state.getAuthToken);
const brokerAddress = useJournalStore(
(state) => state.collectionBrokerAddress
);
const brokerToken = useJournalStore((state) => state.collectionBrokerToken);

const journalClient = useMemo(() => {
if (gatewayConfig?.gateway_url && gatewayConfig.token) {
const authToken = gatewayConfig.token;
const baseUrl = new URL(gatewayConfig.gateway_url);
if (brokerAddress && brokerToken) {
const baseUrl = new URL(brokerAddress);

return new JournalClient(baseUrl, authToken);
return new JournalClient(baseUrl, brokerToken);
} else {
return null;
}
}, [gatewayConfig]);
}, [brokerAddress, brokerToken]);

const fetcher = useCallback(
async (_url: string) => {
if (journalClient && collectionName) {
if (
journalClient &&
collectionName &&
brokerAddress &&
brokerToken
Comment on lines +47 to +48
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really wish typescript was smart enough to not need this.

) {
const journalSelector = new JournalSelector().collection(
collectionName
);

const dataPlaneListResponse = await dataPlaneFetcher_list(
journalClient,
journalSelector,
'JournalData'
const dataPlaneListResponse = await getJournals(
brokerAddress,
brokerToken,
{
include: journalSelector.toLabelSet(),
}
);

if (!Array.isArray(dataPlaneListResponse)) {
if (isEmpty(dataPlaneListResponse)) {
return Promise.reject(dataPlaneListResponse);
}

return {
journals:
dataPlaneListResponse.length > 0
? dataPlaneListResponse
dataPlaneListResponse.result.journals &&
dataPlaneListResponse.result.journals.length > 0
? dataPlaneListResponse.result.journals
: [],
Comment on lines +68 to 71
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we know that the dataPlaneListResponse.result.journals is always an array then I think we could just always return it. Cause even if it is an empty array then that is basically what we're defaulting here.

};
} else {
return null;
}
},
[collectionName, journalClient]
[brokerAddress, brokerToken, collectionName, journalClient]
);

const response = useSWR(
collectionName
collectionName && brokerToken
? `journals-${collectionName}-${
gatewayConfig?.gateway_url ?? '__missing_gateway_url__'
hasLength(brokerAddress)
? brokerAddress
: '__missing_broker_address__'
}`
: null,
fetcher,
Expand All @@ -81,8 +95,16 @@ const useJournalsForCollection = (collectionName: string | undefined) => {
onError: async (error) => {
incAttempts();

if (session && shouldRefreshToken(`${error}`)) {
await refreshAuthToken();
if (
session &&
shouldRefreshToken(`${error}`) &&
collectionName
) {
await refreshAuthToken(
session.access_token,
collectionName,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine for now... but we probably don't want to use the collectionName from the outer scope. Rather I think we can read it from the swr config that should be getting passed in to the onError.

true
);
resetAttempts();
}

Expand All @@ -107,28 +129,34 @@ interface UseJournalDataSettings {
desiredCount?: number;
maxBytes?: number;
}

const useJournalData = (
journalName?: string,
collectionName?: string,
settings?: UseJournalDataSettings
settings?: UseJournalDataSettings,
opsJournalTarget?: boolean
) => {
const failures = useRef(0);
const initialLoadComplete = useRef(false);

const { data: gatewayConfig } = useGatewayAuthToken(
collectionName ? [collectionName] : null
const brokerAddress = useJournalStore((state) =>
opsJournalTarget
? state.taskBrokerAddress
: state.collectionBrokerAddress
);

const brokerToken = useJournalStore((state) =>
opsJournalTarget ? state.taskBrokerToken : state.collectionBrokerToken
);
kiahna-tucker marked this conversation as resolved.
Show resolved Hide resolved

const journalClient = useMemo(() => {
if (journalName && gatewayConfig?.gateway_url && gatewayConfig.token) {
const authToken = gatewayConfig.token;
const baseUrl = new URL(gatewayConfig.gateway_url);
if (brokerAddress && brokerToken) {
const baseUrl = new URL(brokerAddress);

return new JournalClient(baseUrl, authToken);
return new JournalClient(baseUrl, brokerToken);
} else {
return undefined;
}
}, [gatewayConfig, journalName]);
}, [brokerAddress, brokerToken]);

const [data, setData] =
useState<Awaited<ReturnType<typeof loadDocuments>>>();
Expand Down
28 changes: 0 additions & 28 deletions src/hooks/journals/useJournalNameForLogs.ts

This file was deleted.

Loading
Loading