diff --git a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/catalog/rest/VendedCredentialsRestCatalogServlet.java b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/catalog/rest/VendedCredentialsRestCatalogServlet.java index 62df40b3239b..7bd4f4b8d416 100644 --- a/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/catalog/rest/VendedCredentialsRestCatalogServlet.java +++ b/plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/catalog/rest/VendedCredentialsRestCatalogServlet.java @@ -17,7 +17,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.apache.hc.core5.http.ContentType; import org.apache.iceberg.rest.RESTCatalogAdapter; -import org.apache.iceberg.rest.RestCatalogServlet; +import org.apache.iceberg.rest.RESTCatalogServlet; import org.apache.iceberg.rest.credentials.ImmutableCredential; import org.apache.iceberg.rest.responses.ImmutableLoadCredentialsResponse; import org.apache.iceberg.rest.responses.LoadCredentialsResponse; @@ -28,10 +28,10 @@ import java.util.concurrent.atomic.AtomicInteger; /** - * Extends {@link RestCatalogServlet} to handle the {@code GET .../credentials} custom endpoint. + * Extends {@link RESTCatalogServlet} to handle the {@code GET .../credentials} custom endpoint. */ public abstract class VendedCredentialsRestCatalogServlet - extends RestCatalogServlet + extends RESTCatalogServlet { private final AtomicInteger vendedCredentialsRefreshCount = new AtomicInteger(); diff --git a/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/DelegatingRestSessionCatalog.java b/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/DelegatingRestSessionCatalog.java index c8e61120fb3d..16a2037943bf 100644 --- a/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/DelegatingRestSessionCatalog.java +++ b/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/DelegatingRestSessionCatalog.java @@ -65,7 +65,7 @@ public TestingHttpServer testServer() .setHttpAcceptQueueSize(10) .setHttpEnabled(true); HttpServerInfo httpServerInfo = new HttpServerInfo(config, nodeInfo); - RestCatalogServlet servlet = new RestCatalogServlet(adapter); + RESTCatalogServlet servlet = new RESTCatalogServlet(adapter); return new TestingHttpServer("rest-catalog", httpServerInfo, nodeInfo, config, servlet, ServerFeature.builder() // Required due to URIs like: HEAD /v1/namespaces/level_1%1Flevel_2 diff --git a/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/RestCatalogServlet.java b/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/RestCatalogServlet.java deleted file mode 100644 index 9bf26278eff6..000000000000 --- a/plugin/trino-iceberg/src/test/java/org/apache/iceberg/rest/RestCatalogServlet.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.iceberg.rest; - -import io.airlift.log.Logger; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.apache.hc.core5.http.ContentType; -import org.apache.hc.core5.http.HttpHeaders; -import org.apache.iceberg.exceptions.RESTException; -import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; -import org.apache.iceberg.relocated.com.google.common.io.CharStreams; -import org.apache.iceberg.rest.HTTPRequest.HTTPMethod; -import org.apache.iceberg.rest.RESTCatalogAdapter.Route; -import org.apache.iceberg.rest.responses.ErrorResponse; -import org.apache.iceberg.util.Pair; - -import java.io.IOException; -import java.io.Reader; -import java.io.UncheckedIOException; -import java.util.Collections; -import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static java.lang.String.format; - -/** - * The RESTCatalogServlet provides a servlet implementation used in combination with a - * RESTCatalogAdaptor to proxy the REST Spec to any Catalog implementation. - */ -// forked from org.apache.iceberg.rest.RESTCatalogServlet -public class RestCatalogServlet - extends HttpServlet -{ - private static final Logger LOG = Logger.get(RestCatalogServlet.class); - - private final RESTCatalogAdapter restCatalogAdapter; - private final Map responseHeaders = ImmutableMap.of( - HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType()); - - public RestCatalogServlet(RESTCatalogAdapter restCatalogAdapter) - { - this.restCatalogAdapter = restCatalogAdapter; - } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws IOException - { - execute(ServletRequestContext.from(request), response); - } - - @Override - protected void doHead(HttpServletRequest request, HttpServletResponse response) - throws IOException - { - execute(ServletRequestContext.from(request), response); - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException - { - execute(ServletRequestContext.from(request), response); - } - - @Override - protected void doDelete(HttpServletRequest request, HttpServletResponse response) - throws IOException - { - execute(ServletRequestContext.from(request), response); - } - - protected void execute(ServletRequestContext context, HttpServletResponse response) - throws IOException - { - response.setStatus(HttpServletResponse.SC_OK); - responseHeaders.forEach(response::setHeader); - - if (context.error().isPresent()) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - RESTObjectMapper.mapper().writeValue(response.getWriter(), context.error().get()); - return; - } - - HTTPRequest request = restCatalogAdapter.buildRequest( - context.method(), - context.path(), - context.queryParams(), - context.headers(), - context.body()); - - try { - Object responseBody = restCatalogAdapter.execute( - request, - context.route().responseClass(), - handle(response), - _ -> {}); - - if (responseBody != null) { - RESTObjectMapper.mapper().writeValue(response.getWriter(), responseBody); - } - } - catch (RESTException e) { - LOG.error(e, "Error processing REST request"); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - catch (Exception e) { - LOG.error(e, "Unexpected exception when processing REST request"); - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - - protected Consumer handle(HttpServletResponse response) - { - return errorResponse -> { - response.setStatus(errorResponse.code()); - try { - RESTObjectMapper.mapper().writeValue(response.getWriter(), errorResponse); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - }; - } - - public static class ServletRequestContext - { - private HTTPMethod method; - private Route route; - private String path; - private Map headers; - private Map queryParams; - private Object body; - - private ErrorResponse errorResponse; - - private ServletRequestContext(ErrorResponse errorResponse) - { - this.errorResponse = errorResponse; - } - - private ServletRequestContext(HTTPMethod method, Route route, String path, Map headers, Map queryParams, Object body) - { - this.method = method; - this.route = route; - this.path = path; - this.headers = headers; - this.queryParams = queryParams; - this.body = body; - } - - static ServletRequestContext from(HttpServletRequest request) - throws IOException - { - HTTPMethod method = HTTPMethod.valueOf(request.getMethod()); - String path = request.getRequestURI().substring(1); - Pair> routeContext = Route.from(method, path); - - if (routeContext == null) { - return new ServletRequestContext(ErrorResponse.builder() - .responseCode(400) - .withType("BadRequestException") - .withMessage(format("No route for request: %s %s", method, path)) - .build()); - } - - Route route = routeContext.first(); - Object requestBody = null; - if (route.requestClass() != null) { - requestBody = RESTObjectMapper.mapper().readValue(request.getReader(), route.requestClass()); - } - else if (route == Route.TOKENS) { - try (Reader reader = request.getReader()) { - requestBody = RESTUtil.decodeFormData(CharStreams.toString(reader)); - } - } - - Map queryParams = request.getParameterMap().entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue()[0])); - Map headers = Collections.list(request.getHeaderNames()).stream() - .collect(Collectors.toMap(Function.identity(), request::getHeader)); - - return new ServletRequestContext(method, route, path, headers, queryParams, requestBody); - } - - public HTTPMethod method() - { - return method; - } - - public Route route() - { - return route; - } - - public String path() - { - return path; - } - - public Map headers() - { - return headers; - } - - public Map queryParams() - { - return queryParams; - } - - public Object body() - { - return body; - } - - public Optional error() - { - return Optional.ofNullable(errorResponse); - } - } -}