@Override public Headers getHeaders() { return Headers.emptyHeaders(); }
@Override public Headers getHeaders() { Map<String, String> headers = new HashMap<>(); response.headers.forEach((h) -> headers.put(h.key, h.value)); return Headers.fromMap(headers); }
public FnHttpEventBuilder withHeader(String key, String value) { Objects.requireNonNull(key, "key"); Objects.requireNonNull(value, "value"); headers = headers.addHeader(key, value); return this; }
/** * Build a headers object from a map composed of (name, value) entries, we take a copy of the map and * disallow any further modification * * @param headers underlying collection of header entries to copy * @return {@code Headers} built from headers map */ public static Headers fromMultiHeaderMap(Map<String, List<String>> headers) { Map<String, List<String>> hm = new HashMap<>(); headers.forEach((k, vs) -> hm.put(canonicalKey(k), new ArrayList<>(vs))); return new Headers(Collections.unmodifiableMap(new HashMap<>(Objects.requireNonNull(headers)))); }
/** * Create an output event from a byte array * * @param bytes the byte array to write to the output * @param status the status code of this event * @param contentType the content type to present on HTTP responses or null * @param headers any additional headers to supply with HTTP responses * @return a new output event */ static OutputEvent fromBytes(final byte[] bytes, final Status status, final String contentType, final Headers headers) { Objects.requireNonNull(bytes, "bytes"); Objects.requireNonNull(status, "status"); Objects.requireNonNull(headers, "headers"); final Headers newHeaders = contentType== null?Headers.emptyHeaders():headers.setHeader("Content-Type",contentType); return new OutputEvent() { @Override public Status getStatus() { return status; } @Override public Headers getHeaders() { return newHeaders; } @Override public void writeToOutput(OutputStream out) throws IOException { out.write(bytes); } }; }
Headers headersIn = Headers.emptyHeaders(); if (stripInputHeaders.contains(Headers.canonicalKey(h.getName()))) { continue; headersIn = headersIn.addHeader(h.getName(), h.getValue());
public FunctionHTTPGatewayContext(InvocationContext invocationContext) { this.invocationContext = Objects.requireNonNull(invocationContext, "invocationContext"); Map<String, List<String>> myHeaders = new HashMap<>(); String requestUri = ""; String method = ""; for (Map.Entry<String, List<String>> e : invocationContext.getRequestHeaders().asMap().entrySet()) { String key = e.getKey(); if (key.startsWith("Fn-Http-H-")) { String httpKey = key.substring("Fn-Http-H-".length()); if (httpKey.length() > 0) { myHeaders.put(httpKey, e.getValue()); } } if (key.equals("Fn-Http-Request-Url")) { requestUri = e.getValue().get(0); } if (key.equals("Fn-Http-Method")) { method = e.getValue().get(0); } } this.queryParameters = QueryParametersParser.getParams(requestUri); this.requestUrl = requestUri; this.method = method; this.httpRequestHeaders = Headers.emptyHeaders().setHeaders(myHeaders); }
@Override public CompletionId invokeFunction(FlowId flowId, String functionId, byte[] data, HttpMethod method, Headers headers, CodeLocation codeLocation) { APIModel.HTTPReq httpReq = new APIModel.HTTPReq(); if (headers != null) { if (data.length > 0) { BlobResponse blobResponse = blobStoreClient.writeBlob(flowId.getId(), data, headers.get(CONTENT_TYPE_HEADER).orElse(CONTENT_TYPE_OCTET_STREAM)); httpReq.body = APIModel.Blob.fromBlobResponse(blobResponse); } httpReq.headers = new ArrayList<>(); headers.asMap().forEach((k, vs) -> vs.forEach(v -> httpReq.headers.add(APIModel.HTTPHeader.create(k, v)))); Map<String, List<String>> headersMap = headers.asMap(); headersMap.forEach((key, values) -> values.forEach(value -> httpReq.headers.add(APIModel.HTTPHeader.create(key, value)))); } httpReq.method = APIModel.HTTPMethod.fromFlow(method); APIModel.AddInvokeFunctionStageRequest addInvokeFunctionStageRequest = new APIModel.AddInvokeFunctionStageRequest(); addInvokeFunctionStageRequest.arg = httpReq; addInvokeFunctionStageRequest.codeLocation = codeLocation.getLocation(); addInvokeFunctionStageRequest.callerId = FlowRuntimeGlobals.getCurrentCompletionId().map(CompletionId::getId).orElse(null); addInvokeFunctionStageRequest.functionId = functionId; try { return executeAddInvokeFunctionStageRequest(flowId, addInvokeFunctionStageRequest); } catch (IOException e) { throw new PlatformCommunicationException("Failed to create invokeFunction stage", e); } }
/** * Invoke a void JSON function on a given flow by mapping the input to JSON, returns a future that completes with the HttpResponse of the function * if the function returns a successful http response, and completes with an error if the function invocation fails. * * @param flow the flow to invoke the subsequent call onto * @param functionId the function ID to invoke * @param method the HTTP method to use * @param headers additional headers to pass - the content * @param input the input object * @param <U> the input type * @return a future that returns the object value of JSON function or throws an error if that function fails. */ public static <U> FlowFuture<HttpResponse> invokeFunction(Flow flow, String functionId, HttpMethod method, Headers headers, U input) { try { String inputString = getObjectMapper().writeValueAsString(input); Headers newHeaders; if (!headers.get("Content-type").isPresent()) { newHeaders = headers.addHeader("Content-type", "application/json"); } else { newHeaders = headers; } return flow.invokeFunction(functionId, method, newHeaders, inputString.getBytes()); } catch (JsonProcessingException e) { throw new IllegalArgumentException("Failed to coerce function input to JSON", e); } }
/** * The content type of the response. * <p> * * @return The name of the content type. */ default Optional<String> getContentType(){ return getHeaders().get(CONTENT_TYPE_HEADER); }
private void writeEvent(OutputEvent evt, HttpResponse response) { evt.getHeaders().asMap() .entrySet() .stream() .filter(e -> !stripOutputHeaders.contains(e.getKey())) .flatMap(e -> e.getValue().stream().map((v) -> new BasicHeader(e.getKey(), v))) .forEachOrdered(response::addHeader); ContentType contentType = evt.getContentType().map(c -> { try { return ContentType.parse(c); } catch (ParseException e) { return ContentType.DEFAULT_BINARY; } }).orElse(ContentType.DEFAULT_BINARY); response.setHeader("Content-Type", contentType.toString()); response.setStatusLine(new BasicStatusLine(HttpVersion.HTTP_1_1, evt.getStatus().getCode(), evt.getStatus().name())); ByteArrayOutputStream bos = new ByteArrayOutputStream(); // TODO remove output buffering here - possibly change OutputEvent contract to support providing an InputStream? try { evt.writeToOutput(bos); } catch (IOException e) { throw new FunctionOutputHandlingException("Error writing output", e); } byte[] data = bos.toByteArray(); response.setEntity(new ByteArrayEntity(data, contentType)); }
/** * GetAllValues returns all values for a header or an empty list if the header has no values * @param key the Header key * @return a possibly empty list of values */ public List<String> getAllValues(String key) { return headers.getOrDefault(canonicalKey(key), Collections.emptyList()); }
public FnHttpEventBuilder withHeaders(Map<String, String> headers) { Headers h = this.headers; for (Map.Entry<String, String> he : headers.entrySet()) { h = h.setHeader(he.getKey(), he.getValue()); } this.headers = h; return this; }
List<APIModel.HTTPHeader> callHeaders = new ArrayList<>(); for (Map.Entry<String, List<String>> e : res.getHeaders().asMap().entrySet()) { for (String v : e.getValue()) { callHeaders.add(APIModel.HTTPHeader.create(e.getKey(), v)); BlobResponse blobResponse = writeBlob(flowId.getId(), res.getBodyAsBytes(), res.getHeaders().get("Content-type").orElse("application/octet-stream"));
/** * Build a headers object from a map composed of (name, value) entries, we take a copy of the map and * disallow any further modification * * @param headers underlying collection of header entries to copy * @return {@code Headers} built from headers map */ public static Headers fromMap(Map<String, String> headers) { Objects.requireNonNull(headers, "headersIn"); Map<String, List<String>> h = new HashMap<>(); headers.forEach((k, v) -> h.put(canonicalKey(k), Collections.singletonList(v))); return new Headers(Collections.unmodifiableMap(new HashMap<>(h))); }
Optional<String> graphIdOption = evt.getHeaders().get(FLOW_ID_HEADER);
evt.getHeaders().asMap().forEach((k, vs) -> vs.forEach(v -> response.addHeader(k, v)));
@Override public void setResponseHeader(String key, String value, String... vs) { Objects.requireNonNull(key, "key"); Objects.requireNonNull(vs, "vs"); Arrays.stream(vs).forEach(v->Objects.requireNonNull(v,"null value in list ")); String cKey = Headers.canonicalKey(key); if (value == null) { additionalResponseHeaders.remove(cKey); return; } additionalResponseHeaders.put(cKey, Collections.singletonList(value)); }
/** * Create an output event from a byte array * * @param bytes the byte array to write to the output * @param status the status code to report * @param contentType the content type to present on HTTP responses * @return a new output event */ static OutputEvent fromBytes(byte[] bytes, Status status, String contentType) { return fromBytes(bytes, status, contentType, Headers.emptyHeaders()); }
@Override public Headers getHeaders() { Map<String, String> headers = new HashMap<>(); req.headers.forEach((h) -> headers.put(h.key, h.value)); return Headers.fromMap(headers); }