mirror of
https://github.com/datahub-project/datahub.git
synced 2025-09-01 13:23:09 +00:00
feat(ingestion-ui) Sort ingestion sources by last execution time (#5807)
This commit is contained in:
parent
de547a9af9
commit
c4ac09d192
@ -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) {
|
||||||
|
@ -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()))
|
||||||
)))
|
)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -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: '',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user