/** * Returns all required pagination links. * * @param pages The paginated set of results containing the pages being linked to. * @param uriBuilder The builder for creating the pagination links. * * @return the map of metadata for this response */ public static Map<String, Object> addLinks(Pagination<?> pages, UriBuilder uriBuilder) { Map<String, URI> bodyLinks = new LinkedHashMap<>(); Arrays.stream(PaginationLink.values()).forEachOrdered(link -> addLink(link, pages, uriBuilder, bodyLinks)); Map<String, Object> metaBlock = new LinkedHashMap<>(); if (!bodyLinks.isEmpty()) { metaBlock.put(ResponseContextKeys.PAGINATION_LINKS_CONTEXT_KEY.getName(), bodyLinks); } return metaBlock; }
/** * Adds all the required pagination links to the headers and body of the response. * * @param pages The paginated set of results containing the pages being linked to. * @param uriBuilder The uri builder to build the links * @param responseProcessor The response processor whose links are being built */ public static void addLinks( Pagination<?> pages, UriBuilder uriBuilder, MappingResponseProcessor responseProcessor ) { LinkedHashMap<String, URI> bodyLinks = new LinkedHashMap<>(); Arrays.stream(PaginationLink.values()) .forEachOrdered(link -> addLink(link, pages, uriBuilder, responseProcessor, bodyLinks)); ResponseContext responseContext = responseProcessor.getResponseContext(); responseContext.put(ResponseContextKeys.PAGINATION_LINKS_CONTEXT_KEY.getName(), bodyLinks); responseContext.put(ResponseContextKeys.PAGINATION_CONTEXT_KEY.getName(), pages); }
/** * Return the volatile intervals from the context. * * @param context The RequestContext object containing the volatile intervals if any * * @return the volatile intervals from the request or an empty list */ public static SimplifiedIntervalList getVolatileIntervalsWithDefault(Map<String, Serializable> context) { return new SimplifiedIntervalList( (Collection<Interval>) context.computeIfAbsent( VOLATILE_INTERVALS_CONTEXT_KEY.getName(), (ignored) -> new SimplifiedIntervalList() ) ); } }
/** * Build complete response. * * @param preResponse PreResponse object which contains result set, response context and headers * @param apiRequest ApiRequest object which contains request related information * @param containerRequestContext The container for jersey request processing objects * * @return Completely built response with headers and result set */ public javax.ws.rs.core.Response buildResponse( PreResponse preResponse, ApiRequest apiRequest, ContainerRequestContext containerRequestContext ) { ResponseBuilder rspBuilder = createResponseBuilder( preResponse.getResultSet(), preResponse.getResponseContext(), apiRequest, containerRequestContext ); @SuppressWarnings("unchecked") MultivaluedMap<String, Object> headers = (MultivaluedMap<String, Object>) preResponse .getResponseContext() .get(HEADERS.getName()); //Headers are a multivalued map, and we want to add each element of each value to the builder. headers.entrySet().stream() .forEach(entry -> entry.getValue().forEach(value -> rspBuilder.header(entry.getKey(), value))); return rspBuilder.build(); }
/** * Return the missing intervals from the context. * <p> * <b>WARNING</b>: A serialization issue may result in the context value being a list but not a * Simplified Interval List. See https://github.com/yahoo/fili/issues/657 * * @param context The map containing the missing intervals if any * * @return the missing intervals from the request or an empty list */ public static SimplifiedIntervalList getPartialIntervalsWithDefault(Map<String, Serializable> context) { return new SimplifiedIntervalList( (Collection<Interval>) context.computeIfAbsent( MISSING_INTERVALS_CONTEXT_KEY.getName(), (ignored) -> new SimplifiedIntervalList() ) ); } }
if (throwable instanceof ResponseException) { ResponseException responseException = (ResponseException) throwable; responseContext.put(ResponseContextKeys.STATUS.getName(), responseException.getStatusCode()); responseContext.put(ResponseContextKeys.ERROR_MESSAGE.getName(), responseException.getReason()); } else { responseContext.put( ResponseContextKeys.STATUS.getName(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() ); responseContext.put(ResponseContextKeys.ERROR_MESSAGE.getName(), throwable.getMessage());
ResponseContext responseContext = preResponse.getResponseContext(); if (responseContext.containsKey(ResponseContextKeys.STATUS.getName())) { ResponseException responseException = new ResponseException( (Integer) responseContext.get(ResponseContextKeys.STATUS.getName()), (String) responseContext.get(ResponseContextKeys.ERROR_MESSAGE.getName()), (String) responseContext.get(ResponseContextKeys.ERROR_MESSAGE.getName()),
ResponseFormatType responseFormatType = apiRequest.getFormat(); Map<String, URI> bodyLinks = (Map<String, URI>) responseContext.get( PAGINATION_LINKS_CONTEXT_KEY.getName() ); if (bodyLinks == null) { bodyLinks = Collections.emptyMap(); Pagination pagination = (Pagination) responseContext.get(PAGINATION_CONTEXT_KEY.getName()); REQUESTED_API_DIMENSION_FIELDS.getName()); (LinkedHashSet<String>) responseContext.get(API_METRIC_COLUMN_NAMES.getName()), requestedApiDimensionFields, getPartialIntervalsWithDefault(responseContext),
.map(responseContext -> responseContext.containsKey(ResponseContextKeys.ERROR_MESSAGE.getName())) .map(isError -> isError ? updateField(jobMetadata, STATUS, FAILURE.getName()) :
ResponseContext responseContext = response.getResponseContext(); responseContext.put(MISSING_INTERVALS_CONTEXT_KEY.getName(), missingIntervals);
@Override public boolean handleRequest( RequestContext context, DataApiRequest request, DruidAggregationQuery<?> druidQuery, ResponseProcessor response ) { if (!(response instanceof MappingResponseProcessor)) { throw new IllegalStateException("Volatile data request handler requires a mapping response."); } MappingResponseProcessor mappingResponse = (MappingResponseProcessor) response; // Gather the volatile intervals. A volatile interval in one data source make that interval volatile overall. SimplifiedIntervalList volatileIntervals = volatileIntervalsService.getVolatileIntervals( druidQuery.getGranularity(), druidQuery.getIntervals(), physicalTableDictionary.get( druidQuery .getInnermostQuery() .getDataSource() .getPhysicalTable() .getName() ) ); if (!volatileIntervals.isEmpty()) { ResponseContext responseContext = response.getResponseContext(); responseContext.put(VOLATILE_INTERVALS_CONTEXT_KEY.getName(), volatileIntervals); } return next.handleRequest(context, request, druidQuery, mappingResponse); }