private Response createResponse(DiscoveryRequest request, Map<String, ? extends Message> resources, String version) { Collection<? extends Message> filtered = request.getResourceNamesList().isEmpty() ? resources.values() : request.getResourceNamesList().stream() .map(resources::get) .filter(Objects::nonNull) .collect(Collectors.toList()); return Response.create(request, filtered, version); }
private void send(Response response, String typeUrl) { String nonce = Long.toString(streamNonce.getAndIncrement()); DiscoveryResponse discoveryResponse = DiscoveryResponse.newBuilder() .setVersionInfo(response.version()) .addAllResources(response.resources().stream().map(Any::pack).collect(Collectors.toList())) .setTypeUrl(typeUrl) .setNonce(nonce) .build(); LOGGER.info("[{}] response {} with nonce {} version {}", streamId, typeUrl, nonce, response.version()); callbacks.forEach(cb -> cb.onStreamResponse(streamId, response.request(), discoveryResponse)); // Store the latest response *before* we send the response. This ensures that by the time the request // is processed the map is guaranteed to be updated. Doing it afterwards leads to a race conditions // which may see the incoming request arrive before the map is updated, failing the nonce check erroneously. latestResponse.put(typeUrl, discoveryResponse); try { responseObserver.onNext(discoveryResponse); } catch (StatusRuntimeException e) { if (!Status.CANCELLED.getCode().equals(e.getStatus().getCode())) { throw e; } } } }