use of org.hypertrace.core.query.service.api.Filter in project gateway-service by hypertrace.
the class EntityInteractionsFetcher method buildQueryRequests.
@VisibleForTesting
Map<String, QueryRequest> buildQueryRequests(long startTime, long endTime, String spaceId, String entityType, InteractionsRequest interactionsRequest, Set<EntityKey> entityIds, boolean incoming, RequestContext requestContext) {
Set<String> entityTypes = getOtherEntityTypes(interactionsRequest.getFilter());
if (entityTypes.isEmpty()) {
return Collections.emptyMap();
}
QueryRequest.Builder builder = QueryRequest.newBuilder();
// Filter should include the timestamp filters from parent request first
Filter.Builder filterBuilder = Filter.newBuilder().setOperator(Operator.AND).addChildFilter(QueryRequestUtil.createBetweenTimesFilter(AttributeMetadataUtil.getTimestampAttributeId(metadataProvider, requestContext, SCOPE), startTime, endTime));
this.buildSpaceQueryFilterIfNeeded(requestContext, spaceId).ifPresent(filterBuilder::addChildFilter);
List<String> idColumns = getEntityIdColumnsFromInteraction(DomainEntityType.valueOf(entityType), !incoming);
// Add a filter on the entityIds
filterBuilder.addChildFilter(createFilterForEntityKeys(idColumns, entityIds));
// Group by the entity id column first, then the other end entity type for the interaction.
List<org.hypertrace.core.query.service.api.Expression> idExpressions = idColumns.stream().map(QueryRequestUtil::createAttributeExpression).collect(Collectors.toList());
builder.addAllGroupBy(idExpressions);
List<org.hypertrace.core.query.service.api.Expression> selections = new ArrayList<>();
for (Expression expression : interactionsRequest.getSelectionList()) {
// Ignore the predefined selections because they're handled specially.
if (ExpressionReader.isSimpleAttributeSelection(expression) && SELECTIONS_TO_IGNORE.contains(ExpressionReader.getAttributeIdFromAttributeSelection(expression).orElseThrow())) {
continue;
}
// Selection should have metrics and attributes that were requested
selections.add(QueryAndGatewayDtoConverter.convertToQueryExpression(expression).build());
}
// so we add count(*) as a dummy placeholder if there are no explicit selectors.
if (selections.isEmpty()) {
selections.add(QueryRequestUtil.createCountByColumnSelection(Optional.ofNullable(idColumns.get(0)).orElseThrow()));
}
QueryRequest protoType = builder.build();
Filter protoTypeFilter = filterBuilder.build();
Map<String, QueryRequest> queryRequests = new HashMap<>();
// response time.
for (String e : entityTypes) {
DomainEntityType otherEntityType = DomainEntityType.valueOf(e.toUpperCase());
// Get the filters from the interactions request to 'AND' them with the timestamp filter.
Filter.Builder filterCopy = Filter.newBuilder(protoTypeFilter);
filterCopy.addChildFilter(convertToQueryFilter(interactionsRequest.getFilter(), otherEntityType));
QueryRequest.Builder builderCopy = QueryRequest.newBuilder(protoType);
builderCopy.setFilter(filterCopy);
List<String> otherEntityIdColumns = getEntityIdColumnsFromInteraction(otherEntityType, incoming);
List<org.hypertrace.core.query.service.api.Expression> otherIdExpressions = otherEntityIdColumns.stream().map(QueryRequestUtil::createAttributeExpression).collect(Collectors.toList());
builderCopy.addAllGroupBy(otherIdExpressions);
// Add all selections in the correct order. First id, then other entity id and finally
// the remaining selections.
builderCopy.addAllSelection(idExpressions);
builderCopy.addAllSelection(otherIdExpressions);
selections.forEach(builderCopy::addSelection);
int limit = interactionsRequest.getLimit();
if (limit > 0) {
builderCopy.setLimit(limit);
} else {
builderCopy.setLimit(QueryServiceClient.DEFAULT_QUERY_SERVICE_GROUP_BY_LIMIT);
}
queryRequests.put(e, builderCopy.build());
}
return queryRequests;
}
use of org.hypertrace.core.query.service.api.Filter in project gateway-service by hypertrace.
the class QueryServiceEntityFetcher method constructQueryServiceFilter.
/**
* Converts the filter in the given request to the query service filter and adds a non null filter
* on entity id.
*/
private Filter.Builder constructQueryServiceFilter(EntitiesRequest entitiesRequest, EntitiesRequestContext context, List<String> entityIdAttributeIds) {
// adds the Id != "null" filter to remove null entities.
Filter.Builder filterBuilder = Filter.newBuilder().setOperator(Operator.AND).addAllChildFilter(entityIdAttributeIds.stream().map(entityIdAttribute -> createFilter(entityIdAttribute, Operator.NEQ, createStringNullLiteralExpression())).collect(Collectors.toList()));
Filter timeSpaceAndProvidedFilter = QueryAndGatewayDtoConverter.addTimeAndSpaceFiltersAndConvertToQueryFilter(entitiesRequest.getStartTimeMillis(), entitiesRequest.getEndTimeMillis(), entitiesRequest.getSpaceId(), context.getTimestampAttributeId(), AttributeMetadataUtil.getSpaceAttributeId(attributeMetadataProvider, context, entitiesRequest.getEntityType()), entitiesRequest.getFilter());
if (timeSpaceAndProvidedFilter.equals(Filter.getDefaultInstance())) {
return filterBuilder;
}
if (timeSpaceAndProvidedFilter.getOperator().equals(Operator.AND)) {
return filterBuilder.addAllChildFilter(timeSpaceAndProvidedFilter.getChildFilterList());
}
return filterBuilder.addChildFilter(timeSpaceAndProvidedFilter);
}
use of org.hypertrace.core.query.service.api.Filter in project gateway-service by hypertrace.
the class QueryAndGatewayDtoConverter method addTimeAndSpaceFiltersAndConvertToQueryFilter.
public static Filter addTimeAndSpaceFiltersAndConvertToQueryFilter(long startTimeMillis, long endTimeMillis, String spaceId, String timestampAttributeId, String spacesAttributeId, org.hypertrace.gateway.service.v1.common.Filter providedFilter) {
Filter.Builder compositeFilter = Filter.newBuilder().setOperator(Operator.AND);
Filter convertedProvidedFilter = isNonDefaultFilter(providedFilter) ? convertToQueryFilter(providedFilter) : Filter.getDefaultInstance();
if (!hasTimeRangeFilter(convertedProvidedFilter, timestampAttributeId)) {
compositeFilter.addChildFilter(QueryRequestUtil.createBetweenTimesFilter(timestampAttributeId, startTimeMillis, endTimeMillis));
}
if (isNonDefaultFilter(convertedProvidedFilter)) {
compositeFilter.addChildFilter(convertedProvidedFilter);
}
if (!Strings.isNullOrEmpty(spaceId)) {
compositeFilter.addChildFilter(QueryRequestUtil.createStringFilter(spacesAttributeId, Operator.EQ, spaceId));
}
// If only one filter was added, unwrap the one child filter and use that
return compositeFilter.getChildFilterCount() == 1 ? compositeFilter.getChildFilter(0) : compositeFilter.build();
}
use of org.hypertrace.core.query.service.api.Filter in project gateway-service by hypertrace.
the class EntityServiceTest method testGetEntitiesOnlySelectFromSingleSourceWithTimeRangeShouldUseQueryService.
@Test
public void testGetEntitiesOnlySelectFromSingleSourceWithTimeRangeShouldUseQueryService() {
long endTime = System.currentTimeMillis();
long startTime = endTime - 1000;
EntitiesRequest entitiesRequest = EntitiesRequest.newBuilder().setEntityType("API").setStartTimeMillis(startTime).setEndTimeMillis(endTime).addSelection(buildAttributeExpression("API.apiId", "API Id")).addSelection(buildAttributeExpression("API.apiName", "API Name")).setLimit(2).build();
// The filter sent down to query-service by QueryServiceEntityFetcher when there is no filter in
// EntitiesRequest
Filter queryServiceFilter = createQsDefaultRequestFilter("API.startTime", "API.apiId", startTime, endTime);
QueryRequest expectedQueryRequest = QueryRequest.newBuilder().addSelection(createAttributeExpression(// Added implicitly in the getEntitiesAndAggregatedMetrics() in
"API.apiId")).addSelection(createAttributeExpression("API.apiName", "API Name")).addSelection(createQsAggregationExpression("COUNT", "API.apiId")).setFilter(queryServiceFilter).addGroupBy(createAttributeExpression("API.apiId")).addGroupBy(createAttributeExpression("API.apiName", "API Name")).setLimit(QueryServiceClient.DEFAULT_QUERY_SERVICE_GROUP_BY_LIMIT).build();
when(queryServiceClient.executeQuery(eq(expectedQueryRequest), any(), Mockito.anyInt())).thenReturn(List.of(getResultSetChunk(List.of("API.apiId", "API.apiName"), new String[][] { { "apiId1", "/login" }, { "apiId2", "/checkout" } })).iterator());
// get total request.
expectedQueryRequest = QueryRequest.newBuilder().addSelection(createAttributeExpression(// Added implicitly in the getEntitiesAndAggregatedMetrics() in
"API.apiId")).addSelection(createQsAggregationExpression("COUNT", "API.apiId")).setFilter(queryServiceFilter).addGroupBy(createAttributeExpression("API.apiId")).setLimit(QueryServiceClient.DEFAULT_QUERY_SERVICE_GROUP_BY_LIMIT).build();
when(queryServiceClient.executeQuery(eq(expectedQueryRequest), any(), Mockito.anyInt())).thenReturn(List.of(getResultSetChunk(List.of("API.apiId"), new String[][] { { "apiId1" }, { "apiId2" } })).iterator());
ScopeFilterConfigs scopeFilterConfigs = new ScopeFilterConfigs(ConfigFactory.empty());
EntityService entityService = new EntityService(queryServiceClient, 500, entityQueryServiceClient, attributeMetadataProvider, entityIdColumnsConfigs, scopeFilterConfigs, logConfig);
EntitiesResponse response = entityService.getEntities(TENANT_ID, entitiesRequest, Map.of());
Assertions.assertNotNull(response);
Assertions.assertEquals(2, response.getTotal());
Entity entity1 = response.getEntity(0);
Assertions.assertEquals("apiId1", entity1.getAttributeMap().get("API.apiId").getString());
Assertions.assertEquals("/login", entity1.getAttributeMap().get("API.apiName").getString());
Entity entity2 = response.getEntity(1);
Assertions.assertEquals("apiId2", entity2.getAttributeMap().get("API.apiId").getString());
Assertions.assertEquals("/checkout", entity2.getAttributeMap().get("API.apiName").getString());
}
use of org.hypertrace.core.query.service.api.Filter in project gateway-service by hypertrace.
the class QueryAndGatewayDtoConverterTest method onlyAddsTimeRangeFilterOnlyIfMissing.
@Test
void onlyAddsTimeRangeFilterOnlyIfMissing() {
Filter result = addTimeAndSpaceFiltersAndConvertToQueryFilter(10, 20, "", TIMESTAMP_ATTR_ID, SPACES_ATTR_ID, org.hypertrace.gateway.service.v1.common.Filter.getDefaultInstance());
Filter expectedFilter = createBetweenTimesFilter(TIMESTAMP_ATTR_ID, 10, 20);
assertEquals(expectedFilter, result);
result = addTimeAndSpaceFiltersAndConvertToQueryFilter(10, 20, "", TIMESTAMP_ATTR_ID, SPACES_ATTR_ID, buildGatewayTimerangeFilter(10, 20));
assertEquals(expectedFilter, result);
}
Aggregations