This is an automated email from the ASF dual-hosted git repository.

dixitdeepak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 4fb03d40d1 Reverted the service definition verb attribute introduced 
by OFBIZ-11328 for mapping exported services to specific HTTP methods.
4fb03d40d1 is described below

commit 4fb03d40d1c38ba6eeb5f8bcead50db224203347
Author: Deepak Dixit <[email protected]>
AuthorDate: Tue Jun 16 12:09:15 2026 +0530

    Reverted the service definition verb attribute introduced by OFBIZ-11328 
for mapping exported services to specific HTTP methods.
    
    - Exported services are currently exposed through the service engine and 
have historically been available via POST requests.
    - Introducing HTTP method definitions in service descriptors adds 
REST-specific concerns to service definitions.
    - The framework's REST implementation already provides a dedicated 
mechanism for defining REST endpoints through rest.xml.
    - Service definitions should remain transport-agnostic and not require HTTP 
method metadata.
    - Mixing service contracts and REST endpoint definitions creates 
duplication and can lead to inconsistent API behavior.
    
    - Remove the action attribute from service definitions.
    - Remove HTTP method mapping logic introduced for exported services.
    
    Applications requiring REST-style endpoint definitions should use rest.xml 
and the REST framework rather than annotating service definitions with 
HTTP-specific metadata.
    This keeps service definitions independent of protocol concerns and 
preserves backward compatibility with existing exported service behavior.
---
 .../apache/ofbiz/ws/rs/ServiceRequestFilter.java   | 22 +-------------
 .../ofbiz/ws/rs/ServiceRequestProcessor.java       |  4 ---
 .../ofbiz/ws/rs/openapi/OFBizOpenApiReader.java    | 34 +++++-----------------
 .../ws/rs/resources/OFBizServiceResource.java      |  4 +--
 framework/service/dtd/services.xsd                 | 14 ---------
 .../org/apache/ofbiz/service/ModelService.java     | 21 -------------
 .../apache/ofbiz/service/ModelServiceReader.java   |  1 -
 7 files changed, 11 insertions(+), 89 deletions(-)

diff --git 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java
 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java
index 207bca012c..5318c7dca0 100644
--- 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java
+++ 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestFilter.java
@@ -31,8 +31,6 @@ import org.apache.ofbiz.ws.rs.util.RestApiUtil;
 import jakarta.annotation.Priority;
 import jakarta.servlet.ServletContext;
 import jakarta.servlet.http.HttpServletRequest;
-import jakarta.ws.rs.BadRequestException;
-import jakarta.ws.rs.HttpMethod;
 import jakarta.ws.rs.NotFoundException;
 import jakarta.ws.rs.Priorities;
 import jakarta.ws.rs.container.ContainerRequestContext;
@@ -73,9 +71,6 @@ public class ServiceRequestFilter implements 
ContainerRequestFilter {
      *   <li>The service exists — throws {@link ServiceNotFoundException} if 
not</li>
      *   <li>The service is marked as exportable — throws {@link 
NotFoundException} if not</li>
      *   <li>The service has an HTTP action defined — throws {@link 
NotFoundException} if not</li>
-     *   <li>The HTTP method matches the service action — throws {@link 
MethodNotAllowedException} if not</li>
-     *   <li>GET requests include the {@code inParams} query parameter —
-     *       throws {@link BadRequestException} if absent</li>
      * </ul>
      *
      * <p>On successful validation, the service name is stored in
@@ -86,8 +81,6 @@ public class ServiceRequestFilter implements 
ContainerRequestFilter {
     public void filter(ContainerRequestContext requestContext) throws 
IOException {
         Debug.logInfo("Service request is going to get validated!", MODULE);
         String service = (String) 
RestApiUtil.extractParams(uriInfo.getPathParameters()).get("serviceName");
-        String method = requestContext.getMethod();
-        String action = null;
         if (UtilValidate.isNotEmpty(service)) {
             ModelService mdService = null;
             try {
@@ -100,23 +93,10 @@ public class ServiceRequestFilter implements 
ContainerRequestFilter {
                 throw new ServiceNotFoundException(service);
             }
 
-            if (mdService != null && !mdService.isExport()) {
+            if (!mdService.isExport()) {
                 throw new NotFoundException("Service '" + service + "' is not 
exportable.");
             }
 
-            action = mdService.getAction();
-            if (mdService != null && UtilValidate.isEmpty(action)) {
-                throw new NotFoundException("Service '" + service + "' does 
not have HTTP action defined.");
-            }
-
-            if (!action.equalsIgnoreCase(method)) {
-                throw new MethodNotAllowedException("HTTP " + method + " is 
not allowed on service '" + service + "'");
-            }
-
-            if (action.equalsIgnoreCase(HttpMethod.GET) && 
UtilValidate.isNotEmpty(mdService.getInParamNamesMap())
-                    && 
UtilValidate.isEmpty(httpRequest.getParameter(SVC_IN_PARAMS))) {
-                throw new BadRequestException("Missing Parameter: 'inParams'");
-            }
             // If everything looks good, set the 'requestForService' property 
in the
             // context. Indicates which service this request is for.
             ServiceNameContextHolder.set(service);
diff --git 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
index 9625e8f489..cf18ab0c8c 100644
--- 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
+++ 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/ServiceRequestProcessor.java
@@ -20,7 +20,6 @@ package org.apache.ofbiz.ws.rs;
 
 import java.util.Map;
 
-import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.service.DispatchContext;
 import org.apache.ofbiz.service.GenericServiceException;
@@ -75,9 +74,6 @@ public class ServiceRequestProcessor {
         } catch (GenericServiceException gse) {
             throw new NotFoundException(gse.getMessage());
         }
-        if (UtilValidate.isNotEmpty(service.getAction()) && 
!service.getAction().equalsIgnoreCase(httpVerb)) {
-            throw new MethodNotAllowedException("HTTP " + httpVerb + " is not 
allowed on this service.");
-        }
         Map<String, Object> serviceContext = 
dispatchContext.makeValidContext(serviceName, ModelService.IN_PARAM, 
requestMap);
         serviceContext.put("userLogin", userLogin);
         Map<String, Object> result = dispatcher.runSync(serviceName, 
serviceContext);
diff --git 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
index 2c93d8ea18..3f05f06eac 100644
--- 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
+++ 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
@@ -30,7 +30,6 @@ import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.Response;
 
 import org.apache.ofbiz.base.util.Debug;
-import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.service.DispatchContext;
 import org.apache.ofbiz.service.GenericServiceException;
 import org.apache.ofbiz.service.LocalDispatcher;
@@ -224,40 +223,23 @@ public final class OFBizOpenApiReader extends Reader 
implements OpenApiReader {
             } catch (GenericServiceException e) {
                 e.printStackTrace();
             }
-            if (service != null && service.isExport() && 
UtilValidate.isNotEmpty(service.getAction())) {
-                String action = service.getAction().toUpperCase();
+            if (service != null && service.isExport()) {
                 SecurityRequirement security = new SecurityRequirement();
                 security.addList("jwtToken");
                 final Operation operation = new 
Operation().summary(service.getDescription())
                         
.description(service.getDescription()).addTagsItem("Exported Services")
                         
.operationId(service.getName()).deprecated(false).addSecurityItem(security);
                 PathItem pathItemObject = new PathItem();
-                if (service.getAction().equalsIgnoreCase(HttpMethod.GET)) {
-                    boolean inParamsEmpty = 
UtilValidate.isEmpty(service.getInParamNamesMap());
-                    if (!inParamsEmpty) {
-                        QueryParameter serviceInParam = new QueryParameter();
-                        serviceInParam.setRequired(true);
-                        serviceInParam.setDescription("Operation Input 
Parameters in JSON");
-                        serviceInParam.setName("input");
-
-                        Schema<?> refSchema = new Schema<>();
-                        refSchema.$ref("#/components/schemas/" + 
"api.request." + service.getName());
-                        serviceInParam.content(new 
Content().addMediaType(jakarta.ws.rs.core.MediaType.APPLICATION_JSON,
-                                new MediaType().schema(refSchema)));
-                        operation.addParametersItem(serviceInParam);
-                    }
-                    operation.addParametersItem(HEADER_ACCEPT_JSON);
-                } else if (action.matches(HttpMethod.POST + "|" + 
HttpMethod.PUT + "|" + HttpMethod.PATCH)) {
-                    RequestBody request = new 
RequestBody().description("Request Body for service " + service.getName())
-                            .content(new 
Content().addMediaType(jakarta.ws.rs.core.MediaType.APPLICATION_JSON,
-                                    new MediaType().schema(new 
Schema<>().$ref("#/components/schemas/" + "api.request." + 
service.getName()))));
-                    operation.setRequestBody(request);
-                    operation.addParametersItem(HEADER_CONTENT_TYPE_JSON);
-                }
+                RequestBody request = new RequestBody().description("Request 
Body for service " + service.getName())
+                        .content(new 
Content().addMediaType(jakarta.ws.rs.core.MediaType.APPLICATION_JSON,
+                                new MediaType().schema(new 
Schema<>().$ref("#/components/schemas/" + "api.request." + 
service.getName()))));
+                operation.setRequestBody(request);
+                operation.addParametersItem(HEADER_CONTENT_TYPE_JSON);
+
                 addServiceOutSchema(service);
                 addServiceInSchema(service);
                 addServiceOperationApiResponses(service, operation);
-                setPathItemOperation(pathItemObject, 
service.getAction().toUpperCase(), operation);
+                setPathItemOperation(pathItemObject, HttpMethod.POST, 
operation);
                 paths.addPathItem("/services/" + service.getName(), 
pathItemObject);
             }
         }
diff --git 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
index 44cd5f2eaa..42ec82da41 100644
--- 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
+++ 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
@@ -97,12 +97,12 @@ public class OFBizServiceResource {
         List<Map<String, Object>> serviceList = new ArrayList<>();
         for (String serviceName : serviceNames) {
             ModelService service = context.getModelService(serviceName);
-            if (service != null && service.isExport() && 
UtilValidate.isNotEmpty(service.getAction())) {
+            if (service != null && service.isExport()) {
                 Map<String, Object> serviceMap = new LinkedHashMap<String, 
Object>();
                 serviceMap.put("name", service.getName());
                 serviceMap.put("description", service.getDescription());
                 Link selfLink = 
Link.fromUriBuilder(uriInfo.getAbsolutePathBuilder().path(service.getName()))
-                        .type(service.getAction()).rel("self").build();
+                        .type(HttpMethod.POST).rel("self").build();
                 serviceMap.put("link", selfLink);
                 serviceList.add(serviceMap);
             }
diff --git a/framework/service/dtd/services.xsd 
b/framework/service/dtd/services.xsd
index e7e90b4049..f07fd34a96 100644
--- a/framework/service/dtd/services.xsd
+++ b/framework/service/dtd/services.xsd
@@ -67,20 +67,6 @@ under the License.
         <xs:attribute name="export" type="xs:boolean" default="false"/>
         <xs:attribute name="validate" type="xs:boolean" default="true"/>
         <xs:attribute name="default-entity-name" type="xs:string"/>
-        <xs:attribute name="action">
-            <xs:annotation>
-                <xs:documentation>
-                    Specifies the HTTP method name this service can be called 
using REST interface. For now only POST and GET are supported.
-                    Services that have export=true and have action attribute 
defined can be called using REST interface.
-                </xs:documentation>
-            </xs:annotation>
-              <xs:simpleType>
-                <xs:restriction base="xs:string">
-                      <xs:enumeration value="POST"/>
-                      <xs:enumeration value="GET"/>
-                </xs:restriction>
-              </xs:simpleType>
-        </xs:attribute>
         <xs:attribute name="use-transaction" type="xs:boolean" default="true">
             <xs:annotation>
                 <xs:documentation>
diff --git 
a/framework/service/src/main/java/org/apache/ofbiz/service/ModelService.java 
b/framework/service/src/main/java/org/apache/ofbiz/service/ModelService.java
index 11ac720574..8fb9e511fd 100644
--- a/framework/service/src/main/java/org/apache/ofbiz/service/ModelService.java
+++ b/framework/service/src/main/java/org/apache/ofbiz/service/ModelService.java
@@ -134,9 +134,6 @@ public class ModelService extends AbstractMap<String, 
Object> implements Seriali
     /** The namespace of this service */
     private String nameSpace;
 
-    /** The corresponding REST verb behaviour for this service */
-    private String action;
-
     /** The package name or location of this service */
     private String location;
 
@@ -262,14 +259,6 @@ public class ModelService extends AbstractMap<String, 
Object> implements Seriali
         this.nameSpace = nameSpace;
     }
 
-    /**
-     * Sets action.
-     * @param action the action
-     */
-    public void setAction(String action) {
-        this.action = action;
-    }
-
     /**
      * Sets location.
      * @param location the location
@@ -526,14 +515,6 @@ public class ModelService extends AbstractMap<String, 
Object> implements Seriali
         return nameSpace;
     }
 
-    /**
-     * Gets action.
-     * @return the action
-     */
-    public String getAction() {
-        return action;
-    }
-
     /**
      * Gets default entity name.
      * @return the default entity name
@@ -801,7 +782,6 @@ public class ModelService extends AbstractMap<String, 
Object> implements Seriali
         this.defaultEntityName = model.defaultEntityName;
         this.auth = model.auth;
         this.export = model.export;
-        this.action = model.action;
         this.validate = model.validate;
         this.useTransaction = model.useTransaction;
         this.requireNewTransaction = model.requireNewTransaction;
@@ -937,7 +917,6 @@ public class ModelService extends AbstractMap<String, 
Object> implements Seriali
         buf.append(defaultEntityName).append("::");
         buf.append(auth).append("::");
         buf.append(export).append("::");
-        buf.append(action).append("::");
         buf.append(validate).append("::");
         buf.append(useTransaction).append("::");
         buf.append(requireNewTransaction).append("::");
diff --git 
a/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java
 
b/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java
index 8e89221b6f..604868eda2 100644
--- 
a/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java
+++ 
b/framework/service/src/main/java/org/apache/ofbiz/service/ModelServiceReader.java
@@ -170,7 +170,6 @@ public final class ModelServiceReader implements 
Serializable {
         
service.setSemaphore(UtilXml.checkEmpty(serviceElement.getAttribute("semaphore")).intern());
         
service.setDefaultEntityName(UtilXml.checkEmpty(serviceElement.getAttribute("default-entity-name")).intern());
         service.setFromLoader(isFromURL ? readerURL.toExternalForm() : 
handler.getLoaderName());
-        
service.setAction(UtilXml.checkEmpty(serviceElement.getAttribute("action")).intern());
 
         // these default to true; if anything but true, make false
         
service.setAuth("true".equalsIgnoreCase(serviceElement.getAttribute("auth")));

Reply via email to