diff --git a/x-pack/plugins/observability_solution/apm/server/routes/service_map/transform_service_map_responses.ts b/x-pack/plugins/observability_solution/apm/server/routes/service_map/transform_service_map_responses.ts index 824ec0e7fcc1b..c57a5bafb56d0 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/service_map/transform_service_map_responses.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/service_map/transform_service_map_responses.ts @@ -86,9 +86,25 @@ export function getAllNodes( return allNodes; } -export function getServiceNodes(allNodes: ConnectionNode[]) { +export function getServiceNodes( + allNodes: ConnectionNode[], + discoveredServices: Array<{ + from: ExternalConnectionNode; + to: ServiceConnectionNode; + }> +) { + const connectionFromDiscoveredServices = discoveredServices + .filter(({ from, to }) => { + return ( + allNodes.some((node) => node.id === getConnectionNodeId(from)) && + !allNodes.some((node) => node.id === to[SERVICE_NAME]) + ); + }) + .map(({ to }) => ({ ...to, id: getConnectionNodeId(to) })); // List of nodes that are services - const serviceNodes = allNodes.filter((node) => SERVICE_NAME in node) as ServiceConnectionNode[]; + const serviceNodes = [...allNodes, ...connectionFromDiscoveredServices].filter( + (node) => SERVICE_NAME in node + ) as ServiceConnectionNode[]; return serviceNodes; } @@ -108,12 +124,16 @@ export function transformServiceMapResponses({ const { discoveredServices, services, connections, anomalies } = response; const allConnections = addMessagingConnections(connections, discoveredServices); const allNodes = getAllNodes(services, allConnections); - const serviceNodes = getServiceNodes(allNodes); + const serviceNodes = getServiceNodes(allNodes, discoveredServices); // List of nodes that are externals - const externalNodes = allNodes.filter( - (node) => SPAN_DESTINATION_SERVICE_RESOURCE in node - ) as ExternalConnectionNode[]; + const externalNodes = Array.from( + new Set( + allNodes.filter( + (node) => SPAN_DESTINATION_SERVICE_RESOURCE in node + ) as ExternalConnectionNode[] + ) + ); // 1. Map external nodes to internal services // 2. Collapse external nodes into one node based on span.destination.service.resource diff --git a/x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts b/x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts index 334b73d8db4cb..83965595020da 100644 --- a/x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts +++ b/x-pack/test/apm_api_integration/tests/service_maps/service_maps.spec.ts @@ -153,13 +153,11 @@ export default function serviceMapsApiTests({ getService }: FtrProviderContext) it('returns the correct data', () => { const elements: Array<{ data: Record }> = response.body.elements; - const serviceNames = uniq( elements .filter((element) => element.data['service.name'] !== undefined) .map((element) => element.data['service.name']) ).sort(); - expectSnapshot(serviceNames).toMatchInline(` Array [ "auditbeat", diff --git a/x-pack/test/apm_api_integration/tests/service_maps/service_maps_kuery_filter.spec.ts b/x-pack/test/apm_api_integration/tests/service_maps/service_maps_kuery_filter.spec.ts index 4be91cbe7bab6..b87e0de70495e 100644 --- a/x-pack/test/apm_api_integration/tests/service_maps/service_maps_kuery_filter.spec.ts +++ b/x-pack/test/apm_api_integration/tests/service_maps/service_maps_kuery_filter.spec.ts @@ -41,7 +41,6 @@ export default function ApiTest({ getService }: FtrProviderContext) { } registry.when('Service Map', { config: 'trial', archives: [] }, () => { - // FLAKY: https://github.com/elastic/kibana/issues/176982 describe('optional kuery param', () => { before(async () => { const events = timerange(start, end)