private static String createHtmlEntry(MessageHeaders<?, ?, ?> spec) { String requestEntry = createMessageHtmlEntry( spec.getRequestClass(), EmptyRequestBody.class); String responseEntry = createMessageHtmlEntry( spec.getResponseClass(), EmptyResponseBody.class); String pathParameterList = createPathParameterHtmlList(spec.getUnresolvedMessageParameters().getPathParameters()); String queryParameterList = createQueryParameterHtmlList(spec.getUnresolvedMessageParameters().getQueryParameters()); sb.append(" <tbody>\n"); sb.append(" <tr>\n"); sb.append(" <td class=\"text-left\" colspan=\"2\"><h5><strong>" + spec.getTargetRestEndpointURL() + "</strong></h5></td>\n"); sb.append(" </tr>\n"); sb.append(" <tr>\n"); sb.append(" <td class=\"text-left\" style=\"width: 20%\">Verb: <code>" + spec.getHttpMethod() + "</code></td>\n"); sb.append(" <td class=\"text-left\">Response code: <code>" + spec.getResponseStatusCode() + "</code></td>\n"); sb.append(" </tr>\n"); sb.append(" <tr>\n"); sb.append(" <td colspan=\"2\">" + escapeCharacters(spec.getDescription()) + "</td>\n"); sb.append(" </tr>\n"); sb.append(" </tr>\n"); int reqHash = spec.getTargetRestEndpointURL().hashCode() + spec.getHttpMethod().name().hashCode() + spec.getRequestClass().getCanonicalName().hashCode(); int resHash = spec.getTargetRestEndpointURL().hashCode() + spec.getHttpMethod().name().hashCode() + spec.getResponseClass().getCanonicalName().hashCode();
private static void createHtmlFile(DocumentingRestEndpoint restEndpoint, RestAPIVersion apiVersion, Path outputFile) throws IOException { StringBuilder html = new StringBuilder(); List<MessageHeaders> specs = restEndpoint.getSpecs().stream() .filter(spec -> spec.getSupportedAPIVersions().contains(apiVersion)) .collect(Collectors.toList()); specs.forEach(spec -> html.append(createHtmlEntry(spec))); Files.deleteIfExists(outputFile); Files.write(outputFile, html.toString().getBytes(StandardCharsets.UTF_8)); }
Preconditions.checkState(messageParameters.isResolved(), "Message parameters were not resolved."); if (!messageHeaders.getSupportedAPIVersions().contains(apiVersion)) { throw new IllegalArgumentException(String.format( "The requested version %s is not supported by the request (method=%s URL=%s). Supported versions are: %s.", apiVersion, messageHeaders.getHttpMethod(), messageHeaders.getTargetRestEndpointURL(), messageHeaders.getSupportedAPIVersions().stream().map(RestAPIVersion::getURLVersionPrefix).collect(Collectors.joining(",")))); String versionedHandlerURL = "/" + apiVersion.getURLVersionPrefix() + messageHeaders.getTargetRestEndpointURL(); String targetUrl = MessageParameters.resolveUrl(versionedHandlerURL, messageParameters); ByteBuf payload = Unpooled.wrappedBuffer(sw.toString().getBytes(ConfigConstants.DEFAULT_CHARSET)); Request httpRequest = createRequest(targetAddress + ':' + targetPort, targetUrl, messageHeaders.getHttpMethod().getNettyHttpMethod(), payload, fileUploads); final Collection<Class<?>> typeParameters = messageHeaders.getResponseTypeParameters(); responseType = objectMapper.constructType(messageHeaders.getResponseClass()); } else { responseType = objectMapper.getTypeFactory().constructParametricType( messageHeaders.getResponseClass(), typeParameters.toArray(new Class<?>[typeParameters.size()]));
default List<MessageHeaders> getSpecs() { Comparator<String> comparator = new RestServerEndpoint.RestHandlerUrlComparator.CaseInsensitiveOrderComparator(); return initializeHandlers(CompletableFuture.completedFuture(null)).stream() .map(tuple -> tuple.f0) .filter(spec -> spec instanceof MessageHeaders) .map(spec -> (MessageHeaders) spec) .sorted((spec1, spec2) -> comparator.compare(spec1.getTargetRestEndpointURL(), spec2.getTargetRestEndpointURL())) .collect(Collectors.toList()); } }
@Override protected CompletableFuture<Void> respondToRequest(ChannelHandlerContext ctx, HttpRequest httpRequest, HandlerRequest<R, M> handlerRequest, T gateway) { CompletableFuture<P> response; try { response = handleRequest(handlerRequest, gateway); } catch (RestHandlerException e) { response = FutureUtils.completedExceptionally(e); } return response.thenAccept(resp -> HandlerUtils.sendResponse(ctx, httpRequest, resp, messageHeaders.getResponseStatusCode(), responseHeaders)); }
@Override JarPlanMessageParameters getUnresolvedJarMessageParameters() { return handler.getMessageHeaders().getUnresolvedMessageParameters(); }
Preconditions.checkState(messageParameters.isResolved(), "Message parameters were not resolved."); if (!messageHeaders.getSupportedAPIVersions().contains(apiVersion)) { throw new IllegalArgumentException(String.format( "The requested version %s is not supported by the request (method=%s URL=%s). Supported versions are: %s.", apiVersion, messageHeaders.getHttpMethod(), messageHeaders.getTargetRestEndpointURL(), messageHeaders.getSupportedAPIVersions().stream().map(RestAPIVersion::getURLVersionPrefix).collect(Collectors.joining(",")))); String versionedHandlerURL = "/" + apiVersion.getURLVersionPrefix() + messageHeaders.getTargetRestEndpointURL(); String targetUrl = MessageParameters.resolveUrl(versionedHandlerURL, messageParameters); ByteBuf payload = Unpooled.wrappedBuffer(sw.toString().getBytes(ConfigConstants.DEFAULT_CHARSET)); Request httpRequest = createRequest(targetAddress + ':' + targetPort, targetUrl, messageHeaders.getHttpMethod().getNettyHttpMethod(), payload, fileUploads); final Collection<Class<?>> typeParameters = messageHeaders.getResponseTypeParameters(); responseType = objectMapper.constructType(messageHeaders.getResponseClass()); } else { responseType = objectMapper.getTypeFactory().constructParametricType( messageHeaders.getResponseClass(), typeParameters.toArray(new Class<?>[typeParameters.size()]));
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { Collection<? extends AccessExecutionJobVertex> allVertices = graph.getAllVertices().values(); List<ArchivedJson> archive = new ArrayList<>(allVertices.size()); for (AccessExecutionJobVertex task : allVertices) { ResponseBody json = createSubtaskTimesInfo(task); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()) .replace(':' + JobVertexIdPathParameter.KEY, task.getJobVertexId().toString()); archive.add(new ArchivedJson(path, json)); } return archive; }
@Override protected CompletableFuture<Void> respondToRequest(ChannelHandlerContext ctx, HttpRequest httpRequest, HandlerRequest<R, M> handlerRequest, T gateway) { CompletableFuture<P> response; try { response = handleRequest(handlerRequest, gateway); } catch (RestHandlerException e) { response = FutureUtils.completedExceptionally(e); } return response.handle((resp, throwable) -> throwable != null ? errorResponse(throwable) : Tuple2.of(resp, messageHeaders.getResponseStatusCode())) .thenCompose(r -> HandlerUtils.sendResponse(ctx, httpRequest, r.f0, r.f1, responseHeaders)); }
@Override JarRunMessageParameters getUnresolvedJarMessageParameters() { return handler.getMessageHeaders().getUnresolvedMessageParameters(); }
Preconditions.checkState(messageParameters.isResolved(), "Message parameters were not resolved."); String targetUrl = MessageParameters.resolveUrl(messageHeaders.getTargetRestEndpointURL(), messageParameters); ByteBuf payload = Unpooled.wrappedBuffer(sw.toString().getBytes(ConfigConstants.DEFAULT_CHARSET)); Request httpRequest = createRequest(targetAddress + ':' + targetPort, targetUrl, messageHeaders.getHttpMethod().getNettyHttpMethod(), payload, fileUploads); final Collection<Class<?>> typeParameters = messageHeaders.getResponseTypeParameters(); responseType = objectMapper.constructType(messageHeaders.getResponseClass()); } else { responseType = objectMapper.getTypeFactory().constructParametricType( messageHeaders.getResponseClass(), typeParameters.toArray(new Class<?>[typeParameters.size()]));
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { Collection<? extends AccessExecutionJobVertex> allVertices = graph.getAllVertices().values(); List<ArchivedJson> archive = new ArrayList<>(allVertices.size()); for (AccessExecutionJobVertex task : allVertices) { ResponseBody json = createSubtaskTimesInfo(task); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()) .replace(':' + JobVertexIdPathParameter.KEY, task.getJobVertexId().toString()); archive.add(new ArchivedJson(path, json)); } return archive; }
httpRequest, resp, messageHeaders.getResponseStatusCode(), responseHeaders);
public <M extends MessageHeaders<R, P, U>, U extends MessageParameters, R extends RequestBody, P extends ResponseBody> CompletableFuture<P> sendRequest( String targetAddress, int targetPort, M messageHeaders, U messageParameters, R request, Collection<FileUpload> fileUploads) throws IOException { return sendRequest( targetAddress, targetPort, messageHeaders, messageParameters, request, fileUploads, RestAPIVersion.getLatestVersion(messageHeaders.getSupportedAPIVersions())); }
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { Collection<? extends AccessExecutionJobVertex> allVertices = graph.getAllVertices().values(); List<ArchivedJson> archive = new ArrayList<>(allVertices.size()); for (AccessExecutionJobVertex task : allVertices) { ResponseBody json = createSubtaskTimesInfo(task); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()) .replace(':' + JobVertexIdPathParameter.KEY, task.getJobVertexId().toString()); archive.add(new ArchivedJson(path, json)); } return archive; }
public <M extends MessageHeaders<R, P, U>, U extends MessageParameters, R extends RequestBody, P extends ResponseBody> CompletableFuture<P> sendRequest( String targetAddress, int targetPort, M messageHeaders, U messageParameters, R request, Collection<FileUpload> fileUploads) throws IOException { return sendRequest( targetAddress, targetPort, messageHeaders, messageParameters, request, fileUploads, RestAPIVersion.getLatestVersion(messageHeaders.getSupportedAPIVersions())); }
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { ResponseBody json = createJobAccumulatorsInfo(graph, true); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()); return Collections.singleton(new ArchivedJson(path, json)); }
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { ResponseBody json = createJobConfigInfo(graph); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()); return Collections.singleton(new ArchivedJson(path, json)); }
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { ResponseBody json = new MultipleJobsDetails(Collections.singleton(WebMonitorUtils.createDetailsForJob(graph))); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()); return Collections.singletonList(new ArchivedJson(path, json)); } }
@Override public Collection<ArchivedJson> archiveJsonWithPath(AccessExecutionGraph graph) throws IOException { ResponseBody json = createJobPlanInfo(graph); String path = getMessageHeaders().getTargetRestEndpointURL() .replace(':' + JobIDPathParameter.KEY, graph.getJobID().toString()); return Collections.singleton(new ArchivedJson(path, json)); }