Skip to content

Commit

Permalink
Extract reusable REST related functionality (#7838)
Browse files Browse the repository at this point in the history
This change allows to reuse the parameter converters and exception mappers.
  • Loading branch information
snazy committed Dec 14, 2023
1 parent 374f4a9 commit 9cd78c2
Show file tree
Hide file tree
Showing 35 changed files with 308 additions and 115 deletions.
2 changes: 2 additions & 0 deletions bom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ dependencies {
api(project(":nessie-quarkus-cli"))
api(project(":nessie-quarkus"))
api(project(":nessie-quarkus-tests"))
api(project(":nessie-rest-common"))
api(project(":nessie-rest-services"))
api(project(":nessie-services"))
api(project(":nessie-services-config"))
api(project(":nessie-server-store"))
api(project(":nessie-server-store-proto"))
api(project(":nessie-content-generator"))
Expand Down
1 change: 1 addition & 0 deletions compatibility/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies {
api(project(":nessie-compatibility-jersey"))
api(project(":nessie-multi-env-test-engine"))
implementation(project(":nessie-services"))
implementation(project(":nessie-services-config"))
implementation(project(":nessie-versioned-storage-common"))
implementation(project(":nessie-versioned-storage-store"))
compileOnly(project(":nessie-versioned-storage-mongodb"))
Expand Down
1 change: 1 addition & 0 deletions compatibility/jersey/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation(project(":nessie-model"))
implementation(project(":nessie-rest-services"))
implementation(project(":nessie-services"))
implementation(project(":nessie-services-config"))
implementation(project(":nessie-server-store"))
implementation(project(":nessie-versioned-storage-common"))
implementation(project(":nessie-versioned-storage-store"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ protected Application configure() {
"org.projectnessie.services.restjavax.NessieExceptionMapper",
config::register,
true);
withEEClass(
"org.projectnessie.services.restjakarta.AccessCheckExceptionMapper",
c -> config.register(c, 10),
false);
withEEClass(
"org.projectnessie.services.restjakarta.BackendLimitExceededExceptionMapper",
c -> config.register(c, 10),
false);
withEEClass(
"org.projectnessie.services.rest.exceptions.NotSupportedExceptionMapper",
c -> config.register(c, 10),
false);
withEEClass(
"org.projectnessie.services.restjavax.NessieJaxRsJsonParseExceptionMapper",
c -> config.register(c, 10),
Expand Down Expand Up @@ -169,9 +181,10 @@ private static void withEEClass(
String eeClassName, Consumer<Class<?>> whenClassExists, boolean mandatory) {
Iterator<String> classNames =
List.of(
eeClassName,
eeClassName.replace("restjavax.", "restjakarta."),
eeClassName.replace("restjavax.", "rest."))
eeClassName.replace("restjavax.", "rest.converters."),
eeClassName.replace("restjavax.", "rest.exceptions."),
eeClassName.replace("restjavax.", "rest."),
eeClassName)
.iterator();
while (classNames.hasNext()) {
String className = classNames.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import jakarta.enterprise.inject.spi.AfterBeanDiscovery;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.Extension;
import org.projectnessie.services.config.ExceptionConfig;
import org.projectnessie.services.config.ServerConfig;

public class ServerConfigExtension implements Extension {
Expand All @@ -44,5 +45,10 @@ public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm)
.addQualifier(Default.Literal.INSTANCE)
.scope(ApplicationScoped.class)
.produceWith(i -> SERVER_CONFIG);
abd.addBean()
.addType(ExceptionConfig.class)
.addQualifier(Default.Literal.INSTANCE)
.scope(ApplicationScoped.class)
.produceWith(i -> SERVER_CONFIG);
}
}
2 changes: 2 additions & 0 deletions gradle/projects.main.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ nessie-quarkus-cli=servers/quarkus-cli
nessie-quarkus-common=servers/quarkus-common
nessie-quarkus=servers/quarkus-server
nessie-quarkus-tests=servers/quarkus-tests
nessie-rest-common=servers/rest-common
nessie-rest-services=servers/rest-services
nessie-s3minio=testing/s3minio
nessie-s3mock=testing/s3mock
nessie-multi-env-test-engine=testing/multi-env-test-engine
nessie-services=servers/services
nessie-services-config=servers/services-config
nessie-services-bench=servers/services-bench
nessie-server-store=servers/store
nessie-server-store-proto=servers/store-proto
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,24 @@
import org.projectnessie.services.config.ServerConfigExtension;
import org.projectnessie.services.impl.ConfigApiImpl;
import org.projectnessie.services.impl.TreeApiImpl;
import org.projectnessie.services.rest.AccessCheckExceptionMapper;
import org.projectnessie.services.rest.BackendLimitExceededExceptionMapper;
import org.projectnessie.services.rest.RestConfigResource;
import org.projectnessie.services.rest.RestContentResource;
import org.projectnessie.services.rest.RestDiffResource;
import org.projectnessie.services.rest.RestNamespaceResource;
import org.projectnessie.services.rest.RestTreeResource;
import org.projectnessie.services.rest.RestV2ConfigResource;
import org.projectnessie.services.rest.RestV2TreeResource;
import org.projectnessie.services.restjakarta.ConstraintViolationExceptionMapper;
import org.projectnessie.services.restjakarta.ContentKeyParamConverterProvider;
import org.projectnessie.services.restjakarta.NamespaceParamConverterProvider;
import org.projectnessie.services.restjakarta.NessieExceptionMapper;
import org.projectnessie.services.restjakarta.NessieJaxRsJsonMappingExceptionMapper;
import org.projectnessie.services.restjakarta.NessieJaxRsJsonParseExceptionMapper;
import org.projectnessie.services.restjakarta.ReferenceTypeParamConverterProvider;
import org.projectnessie.services.restjakarta.ValidationExceptionMapper;
import org.projectnessie.services.rest.converters.ContentKeyParamConverterProvider;
import org.projectnessie.services.rest.converters.NamespaceParamConverterProvider;
import org.projectnessie.services.rest.converters.ReferenceTypeParamConverterProvider;
import org.projectnessie.services.rest.exceptions.ConstraintViolationExceptionMapper;
import org.projectnessie.services.rest.exceptions.NessieExceptionMapper;
import org.projectnessie.services.rest.exceptions.NessieJaxRsJsonMappingExceptionMapper;
import org.projectnessie.services.rest.exceptions.NessieJaxRsJsonParseExceptionMapper;
import org.projectnessie.services.rest.exceptions.NotSupportedExceptionMapper;
import org.projectnessie.services.rest.exceptions.ValidationExceptionMapper;
import org.projectnessie.versioned.VersionStoreImplExtension;
import org.projectnessie.versioned.storage.common.logic.RepositoryLogic;
import org.projectnessie.versioned.storage.common.persist.Persist;
Expand Down Expand Up @@ -234,7 +237,10 @@ protected Application configure() {
config.register(NamespaceParamConverterProvider.class);
config.register(ReferenceTypeParamConverterProvider.class);
config.register(ValidationExceptionMapper.class, 10);
config.register(AccessCheckExceptionMapper.class, 10);
config.register(ConstraintViolationExceptionMapper.class, 10);
config.register(BackendLimitExceededExceptionMapper.class, 10);
config.register(NotSupportedExceptionMapper.class, 10);
config.register(NessieExceptionMapper.class);
config.register(NessieJaxRsJsonParseExceptionMapper.class, 10);
config.register(NessieJaxRsJsonMappingExceptionMapper.class, 10);
Expand Down
2 changes: 2 additions & 0 deletions servers/jax-rs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ description = "Nessie on Glassfish/Jersey/Weld"
dependencies {
api(project(":nessie-client"))
api(project(":nessie-model"))
api(project(":nessie-rest-common"))
api(project(":nessie-rest-services"))
api(project(":nessie-services"))
api(project(":nessie-services-config"))
api(project(":nessie-server-store"))
api(project(":nessie-versioned-spi"))
api(project(":nessie-versioned-storage-common"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,10 @@ public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm)
.addQualifier(Default.Literal.INSTANCE)
.scope(ApplicationScoped.class)
.produceWith(i -> SERVER_CONFIG);
abd.addBean()
.addType(ExceptionConfig.class)
.addQualifier(Default.Literal.INSTANCE)
.scope(ApplicationScoped.class)
.produceWith(i -> SERVER_CONFIG);
}
}
1 change: 1 addition & 0 deletions servers/quarkus-cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ extra["maven.name"] = "Nessie - Quarkus CLI"
dependencies {
implementation(project(":nessie-quarkus-common"))
implementation(project(":nessie-services"))
implementation(project(":nessie-services-config"))
implementation(project(":nessie-server-store"))
implementation(project(":nessie-versioned-spi"))
implementation(project(":nessie-versioned-transfer"))
Expand Down
2 changes: 2 additions & 0 deletions servers/quarkus-common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ extra["maven.name"] = "Nessie - Quarkus Common"

dependencies {
implementation(project(":nessie-model"))
implementation(project(":nessie-rest-common"))
implementation(project(":nessie-server-store"))
implementation(project(":nessie-services"))
implementation(project(":nessie-services-config"))
implementation(project(":nessie-versioned-spi"))

implementation(project(":nessie-versioned-storage-bigtable"))
Expand Down
1 change: 1 addition & 0 deletions servers/quarkus-server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ dependencies {
implementation(project(":nessie-quarkus-auth"))
implementation(project(":nessie-quarkus-common"))
implementation(project(":nessie-events-quarkus"))
implementation(project(":nessie-rest-common"))
implementation(project(":nessie-rest-services"))
implementation(project(":nessie-versioned-spi"))
implementation(libs.nessie.ui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@
*/
package org.projectnessie.server.rest;

import jakarta.inject.Inject;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import org.jboss.resteasy.api.validation.ResteasyViolationException;
import org.jboss.resteasy.api.validation.Validation;
import org.projectnessie.error.ErrorCode;
import org.projectnessie.services.config.ServerConfig;
import org.projectnessie.services.restjakarta.BaseExceptionMapper;
import org.projectnessie.services.restjakarta.NessieExceptionMapper;
import org.projectnessie.services.rest.exceptions.BaseExceptionMapper;
import org.projectnessie.services.rest.exceptions.NessieExceptionMapper;

/**
* "Special" implementation for exceptions that extend {@link ValidationException}, as those do not
Expand All @@ -39,14 +37,7 @@ public class ResteasyExceptionMapper extends BaseExceptionMapper<ResteasyViolati

// Unused constructor
// Required because of https://issues.jboss.org/browse/RESTEASY-1538
public ResteasyExceptionMapper() {
this(null);
}

@Inject
public ResteasyExceptionMapper(ServerConfig config) {
super(config);
}
public ResteasyExceptionMapper() {}

@Override
public Response toResponse(ResteasyViolationException exception) {
Expand Down
50 changes: 50 additions & 0 deletions servers/rest-common/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2022 Dremio
*
* 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.
*/

plugins {
id("nessie-conventions-server")
id("nessie-jacoco")
}

extra["maven.name"] = "Nessie - REST Common"

dependencies {
implementation(project(":nessie-services-config"))
implementation(project(":nessie-model"))

implementation(libs.slf4j.api)
implementation(libs.guava)

compileOnly(libs.jakarta.enterprise.cdi.api)
compileOnly(libs.jakarta.annotation.api)
compileOnly(libs.jakarta.validation.api)
compileOnly(libs.jakarta.ws.rs.api)
compileOnly(libs.jakarta.servlet.api)

compileOnly(libs.microprofile.openapi)

implementation(platform(libs.jackson.bom))
implementation("com.fasterxml.jackson.core:jackson-databind")
compileOnly("com.fasterxml.jackson.core:jackson-annotations")

testImplementation(libs.jakarta.validation.api)
testImplementation(libs.jakarta.ws.rs.api)

testCompileOnly(libs.microprofile.openapi)

testImplementation(platform(libs.junit.bom))
testImplementation(libs.bundles.junit.testing)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.rest;
package org.projectnessie.services.rest.common;

import com.google.common.base.Throwables;
import java.util.function.Function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.restjakarta;
package org.projectnessie.services.rest.converters;

import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.ParamConverterProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.restjakarta;
package org.projectnessie.services.rest.converters;

import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.ParamConverterProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.restjakarta;
package org.projectnessie.services.rest.converters;

import jakarta.ws.rs.ext.ParamConverter;
import jakarta.ws.rs.ext.ParamConverterProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.restjakarta;
package org.projectnessie.services.rest.exceptions;

import jakarta.inject.Inject;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
Expand All @@ -24,27 +25,22 @@
import java.util.function.Consumer;
import org.projectnessie.error.ErrorCode;
import org.projectnessie.error.NessieError;
import org.projectnessie.services.config.ServerConfig;
import org.projectnessie.services.rest.RestCommon;
import org.projectnessie.services.config.ExceptionConfig;
import org.projectnessie.services.rest.common.RestCommon;

/** Code shared between concrete exception-mapper implementations. */
public abstract class BaseExceptionMapper<T extends Throwable> implements ExceptionMapper<T> {

private final ServerConfig serverConfig;
@Inject private ExceptionConfig config;

@Context private HttpHeaders headers;

protected BaseExceptionMapper(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
}

protected Response buildBadRequestResponse(Exception e) {
return buildExceptionResponse(ErrorCode.BAD_REQUEST, e.getMessage(), e);
}

protected Response buildExceptionResponse(ErrorCode errorCode, String message, Exception e) {
return buildExceptionResponse(
errorCode, message, e, serverConfig.sendStacktraceToClient(), h -> {});
return buildExceptionResponse(errorCode, message, e, config.sendStacktraceToClient(), h -> {});
}

protected Response buildExceptionResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.projectnessie.services.restjakarta;
package org.projectnessie.services.rest.exceptions;

import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.ElementKind;
import jakarta.validation.Path;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider;
import org.projectnessie.error.ErrorCode;
import org.projectnessie.services.config.ServerConfig;

/**
* "Special" implementation for exceptions that extend {@link ConstraintViolationException}, as
* those do not "go through" {@link NessieExceptionMapper} and also not through the {@link
* ValidationExceptionMapper}.
*/
@Provider
@ApplicationScoped
public class ConstraintViolationExceptionMapper
extends BaseExceptionMapper<ConstraintViolationException> {

// Unused constructor
// Required because of https://issues.jboss.org/browse/RESTEASY-1538
public ConstraintViolationExceptionMapper() {
this(null);
}

@Inject
public ConstraintViolationExceptionMapper(ServerConfig config) {
super(config);
}
public ConstraintViolationExceptionMapper() {}

@Override
public Response toResponse(ConstraintViolationException exception) {
Expand Down

0 comments on commit 9cd78c2

Please sign in to comment.