Search in sources :

Example 1 with ResponseExceptionMapper

use of org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper in project jersey by eclipse-ee4j.

the class MethodModel method evaluateResponse.

/**
 * Evaluation of {@link Response} if it is applicable for any of the registered {@link ResponseExceptionMapper} providers.
 *
 * @param response obtained response
 * @param method   called method
 */
private void evaluateResponse(Response response, Method method) {
    ResponseExceptionMapper lowestMapper = null;
    Throwable throwable = null;
    for (ResponseExceptionMapper responseExceptionMapper : interfaceModel.context().responseExceptionMappers()) {
        if (responseExceptionMapper.handles(response.getStatus(), response.getHeaders())) {
            if (lowestMapper == null || throwable == null || lowestMapper.getPriority() > responseExceptionMapper.getPriority()) {
                lowestMapper = responseExceptionMapper;
                Throwable tmp = lowestMapper.toThrowable(response);
                if (tmp != null) {
                    throwable = tmp;
                }
            }
        }
    }
    if (throwable != null) {
        if (throwable instanceof RuntimeException) {
            throw (RuntimeException) throwable;
        } else if (throwable instanceof Error) {
            throw (Error) throwable;
        }
        for (Class<?> exception : method.getExceptionTypes()) {
            if (throwable.getClass().isAssignableFrom(exception)) {
                throw new WebApplicationException(throwable);
            }
        }
    }
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) ResponseExceptionMapper(org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper)

Example 2 with ResponseExceptionMapper

use of org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper in project quarkus by quarkusio.

the class QuarkusRestClientBuilder method register.

@Override
public RestClientBuilder register(Object o, int i) {
    if (o instanceof ResponseExceptionMapper) {
        // local
        ResponseExceptionMapper mapper = (ResponseExceptionMapper) o;
        HashMap<Class<?>, Integer> contracts = new HashMap<>();
        contracts.put(ResponseExceptionMapper.class, i);
        registerLocalProviderInstance(mapper, contracts);
        // delegate
        builderDelegate.register(mapper, i);
    } else if (o instanceof ParamConverterProvider) {
        // local
        ParamConverterProvider converter = (ParamConverterProvider) o;
        HashMap<Class<?>, Integer> contracts = new HashMap<>();
        contracts.put(ParamConverterProvider.class, i);
        registerLocalProviderInstance(converter, contracts);
        // delegate
        builderDelegate.register(converter, i);
    } else if (o instanceof AsyncInvocationInterceptorFactory) {
        invocationInterceptorFactories.add((AsyncInvocationInterceptorFactory) o);
    } else {
        builderDelegate.register(o, i);
    }
    return this;
}
Also used : HashMap(java.util.HashMap) ResponseExceptionMapper(org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper) DefaultResponseExceptionMapper(org.jboss.resteasy.microprofile.client.DefaultResponseExceptionMapper) ParamConverterProvider(jakarta.ws.rs.ext.ParamConverterProvider) AsyncInvocationInterceptorFactory(org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptorFactory)

Example 3 with ResponseExceptionMapper

use of org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper in project quarkus by quarkusio.

the class ClientExceptionMapperHandler method generateResponseExceptionMapper.

/**
 * Generates an implementation of {@link ResponseExceptionMapper} that looks something like:
 *
 * <pre>
 * {@code
 *  public class SomeService_map_ResponseExceptionMapper_a8fb70beeef2a54b80151484d109618eed381626 implements ResponseExceptionMapper {
 *      public Throwable toThrowable(Response var1) {
 *          // simply call the static method of interface
 *          return SomeService.map(var1);
 *      }
 *
 * }
 * </pre>
 */
Result generateResponseExceptionMapper(AnnotationInstance instance) {
    if (!DotNames.CLIENT_EXCEPTION_MAPPER.equals(instance.name())) {
        throw new IllegalArgumentException("'clientExceptionMapperInstance' must be an instance of " + DotNames.CLIENT_EXCEPTION_MAPPER);
    }
    MethodInfo targetMethod = null;
    boolean isValid = false;
    if (instance.target().kind() == AnnotationTarget.Kind.METHOD) {
        if ((instance.target().asMethod().flags() & Modifier.STATIC) != 0) {
            targetMethod = instance.target().asMethod();
            String returnTypeClassName = targetMethod.returnType().name().toString();
            try {
                boolean returnsRuntimeException = RuntimeException.class.isAssignableFrom(Class.forName(returnTypeClassName, false, Thread.currentThread().getContextClassLoader()));
                if (returnsRuntimeException) {
                    isValid = true;
                }
            } catch (ClassNotFoundException ignored) {
            }
        }
    }
    if (!isValid) {
        String message = DotNames.CLIENT_EXCEPTION_MAPPER + " is only supported on static methods of REST Client interfaces that take 'javax.ws.rs.core.Response' as a single parameter and return 'java.lang.RuntimeException'.";
        if (targetMethod != null) {
            message += " Offending instance is '" + targetMethod.declaringClass().name().toString() + "#" + targetMethod.name() + "'";
        }
        throw new IllegalStateException(message);
    }
    StringBuilder sigBuilder = new StringBuilder();
    sigBuilder.append(targetMethod.name()).append("_").append(targetMethod.returnType().name().toString());
    for (Type i : targetMethod.parameters()) {
        sigBuilder.append(i.name().toString());
    }
    int priority = Priorities.USER;
    AnnotationValue priorityAnnotationValue = instance.value("priority");
    if (priorityAnnotationValue != null) {
        priority = priorityAnnotationValue.asInt();
    }
    ClassInfo restClientInterfaceClassInfo = targetMethod.declaringClass();
    String generatedClassName = restClientInterfaceClassInfo.name().toString() + "_" + targetMethod.name() + "_" + "ResponseExceptionMapper" + "_" + HashUtil.sha1(sigBuilder.toString());
    try (ClassCreator cc = ClassCreator.builder().classOutput(classOutput).className(generatedClassName).interfaces(ResponseExceptionMapper.class).build()) {
        MethodCreator toThrowable = cc.getMethodCreator("toThrowable", Throwable.class, Response.class);
        ResultHandle resultHandle = toThrowable.invokeStaticInterfaceMethod(MethodDescriptor.ofMethod(restClientInterfaceClassInfo.name().toString(), targetMethod.name(), targetMethod.returnType().name().toString(), targetMethod.parameters().get(0).name().toString()), toThrowable.getMethodParam(0));
        toThrowable.returnValue(resultHandle);
        if (priority != Priorities.USER) {
            MethodCreator getPriority = cc.getMethodCreator("getPriority", int.class);
            getPriority.returnValue(getPriority.load(priority));
        }
    }
    return new Result(restClientInterfaceClassInfo.name().toString(), generatedClassName, priority);
}
Also used : ClassCreator(io.quarkus.gizmo.ClassCreator) Type(org.jboss.jandex.Type) MethodCreator(io.quarkus.gizmo.MethodCreator) ResponseExceptionMapper(org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper) AnnotationValue(org.jboss.jandex.AnnotationValue) MethodInfo(org.jboss.jandex.MethodInfo) ResultHandle(io.quarkus.gizmo.ResultHandle) ClassInfo(org.jboss.jandex.ClassInfo)

Example 4 with ResponseExceptionMapper

use of org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper in project cxf by apache.

the class MicroProfileClientProxyImpl method checkResponse.

@Override
protected void checkResponse(Method m, Response r, Message inMessage) throws Throwable {
    MicroProfileClientProviderFactory factory = MicroProfileClientProviderFactory.getInstance(inMessage);
    List<ResponseExceptionMapper<?>> mappers = factory.createResponseExceptionMapper(inMessage, Throwable.class);
    for (ResponseExceptionMapper<?> mapper : mappers) {
        if (mapper.handles(r.getStatus(), r.getHeaders())) {
            Throwable t = mapper.toThrowable(r);
            if (t == null) {
                continue;
            }
            if (t instanceof RuntimeException) {
                throw t;
            } else if (CompletionStage.class.isAssignableFrom(m.getReturnType())) {
                throw new CompletionException(t);
            } else if (m.getExceptionTypes() != null) {
                // its a checked exception, make sure its declared
                for (Class<?> c : m.getExceptionTypes()) {
                    if (c.isAssignableFrom(t.getClass())) {
                        throw t;
                    }
                }
                if (LOG.isLoggable(Level.FINEST)) {
                    LOG.log(Level.FINEST, "ResponseExceptionMapper, " + mapper.getClass().getName() + ", handles " + "response, but client method does not declare it's Throwable type, " + t.getClass().getName());
                }
            }
        }
    }
}
Also used : ResponseExceptionMapper(org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper) CompletionException(java.util.concurrent.CompletionException) MicroProfileClientProviderFactory(org.apache.cxf.microprofile.client.MicroProfileClientProviderFactory) CompletionStage(java.util.concurrent.CompletionStage)

Example 5 with ResponseExceptionMapper

use of org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper in project wildfly-swarm by wildfly-swarm.

the class ExceptionMapping method filter.

@Override
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
    Response response = new PartialResponse(responseContext);
    Map<ResponseExceptionMapper, Integer> mappers = new HashMap<>();
    for (Object o : instances) {
        if (o instanceof ResponseExceptionMapper) {
            ResponseExceptionMapper candiate = (ResponseExceptionMapper) o;
            if (candiate.handles(response.getStatus(), response.getHeaders())) {
                mappers.put(candiate, candiate.getPriority());
            }
        }
    }
    if (mappers.size() > 0) {
        Map<Optional<Throwable>, Integer> errors = new HashMap<>();
        mappers.forEach((m, i) -> {
            Optional<Throwable> t = Optional.ofNullable(m.toThrowable(response));
            errors.put(t, i);
        });
        Optional<Throwable> prioritised = Optional.empty();
        for (Optional<Throwable> throwable : errors.keySet()) {
            if (throwable.isPresent()) {
                if (!prioritised.isPresent()) {
                    prioritised = throwable;
                } else if (errors.get(throwable) < errors.get(prioritised)) {
                    prioritised = throwable;
                }
            }
        }
        if (prioritised.isPresent()) {
            // strange rule from the spec
            throw (WebApplicationException) prioritised.get();
        }
    }
}
Also used : Response(javax.ws.rs.core.Response) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) ResponseExceptionMapper(org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper)

Aggregations

ResponseExceptionMapper (org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper)13 HashMap (java.util.HashMap)5 DefaultResponseExceptionMapper (org.jboss.resteasy.microprofile.client.DefaultResponseExceptionMapper)3 ParamConverterProvider (jakarta.ws.rs.ext.ParamConverterProvider)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 ParamConverterProvider (javax.ws.rs.ext.ParamConverterProvider)2 AsyncInvocationInterceptorFactory (org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptorFactory)2 ClassCreator (io.quarkus.gizmo.ClassCreator)1 MethodCreator (io.quarkus.gizmo.MethodCreator)1 ResultHandle (io.quarkus.gizmo.ResultHandle)1 Optional (java.util.Optional)1 CompletionException (java.util.concurrent.CompletionException)1 CompletionStage (java.util.concurrent.CompletionStage)1 Response (javax.ws.rs.core.Response)1 MicroProfileClientProviderFactory (org.apache.cxf.microprofile.client.MicroProfileClientProviderFactory)1 AnnotationValue (org.jboss.jandex.AnnotationValue)1 ClassInfo (org.jboss.jandex.ClassInfo)1 MethodInfo (org.jboss.jandex.MethodInfo)1 Type (org.jboss.jandex.Type)1 ClientRequestContextImpl (org.jboss.resteasy.reactive.client.impl.ClientRequestContextImpl)1