Skip to content

Commit

Permalink
refactor: ♻️ Convert addresses to services
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoval committed Dec 17, 2024
1 parent f113fd5 commit 1c81c4e
Show file tree
Hide file tree
Showing 15 changed files with 53 additions and 40 deletions.
5 changes: 3 additions & 2 deletions __tests__/TopologyDetails.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { Providers } from '../src/providers';
import TopologyDetails from '../src/pages/Topology/components/TopologyDetails';
import { ProcessPairsResponse, ProcessResponse } from '../src/types/REST.interfaces';
import { DEFAULT_COMPLEX_STRING_SEPARATOR } from '../src/config/app';
import { mapResponseProperties } from '../src/API/REST.utils';

const processesResults = processesData.results as ProcessResponse[];
const processesResults = mapResponseProperties(processesData.results, 'toFrontend') as ProcessResponse[];
const processPairsResults = processesPairsData.results as ProcessPairsResponse[];

describe('Topology details', () => {
Expand Down Expand Up @@ -125,7 +126,7 @@ describe('Topology details', () => {
expect(screen.getAllByText(processesResults[12].parentName)[0]).toBeInTheDocument();
expect(
screen.getAllByText(
(processesResults[12].addresses as string[])[0]?.split(DEFAULT_COMPLEX_STRING_SEPARATOR)[0] as string
(processesResults[12].services as string[])[0]?.split(DEFAULT_COMPLEX_STRING_SEPARATOR)[0] as string
)[0]
).toBeInTheDocument();
});
Expand Down
2 changes: 1 addition & 1 deletion mocks/server.API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const MockApi = {
const processesByServiceIds = processes.results
.filter(
({ addresses }) =>
addresses && addresses.some((address) => address.split(DEFAULT_COMPLEX_STRING_SEPARATOR)[1] === id)
addresses && addresses.some((service) => service.split(DEFAULT_COMPLEX_STRING_SEPARATOR)[1] === id)
)
.map(({ identity }) => identity);

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@
}
},
"browserslist": [
"defaults",
"not IE 11",
"maintained node versions"
" > 0.2%",
"not dead",
"not op_mini all"
]
}
20 changes: 15 additions & 5 deletions src/API/REST.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Protocols, SortDirection } from './REST.enum';
import { backendToFrontendPropertydMapper } from '../config/api';
import { backendToFrontendPropertyMapper } from '../config/api';
import { PairsResponse, RouterLinkResponse, QueryFilters, QueryParams } from '../types/REST.interfaces';

/*
Expand Down Expand Up @@ -82,13 +82,24 @@ export const aggregateLinksBySite = (linksData: RouterLinkResponse[]): RouterLin
* Maps the data in the response object based on a provided field mapping.
* Transforms the keys in the `results` array or object to align with the specified mapping.
*/
export function mapResponseProperties<T>(results: T): T {
// Helper function to map a single item
export function mapResponseProperties<T>(results: T, direction: 'toFrontend' | 'toBackend'): T {
// Helper per invertire la mappa al volo
const mapKey = (key: string) => {
if (direction === 'toFrontend') {
return backendToFrontendPropertyMapper[key] || key;
}
// Trova la chiave inversa nella mappa per 'toBackend'
const entry = Object.entries(backendToFrontendPropertyMapper).find(([, value]) => value === key);

return entry ? entry[0] : key;
};

// Helper per mappare un singolo oggetto
const mapItem = (item: Record<string, unknown>) => {
const mappedItem = {} as Record<string, unknown>;
for (const key in item) {
if (Object.prototype.hasOwnProperty.call(item, key)) {
const mappedKey = backendToFrontendPropertydMapper[key] || key;
const mappedKey = mapKey(key);
mappedItem[mappedKey] = item[key];
}
}
Expand All @@ -101,7 +112,6 @@ export function mapResponseProperties<T>(results: T): T {
return results.map(mapItem) as T;
}

// If results is a single object (not an array), map it directly
return mapItem(results as Record<string, unknown>) as T;
}

Expand Down
4 changes: 2 additions & 2 deletions src/API/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import { QueryFilters, ApiResponse } from '../types/REST.interfaces';
* Maps the `results` field of the response using the provided field mapping.
*/
export const fetchApiDataWithMapper = async <T>(url: string, options?: QueryFilters): Promise<ApiResponse<T>> => {
const params = options ? mapFiltersToRequestQueryParams(options) : null;
const params = options ? mapFiltersToRequestQueryParams(mapResponseProperties(options, 'toBackend')) : null;
const data = await fetchApiData<ApiResponse<T>>(url, { params });

return { ...data, results: mapResponseProperties<T>(data.results) };
return { ...data, results: mapResponseProperties(data.results, 'toFrontend') };
};

/**
Expand Down
6 changes: 4 additions & 2 deletions src/config/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const MSG_TIMEOUT_ERROR = 'The request to fetch the data has timed out.';
in transforming the data received from the backend into a format
that can be used directly by the frontend for display or further processing.
*/
export const backendToFrontendPropertydMapper: Record<string, string> = {
export const backendToFrontendPropertyMapper: Record<string, string> = {
identity: 'identity',
startTime: 'startTime',
endTime: 'endTime',
Expand Down Expand Up @@ -66,7 +66,9 @@ export const backendToFrontendPropertydMapper: Record<string, string> = {
sourceHost: 'sourceHost',
processBinding: 'processBinding',
processRole: 'processRole',
addresses: 'addresses',
addresses: 'services',
address: 'service',
addressId: 'serviceId',
processPairs: 'processPairs',
prometheusKey: 'prometheusKey',
processPairsKey: 'processPairsKey',
Expand Down
2 changes: 1 addition & 1 deletion src/config/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const BIG_PAGINATION_SIZE = 20;
export const SMALL_PAGINATION_SIZE = 10;

export const EMPTY_VALUE_SYMBOL = '-';
export const DEFAULT_COMPLEX_STRING_SEPARATOR = '@'; // process -> addresses format and connector name format
export const DEFAULT_COMPLEX_STRING_SEPARATOR = '@'; // used for: 1) process -> services format and 2) connector name format

/** Tests */
export const waitForElementToBeRemovedTimeout = 10000;
6 changes: 3 additions & 3 deletions src/pages/Processes/components/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const Details: FC<DetailsProps> = function ({ process, title }) {
hostName,
startTime,
processBinding,
addresses
services
} = process;

return (
Expand Down Expand Up @@ -113,13 +113,13 @@ const Details: FC<DetailsProps> = function ({ process, title }) {
</DescriptionListGroup>
</GridItem>

{!!addresses?.length && (
{!!services?.length && (
<GridItem span={6}>
<DescriptionListGroup>
<DescriptionListTerm>{Labels.RoutingKeys}</DescriptionListTerm>
<DescriptionListDescription>
<Flex>
{addresses.map((service) => (
{services.map((service) => (
<div key={service}>
<ResourceIcon type="service" />
<Link to={`${ServicesRoutesPaths.Services}/${service}`}>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Services/hooks/useListenersAndConnectorsData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ const useListenersAndConnectorsData = (serviceId: string) => {
queries: [
{
queryKey: [getAllListeners(), serviceId],
queryFn: () => RESTApi.fetchListeners({ addressId: serviceId }),
queryFn: () => RESTApi.fetchListeners({ serviceId }),
refetchInterval: UPDATE_INTERVAL
},
{
queryKey: [getAllConnectors(), serviceId],
queryFn: () => RESTApi.fetchConnectors({ addressId: serviceId }),
queryFn: () => RESTApi.fetchConnectors({ serviceId }),
refetchInterval: UPDATE_INTERVAL
}
]
Expand Down
8 changes: 4 additions & 4 deletions src/pages/Services/hooks/useServiceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ const useServiceData = (serviceId: string) => {
});

const { data: serversData } = useQuery({
queryKey: [getAllProcesses(), { ...initServersQueryParams, addresses: [service.results.identity] }],
queryFn: () => RESTApi.fetchProcesses({ ...initServersQueryParams, addresses: [service.results.identity] }),
queryKey: [getAllProcesses(), { ...initServersQueryParams, services: [service.results.identity] }],
queryFn: () => RESTApi.fetchProcesses({ ...initServersQueryParams, services: [service.results.identity] }),
refetchInterval: UPDATE_INTERVAL
});

Expand All @@ -61,13 +61,13 @@ const useServiceData = (serviceId: string) => {

const { data: listenersData } = useQuery({
queryKey: [getAllListeners(), initServersQueryParams],
queryFn: () => RESTApi.fetchListeners({ ...initServersQueryParams, addressId: serviceId }),
queryFn: () => RESTApi.fetchListeners({ ...initServersQueryParams, serviceId }),
refetchInterval: UPDATE_INTERVAL
});

const { data: connectorsData } = useQuery({
queryKey: [getAllConnectors(), initServersQueryParams],
queryFn: () => RESTApi.fetchConnectors({ ...initServersQueryParams, addressId: serviceId }),
queryFn: () => RESTApi.fetchConnectors({ ...initServersQueryParams, serviceId }),
refetchInterval: UPDATE_INTERVAL
});

Expand Down
10 changes: 5 additions & 5 deletions src/pages/Services/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export const ServicesController = {
},

mapListenersToRoutingKey: (listeners: ListenerResponse[]) =>
listeners.map(({ identity, name, siteId, siteName, address, addressId }) => ({
listeners.map(({ identity, name, siteId, siteName, service, serviceId }) => ({
sourceId: identity,
sourceName: name,
siteId: `${siteId}-listener`, // Avoids including connectors and processes in the combo
siteName,
destinationId: addressId,
destinationName: address,
destinationId: serviceId,
destinationName: service,
type: 'SkEmptyNode' as GraphElementNames,
iconName: 'listener' as GraphIconKeys
})),
Expand All @@ -50,8 +50,8 @@ export const ServicesController = {
mapRoutingKeyToAggregatedConnectors: (aggregatedConnectors: ConnectorResponse[], id: string, name: string) =>
aggregatedConnectors.length
? aggregatedConnectors.map((item) => ({
sourceId: item.addressId,
sourceName: item.address,
sourceId: item.serviceId,
sourceName: item.service,
destinationId: `${item.name}-${item.siteId}-${item.destPort}`,
destinationName: `${item.name}:${item.destPort}`,
type: 'SkEmptyNode' as GraphElementNames,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Topology/components/NodeDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ const NodeDetails: FC<{ data: ProcessResponse[]; metrics: TopologyMetrics }> = f
</FlexItem>

<FlexItem>
{itemSelected?.addresses?.map((service) => (
{itemSelected?.services?.map((service) => (
<Fragment key={service}>
<ResourceIcon type="service" />
<Link
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Topology/services/topologyProcessController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const TopologyProcessController = {
// a process can be filered by services
if (serviceIdsSelected) {
const serverIds = processesSelected
.filter(({ addresses: services }) =>
.filter(({ services: services }) =>
services
?.map((service) => parseService(service).serviceId)
.some((service) => serviceIdsSelected.includes(service))
Expand Down Expand Up @@ -131,7 +131,7 @@ function findMatched(processNodes: GraphNode[] | GraphEdge[], idsSelected?: stri
function filterProcessesBySelectedServices(processes: ProcessResponse[], serviceIdSelected: string[]) {
return processes.filter(
(process) =>
process.addresses?.some((address) => serviceIdSelected.some((serviceId) => address.includes(`@${serviceId}`))) ||
process.services?.some((service) => serviceIdSelected.some((serviceId) => service.includes(`@${serviceId}`))) ||
serviceIdSelected.includes(process.identity)
);
}
Expand Down
10 changes: 5 additions & 5 deletions src/types/REST.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export interface ProcessResponse extends BaseResponse {
processRole: Role;
hostName: string | null;
imageName: string | null;
addresses: string[] | null;
services: string[] | null;
}

export interface BasePairs {
Expand All @@ -121,8 +121,8 @@ export type PairsResponse = BasePairsResponse | ProcessPairsResponse;
export interface ListenerResponse extends BaseResponse {
name: string;
parent: string;
addressId: string;
address: string;
serviceId: string;
service: string;
destHost: string;
destPort: number;
processId: string;
Expand All @@ -133,8 +133,8 @@ export interface ListenerResponse extends BaseResponse {
export interface ConnectorResponse extends BaseResponse {
name: string;
parent: string;
addressId: string;
address: string;
serviceId: string;
service: string;
destHost: string;
destPort: number;
processId: string;
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@
},

// Include the following directories for type-checking and compiling
"include": ["src", "__tests__", "jest.config.ts", "mocks"],
"include": ["src", "jest.config.ts"],

// Exclude unnecessary directories like build and node_modules from type-checking
// Cypress config is excluded due to a known issue: https://github.com/cypress-io/cypress/issues/22059
"exclude": ["node_modules", "build", "cypress.config.ts"]
"exclude": ["node_modules", "build", "cypress.config.ts", "__tests__", "mocks"]
}

0 comments on commit 1c81c4e

Please sign in to comment.