feat(ingestion-ui) Sort ingestion sources by last execution time (#5807)

This commit is contained in:
Chris Collins 2022-09-09 17:14:33 -04:00 committed by GitHub
parent de547a9af9
commit c4ac09d192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 4 deletions

View File

@ -15,7 +15,9 @@ import com.linkedin.metadata.search.SearchEntity;
import com.linkedin.metadata.search.SearchResult; import com.linkedin.metadata.search.SearchResult;
import graphql.schema.DataFetcher; import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingEnvironment;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -66,15 +68,20 @@ public class ListIngestionSourcesResolver implements DataFetcher<CompletableFutu
new HashSet<>(gmsResult.getEntities().stream() new HashSet<>(gmsResult.getEntities().stream()
.map(SearchEntity::getEntity) .map(SearchEntity::getEntity)
.collect(Collectors.toList())), .collect(Collectors.toList())),
ImmutableSet.of(Constants.INGESTION_INFO_ASPECT_NAME), ImmutableSet.of(Constants.INGESTION_INFO_ASPECT_NAME, Constants.INGESTION_SOURCE_KEY_ASPECT_NAME),
context.getAuthentication()); context.getAuthentication());
final Collection<EntityResponse> sortedEntities = entities.values()
.stream()
.sorted(Comparator.comparingLong(s -> -s.getAspects().get(Constants.INGESTION_SOURCE_KEY_ASPECT_NAME).getCreated().getTime()))
.collect(Collectors.toList());
// Now that we have entities we can bind this to a result. // Now that we have entities we can bind this to a result.
final ListIngestionSourcesResult result = new ListIngestionSourcesResult(); final ListIngestionSourcesResult result = new ListIngestionSourcesResult();
result.setStart(gmsResult.getFrom()); result.setStart(gmsResult.getFrom());
result.setCount(gmsResult.getPageSize()); result.setCount(gmsResult.getPageSize());
result.setTotal(gmsResult.getNumEntities()); result.setTotal(gmsResult.getNumEntities());
result.setIngestionSources(IngestionResolverUtils.mapIngestionSources(entities.values())); result.setIngestionSources(IngestionResolverUtils.mapIngestionSources(sortedEntities));
return result; return result;
} catch (Exception e) { } catch (Exception e) {

View File

@ -12,6 +12,7 @@ import com.linkedin.entity.EnvelopedAspectMap;
import com.linkedin.entity.client.EntityClient; import com.linkedin.entity.client.EntityClient;
import com.linkedin.ingestion.DataHubIngestionSourceInfo; import com.linkedin.ingestion.DataHubIngestionSourceInfo;
import com.linkedin.metadata.Constants; import com.linkedin.metadata.Constants;
import com.linkedin.metadata.key.DataHubIngestionSourceKey;
import com.linkedin.metadata.search.SearchEntity; import com.linkedin.metadata.search.SearchEntity;
import com.linkedin.metadata.search.SearchEntityArray; import com.linkedin.metadata.search.SearchEntityArray;
import com.linkedin.metadata.search.SearchResult; import com.linkedin.metadata.search.SearchResult;
@ -36,6 +37,8 @@ public class ListIngestionSourceResolverTest {
EntityClient mockClient = Mockito.mock(EntityClient.class); EntityClient mockClient = Mockito.mock(EntityClient.class);
DataHubIngestionSourceInfo returnedInfo = getTestIngestionSourceInfo(); DataHubIngestionSourceInfo returnedInfo = getTestIngestionSourceInfo();
final DataHubIngestionSourceKey key = new DataHubIngestionSourceKey();
key.setId("test");
Mockito.when(mockClient.search( Mockito.when(mockClient.search(
Mockito.eq(Constants.INGESTION_SOURCE_ENTITY_NAME), Mockito.eq(Constants.INGESTION_SOURCE_ENTITY_NAME),
@ -55,7 +58,7 @@ public class ListIngestionSourceResolverTest {
Mockito.when(mockClient.batchGetV2( Mockito.when(mockClient.batchGetV2(
Mockito.eq(Constants.INGESTION_SOURCE_ENTITY_NAME), Mockito.eq(Constants.INGESTION_SOURCE_ENTITY_NAME),
Mockito.eq(new HashSet<>(ImmutableSet.of(TEST_INGESTION_SOURCE_URN))), Mockito.eq(new HashSet<>(ImmutableSet.of(TEST_INGESTION_SOURCE_URN))),
Mockito.eq(ImmutableSet.of(Constants.INGESTION_INFO_ASPECT_NAME)), Mockito.eq(ImmutableSet.of(Constants.INGESTION_INFO_ASPECT_NAME, Constants.INGESTION_SOURCE_KEY_ASPECT_NAME)),
Mockito.any(Authentication.class) Mockito.any(Authentication.class)
)).thenReturn( )).thenReturn(
ImmutableMap.of( ImmutableMap.of(
@ -65,7 +68,9 @@ public class ListIngestionSourceResolverTest {
.setUrn(TEST_INGESTION_SOURCE_URN) .setUrn(TEST_INGESTION_SOURCE_URN)
.setAspects(new EnvelopedAspectMap(ImmutableMap.of( .setAspects(new EnvelopedAspectMap(ImmutableMap.of(
Constants.INGESTION_INFO_ASPECT_NAME, Constants.INGESTION_INFO_ASPECT_NAME,
new EnvelopedAspect().setValue(new Aspect(returnedInfo.data())) new EnvelopedAspect().setValue(new Aspect(returnedInfo.data())),
Constants.INGESTION_SOURCE_KEY_ASPECT_NAME,
new EnvelopedAspect().setValue(new Aspect(key.data()))
))) )))
) )
); );

View File

@ -49,12 +49,14 @@ function IngestionSourceTable({
dataIndex: 'type', dataIndex: 'type',
key: 'type', key: 'type',
render: TypeColumn, render: TypeColumn,
sorter: (sourceA, sourceB) => sourceA.type.localeCompare(sourceB.type),
}, },
{ {
title: 'Name', title: 'Name',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
render: (name: string) => name || '', render: (name: string) => name || '',
sorter: (sourceA, sourceB) => sourceA.name.localeCompare(sourceB.name),
}, },
{ {
title: 'Schedule', title: 'Schedule',
@ -67,12 +69,14 @@ function IngestionSourceTable({
dataIndex: 'execCount', dataIndex: 'execCount',
key: 'execCount', key: 'execCount',
render: (execCount: any) => <Typography.Text>{execCount || '0'}</Typography.Text>, render: (execCount: any) => <Typography.Text>{execCount || '0'}</Typography.Text>,
sorter: (sourceA, sourceB) => sourceA.execCount - sourceB.execCount,
}, },
{ {
title: 'Last Execution', title: 'Last Execution',
dataIndex: 'lastExecTime', dataIndex: 'lastExecTime',
key: 'lastExecTime', key: 'lastExecTime',
render: LastExecutionColumn, render: LastExecutionColumn,
sorter: (sourceA, sourceB) => sourceA.lastExecTime - sourceB.lastExecTime,
}, },
{ {
title: 'Last Status', title: 'Last Status',
@ -81,6 +85,7 @@ function IngestionSourceTable({
render: (status: any, record) => ( render: (status: any, record) => (
<LastStatusColumn status={status} record={record} setFocusExecutionUrn={setFocusExecutionUrn} /> <LastStatusColumn status={status} record={record} setFocusExecutionUrn={setFocusExecutionUrn} />
), ),
sorter: (sourceA, sourceB) => (sourceA.lastExecStatus || '').localeCompare(sourceB.lastExecStatus || ''),
}, },
{ {
title: '', title: '',