This is an automated email from the ASF dual-hosted git repository. deepak pushed a commit to branch release24.09 in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git
commit 6d228007c034e9222f5823c1370b7da369e291ca Author: ArashPreet <66062618+arashpreet0...@users.noreply.github.com> AuthorDate: Thu Aug 21 16:14:29 2025 +0530 OFBIZ-12345: Fixed repeated REST API exception issue returning 500 error (#139) Co-authored-by: ArashPreet Singh <ar...@insonix.com> Co-authored-by: Deepak Dixit <dee...@apache.org> --- .../ofbiz/ws/rs/ServiceNameContextHolder.java | 53 ++++++++++++++++++++++ .../apache/ofbiz/ws/rs/ServiceRequestFilter.java | 2 +- .../apache/ofbiz/ws/rs/core/OFBizApiConfig.java | 2 + .../ws/rs/filters/ServiceContextCleanupFilter.java | 18 ++++++++ .../rs/spi/impl/GenericServiceExceptionMapper.java | 3 +- 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceNameContextHolder.java b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceNameContextHolder.java new file mode 100644 index 000000000..305badc2b --- /dev/null +++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceNameContextHolder.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.ofbiz.ws.rs; + +public final class ServiceNameContextHolder { + + private static final ThreadLocal<String> SERVICE_NAME = new ThreadLocal<>(); + + private ServiceNameContextHolder() { + // Prevent instantiation + } + + /** + * Sets the current service name for this thread. + * + * @param serviceName the name of the service being executed + */ + public static void set(String serviceName) { + SERVICE_NAME.set(serviceName); + } + + /** + * Returns the current service name for this thread, or null if none is set. + * + * @return the service name + */ + public static String get() { + return SERVICE_NAME.get(); + } + + /** + * Clears the stored service name from the current thread context. + */ + public static void clear() { + SERVICE_NAME.remove(); + } +} \ No newline at end of file diff --git a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java index 444b8a005..858790dbd 100644 --- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java +++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java @@ -104,7 +104,7 @@ public class ServiceRequestFilter implements ContainerRequestFilter { } // If everything looks good, set the 'requestForService' property in the // context. Indicates which service this request is for. - requestContext.setProperty("requestForService", service); + ServiceNameContextHolder.set(service); } } diff --git a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java index d85d87f65..579e11de9 100644 --- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java +++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java @@ -46,6 +46,7 @@ import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.model.Resource; import org.glassfish.jersey.server.model.ResourceMethod; +import org.apache.ofbiz.ws.rs.filters.ServiceContextCleanupFilter; public class OFBizApiConfig extends ResourceConfig { private static final String MODULE = OFBizApiConfig.class.getName(); @@ -60,6 +61,7 @@ public class OFBizApiConfig extends ResourceConfig { register(JacksonFeature.class); register(ServiceRequestFilter.class); register(MultiPartFeature.class); + register(ServiceContextCleanupFilter.class); if (Debug.verboseOn()) { register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 10000)); diff --git a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/filters/ServiceContextCleanupFilter.java b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/filters/ServiceContextCleanupFilter.java new file mode 100644 index 000000000..b467ad3fe --- /dev/null +++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/filters/ServiceContextCleanupFilter.java @@ -0,0 +1,18 @@ +package org.apache.ofbiz.ws.rs.filters; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.ext.Provider; +import java.io.IOException; + +import org.apache.ofbiz.ws.rs.ServiceNameContextHolder; + +@Provider +public class ServiceContextCleanupFilter implements ContainerResponseFilter { + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + ServiceNameContextHolder.clear(); // ✅ runs after ExceptionMapper + } +} diff --git a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java index b59d6702b..9b9fefb9e 100644 --- a/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java +++ b/rest-api/src/main/java/org/apache/ofbiz/ws/rs/spi/impl/GenericServiceExceptionMapper.java @@ -37,6 +37,7 @@ import org.apache.ofbiz.ws.rs.response.Error; import org.apache.ofbiz.ws.rs.spi.AbstractExceptionMapper; import org.apache.ofbiz.ws.rs.util.ErrorUtil; import org.codehaus.groovy.runtime.InvokerInvocationException; +import org.apache.ofbiz.ws.rs.ServiceNameContextHolder; /** * @@ -72,7 +73,7 @@ public class GenericServiceExceptionMapper extends AbstractExceptionMapper imple } else if (actualCause instanceof InvokerInvocationException) { actualCause = actualCause.getCause(); } - String service = (String) crc.getProperty("requestForService"); + String service = ServiceNameContextHolder.get(); if (actualCause instanceof ServiceValidationException) { ServiceValidationException validationException = (ServiceValidationException) actualCause; Error error = new Error().type(actualCause.getClass().getSimpleName())