public static RequestGroup fromRequest(final Request<?> request, int maxBatchSize) { switch (request.getMethod()) { case GET: return new GetRequestGroup(request, maxBatchSize); case BATCH_GET: return new GetRequestGroup(request, maxBatchSize); default: throw new IllegalArgumentException("Can't create RequestGroup for request method: " + request.getMethod() + ", batching for this method must be disabled"); } }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; RestRequestBatchKey other = (RestRequestBatchKey) obj; if (_request == null) { if (other._request != null) return false; } else if (!_request.equals(other._request)) return false; if (_requestContext == null) { if (other._requestContext != null) return false; } else if (!_requestContext.equals(other._requestContext)) return false; return true; }
@SuppressWarnings("deprecation") public GetRequestGroup(Request<?> request, int maxBatchSize) { _baseUriTemplate = request.getBaseUriTemplate(); _headers = request.getHeaders(); _queryParams = getQueryParamsForBatchingKey(request); _resourceSpec = request.getResourceSpec(); _requestOptions = request.getRequestOptions(); _pathKeys = request.getPathKeys(); _maxBatchSize = maxBatchSize; }
/** * Generates a task name for the request. * @param request * @return a task name */ static String generateTaskName(final Request<?> request) { return request.getBaseUriTemplate() + " " + OperationNameGenerator.generate(request.getMethod(), request.getMethodName()); }
private static Optional<String> getOpOutName(Request<?> request) { if (request.getMethod() == ResourceMethod.ACTION) { return Optional.of((String)request.getQueryParamsObjects().get(RestConstants.ACTION_PARAM)); } else if (request.getMethod() == ResourceMethod.FINDER) { return Optional.of((String)request.getQueryParamsObjects().get(RestConstants.QUERY_TYPE_PARAM)); } else { return Optional.empty(); } }
@Override public void onSuccess(ProtocolVersion protocolVersion) { URI requestUri = RestliUriBuilderUtil.createUriBuilder(request, _uriPrefix, protocolVersion).build(); final ResourceMethod method = request.getMethod(); final String methodName = request.getMethodName(); addDisruptContext(request.getBaseUriTemplate(), method, methodName, requestContext); sendStreamRequestImpl(requestContext, requestUri, method, input != null ? RequestBodyTransformer.transform(request, protocolVersion) : null, request.getHeaders(), CookieUtil.encodeCookies(request.getCookies()), methodName, protocolVersion, request.getRequestOptions(), request.getStreamingAttachments(), callback); } });
RequestConfigCacheKey(Optional<InboundRequestContext> inbound, Request<?> outbound) { StringJoiner sj = new StringJoiner(":"); for (String pathComponent: URIParamUtils.extractPathComponentsFromUriTemplate(outbound.getBaseUriTemplate())) { sj.add(pathComponent); } _outboundName = sj.toString(); _inboundName = inbound.map(r -> r.getName()); _outboundOp = outbound.getMethod(); _outboundOpName = getOpOutName(outbound); _inboundOp = inbound.map(r -> r.getMethod()); _inboundOpName = _inboundOp.flatMap(method -> getOpInName(inbound, method)); }
_baseUriTemplate = request.getBaseUriTemplate(); _pathKeys = request.getPathKeys(); final Map<String, Object> rawQueryParams = request.getQueryParamsObjects(); if (rawQueryParams == null) _queryParamClasses = request.getQueryParamClasses();
switch (request.getMethod()) resourceProperties = request.getResourceProperties(); convertToBatchRequest((CollectionRequest<KeyValueRecord>) request.getInputRecord(), resourceProperties.getKeyType(), resourceProperties.getComplexKeyType(), version).data(); case BATCH_PARTIAL_UPDATE: resourceProperties = request.getResourceProperties(); convertToBatchRequest((CollectionRequest<KeyValueRecord>) request.getInputRecord(), resourceProperties.getKeyType(), resourceProperties.getComplexKeyType(), version).data(); default: return request.getInputRecord().data();
private static IndividualRequest toIndividualRequest(Request<?> request, IndividualRequestMap dependantRequests) throws RestLiEncodingException { //TODO: Hardcoding RESTLI_PROTOCOL_2_0_0 for now. We need to refactor this code later to get protocol version using the mechanism similar to // RestClient.getProtocolVersionForService() ProtocolVersion protocolVersion = AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion(); String relativeUrl = getRelativeUrl(request, protocolVersion); IndividualRequest individualRequest = new IndividualRequest(); individualRequest.setRelativeUrl(relativeUrl); individualRequest.setMethod(request.getMethod().getHttpMethod().name()); individualRequest.setHeaders(new StringMap(request.getHeaders())); List<HttpCookie> cookies = request.getCookies(); if (cookies != null && !cookies.isEmpty()) { throw new IllegalArgumentException(String.format("Cookies for individual request '%s' MUST be added at the envelope request level", relativeUrl)); } individualRequest.setBody(getBody(request, protocolVersion), SetMode.IGNORE_NULL); individualRequest.setDependentRequests(dependantRequests); return individualRequest; }
/** * {@inheritDoc} */ @Override public <T> boolean needScatterGather(Request<T> request) { if (!BATCHING_STRATEGY_METHODS.contains(request.getMethod())) { return false; } final String serviceName = request.getServiceName(); try { return _uriMapper.needScatterGather(serviceName); } catch (ServiceUnavailableException e) { log.error("Unable to determine scatter-gather capability for service :" + serviceName + " and treat as unsupported!", e); return false; } }
requestBuilder.setMethod(request.getMethod().getHttpMethod().name()); if (request.getMethod().getHttpMethod() == HttpMethod.POST) requestBuilder.setHeader(RestConstants.HEADER_RESTLI_REQUEST_METHOD, request.getMethod().toString()); if (request.getInputRecord() != null)
/** * Validates that all path keys in the URI template are present. If not, an {@link IllegalStateException} is thrown. */ private void validatePathKeys() { UriTemplate template = new UriTemplate(getBaseUriTemplate()); for (String key: template.getTemplateVariables()) { Object value = getPathKeys().get(key); if (value == null) { throw new IllegalStateException("Missing path key: " + key); } } }
if (request.getStreamingAttachments() != null) if (request.getRequestOptions() != null && request.getRequestOptions().getAcceptResponseAttachments()) RecordTemplate input = request.getInputRecord(); getProtocolVersionForService(request, new Callback<ProtocolVersion>()
private static Tuple3<Set<Object>, Set<PathSpec>, Boolean> reduceFields(Tuple3<Set<Object>, Set<PathSpec>, Boolean> state, Request<?> request) { if (request instanceof GetRequest || request instanceof BatchRequest) { final Set<PathSpec> requestFields = request.getFields(); if (requestFields != null && !requestFields.isEmpty()) { if (state._2() != null) { state._2().addAll(requestFields); } return state; } else { return Tuples.tuple(state._1(), null, state._3()); } } else { throw unsupportedGetRequestType(request); } }
private <T> void sendRequestNoScatterGather(final Request<T> request, final RequestContext requestContext, final Callback<Response<T>> callback) { //Here we need to decide if we want to use StreamRequest/StreamResponse or RestRequest/RestResponse. //Eventually we will move completely to StreamRequest/StreamResponse for all traffic. //However for the time being we will only use StreamRequest/StreamResponse for traffic that contains attachments. // //Therefore the decision is made as follows: //1. If the content-type OR accept-type is multipart/related then we use StreamRequest/StreamResponse, //otherwise we use RestRequest/RestResponse. //2. The content-type will be decided based on the presence of attachments in the request. //3. The accept-type will be based on the RestLiRequestOptions. //Note that it is not possible for the list of streaming attachments to be non-null and have 0 elements. If the //list of streaming attachments is non null then it must have at least one attachment. The request builders enforce //this invariant. if (_restLiClientConfig.isUseStreaming() || request.getStreamingAttachments() != null || request.getRequestOptions().getAcceptResponseAttachments()) { //Set content type and accept type correctly and use StreamRequest/StreamResponse sendStreamRequest(request, requestContext, new RestLiStreamCallbackAdapter<T>(request.getResponseDecoder(), callback)); } else { sendRestRequest(request, requestContext, new RestLiCallbackAdapter<T>(request.getResponseDecoder(), callback)); } }
private void getProtocolVersionForService(final Request<?> request, Callback<ProtocolVersion> callback) { try { _client.getMetadata(new URI(_uriPrefix + request.getServiceName()), Callbacks.handle(metadata -> callback.onSuccess(getProtocolVersion(AllProtocolVersions.BASELINE_PROTOCOL_VERSION, AllProtocolVersions.PREVIOUS_PROTOCOL_VERSION, AllProtocolVersions.LATEST_PROTOCOL_VERSION, AllProtocolVersions.NEXT_PROTOCOL_VERSION, getAnnouncedVersion(metadata), request.getRequestOptions().getProtocolVersionOption(), _forceUseNextVersionOverride)), callback)); } catch (URISyntaxException e) { throw new RuntimeException("Failed to create a valid URI to fetch properties for!"); } }
protected void appendQueryParams(UriBuilder b) { DataMap params = QueryParamsUtil.convertToDataMap(_request.getQueryParamsObjects(), _request.getQueryParamClasses(), _version); if (_version.compareTo(AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion()) >= 0) { URIParamUtils.addSortedParams(b, params); } else { QueryParamsDataMap.addSortedParams(b, params); } }
Callback<StreamResponse> callback) RecordTemplate input = request.getInputRecord(); getProtocolVersionForService(request, new Callback<ProtocolVersion>()
/** * Extract the get response for this resource out of an auto-batched batch response. * This is pure rest.li logic, and it complements the auto-batching logic in BatchGetRequestBuilder. * @throws com.linkedin.r2.RemoteInvocationException if the server returned an error response for this resource, * or if it returned neither a result nor an error. */ public static <K, V extends RecordTemplate> Response<V> unbatchKVResponse(Request<BatchKVResponse<K, V>> request, Response<BatchKVResponse<K, V>> batchResponse, K id) throws RemoteInvocationException { final BatchKVResponse<K, V> batchEntity = batchResponse.getEntity(); final ErrorResponse errorResponse = batchEntity.getErrors().get(id); if (errorResponse != null) { throw new RestLiResponseException(errorResponse); } final V entityResult = batchEntity.getResults().get(id); if (entityResult == null) { throw new RestLiDecodingException("No result or error for base URI " + request.getBaseUriTemplate() + ", id " + id + ". Verify that the batchGet endpoint returns response keys that match batchGet request IDs.", null); } return new ResponseImpl<V>(batchResponse, entityResult); }