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

albumenj pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.3 by this push:
     new 1916666146 [Feature][3.3] Triple rest jaxrs ParamConverter support 
(#14148)
1916666146 is described below

commit 1916666146ed257bbb0f519eed3f2164a32438f3
Author: fanlobu <[email protected]>
AuthorDate: Mon Jul 22 18:45:03 2024 +0800

    [Feature][3.3] Triple rest jaxrs ParamConverter support (#14148)
    
    * feat() : add paramconverter support
    
    * fix():fix codestyle
    
    * add(): add ParamConverterFactory ,fix the rule of get converter
    
    * add(): add test , complete JaxrsRestToolKit
    
    * fix(): Simplify code writing and fix some logic
    
    * fix(): fix log error code
    
    ---------
    
    Co-authored-by: Albumen Kevin <[email protected]>
    Co-authored-by: earthchen <[email protected]>
---
 .../tri/rest/support/jaxrs/JaxrsRestToolKit.java   | 20 ++++++
 .../rest/support/jaxrs/ParamConverterFactory.java  | 73 ++++++++++++++++++++++
 .../jaxrs/compatible/JaxrsRestProtocolTest.java    | 22 +++++++
 .../rest/ParamConverterProviderImpl.java           | 51 +++++++++++++++
 .../compatible/rest/ParamConverterService.java     | 31 +++++++++
 .../compatible/rest/ParamConverterServiceImpl.java | 26 ++++++++
 .../javax.ws.rs.ext.ParamConverterProvider         |  1 +
 7 files changed, 224 insertions(+)

diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRestToolKit.java
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRestToolKit.java
index 95ef839b87..89d1861dc5 100644
--- 
a/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRestToolKit.java
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRestToolKit.java
@@ -25,16 +25,23 @@ import 
org.apache.dubbo.rpc.protocol.tri.rest.util.DefaultRestToolKit;
 
 import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.ParamConverter;
+
+import java.util.Optional;
 
 final class JaxrsRestToolKit extends DefaultRestToolKit {
 
     private final BeanArgumentBinder binder;
 
+    private final ParamConverterFactory paramConverterFactory;
+
     public JaxrsRestToolKit(FrameworkModel frameworkModel) {
         super(frameworkModel);
         binder = new BeanArgumentBinder(frameworkModel);
+        paramConverterFactory = new ParamConverterFactory();
     }
 
+    @SuppressWarnings({"unchecked", "rawtypes"})
     @Override
     public Object convert(Object value, ParameterMeta parameter) {
         if (MultivaluedMap.class.isAssignableFrom(parameter.getType())) {
@@ -43,6 +50,19 @@ final class JaxrsRestToolKit extends DefaultRestToolKit {
             }
             return typeConverter.convert(value, MultivaluedHashMap.class);
         }
+
+        Optional<ParamConverter> optional = 
paramConverterFactory.getParamConverter(
+                parameter.getType(), parameter.getGenericType(), 
parameter.getRealAnnotations());
+        if (optional.isPresent()) {
+            ParamConverter paramConverter = optional.get();
+            Object result = value.getClass() == String.class
+                    ? paramConverter.fromString((String) value)
+                    : paramConverter.toString(value);
+            if (result != null) {
+                return result;
+            }
+        }
+
         return super.convert(value, parameter);
     }
 
diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/ParamConverterFactory.java
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/ParamConverterFactory.java
new file mode 100644
index 0000000000..bef0a63b90
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/ParamConverterFactory.java
@@ -0,0 +1,73 @@
+/*
+ * 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.dubbo.rpc.protocol.tri.rest.support.jaxrs;
+
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.Pair;
+
+import javax.ws.rs.ext.ParamConverter;
+import javax.ws.rs.ext.ParamConverterProvider;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.ServiceLoader;
+
+import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_ERROR_LOAD_EXTENSION;
+
+@SuppressWarnings({"rawtypes"})
+public class ParamConverterFactory {
+
+    private static final ErrorTypeAwareLogger logger =
+            LoggerFactory.getErrorTypeAwareLogger(ParamConverterFactory.class);
+    private final Map<Pair<Pair<Class<?>, Type>, Annotation[]>, 
Optional<ParamConverter>> cache =
+            CollectionUtils.newConcurrentHashMap();
+    private final List<ParamConverterProvider> providers = new ArrayList<>();
+
+    ParamConverterFactory() {
+        ServiceLoader<ParamConverterProvider> serviceLoader = 
ServiceLoader.load(ParamConverterProvider.class);
+        Iterator<ParamConverterProvider> iterator = serviceLoader.iterator();
+        while (iterator.hasNext()) {
+            try {
+                ParamConverterProvider paramConverterProvider = 
iterator.next();
+                providers.add(paramConverterProvider);
+            } catch (Throwable e) {
+                logger.error(COMMON_ERROR_LOAD_EXTENSION, "", "", "Spi Fail to 
load ParamConverterProvider");
+            }
+        }
+    }
+
+    public <T> Optional<ParamConverter> getParamConverter(
+            Class<T> rawType, Type genericType, Annotation[] annotations) {
+        Pair<Pair<Class<?>, Type>, Annotation[]> pair = 
Pair.of(Pair.of(rawType, genericType), annotations);
+        return cache.computeIfAbsent(pair, k -> {
+            for (ParamConverterProvider provider : providers) {
+                ParamConverter converter = provider.getConverter(rawType, 
genericType, annotations);
+                if (converter != null) {
+                    return Optional.of(converter);
+                }
+            }
+            return Optional.empty();
+        });
+    }
+}
diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/JaxrsRestProtocolTest.java
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/JaxrsRestProtocolTest.java
index fa4b681843..f46c31310a 100644
--- 
a/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/JaxrsRestProtocolTest.java
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/JaxrsRestProtocolTest.java
@@ -39,6 +39,8 @@ import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.Anot
 import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.AnotherUserRestServiceImpl;
 import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.HttpMethodService;
 import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.HttpMethodServiceImpl;
+import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.ParamConverterService;
+import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.ParamConverterServiceImpl;
 import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.RestDemoForTestException;
 import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.RestDemoService;
 import 
org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.RestDemoServiceImpl;
@@ -562,4 +564,24 @@ class JaxrsRestProtocolTest {
         repository.registerProvider(providerModel);
         return url.setServiceModel(providerModel);
     }
+
+    @Test
+    void testParamConverter() {
+        ParamConverterService service = new ParamConverterServiceImpl();
+        URL exportUrl = URL.valueOf(
+                "tri://127.0.0.1:" + availablePort + "/rest?interface=" + 
ParamConverterService.class.getName());
+
+        URL nettyUrl = this.registerProvider(exportUrl, service, 
ParamConverterService.class);
+
+        tProtocol.export(proxy.getInvoker(service, 
ParamConverterService.class, nettyUrl));
+
+        ParamConverterService paramConverterService =
+                
this.proxy.getProxy(protocol.refer(ParamConverterService.class, nettyUrl));
+
+        User user = paramConverterService.convert(User.getInstance());
+        User u = new User();
+        u.setAge(20);
+        u.setId(1L);
+        Assertions.assertEquals(u, user);
+    }
 }
diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterProviderImpl.java
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterProviderImpl.java
new file mode 100644
index 0000000000..24d0a472cb
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterProviderImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest;
+
+import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.User;
+
+import javax.ws.rs.ext.ParamConverter;
+import javax.ws.rs.ext.ParamConverterProvider;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class ParamConverterProviderImpl implements ParamConverterProvider {
+
+    @Override
+    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type type, 
Annotation[] annotations) {
+        if (rawType.isAssignableFrom(User.class)) {
+            return (ParamConverter<T>) new UserParamConverter();
+        }
+        return null;
+    }
+
+    static class UserParamConverter implements ParamConverter<User> {
+        @Override
+        public User fromString(String param) {
+            User user = new User();
+            user.setId(1L);
+            user.setAge(20);
+            return user;
+        }
+
+        @Override
+        public String toString(User user) {
+            return "User{" + "id=" + user.getId() + ", name='" + 
user.getName() + '\'' + ", age=" + user.getAge() + '}';
+        }
+    }
+}
diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterService.java
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterService.java
new file mode 100644
index 0000000000..fa1c20c12d
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterService.java
@@ -0,0 +1,31 @@
+/*
+ * 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.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest;
+
+import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.User;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+@Path("/ParamConverterService")
+public interface ParamConverterService {
+
+    @GET()
+    @Path("/convert")
+    User convert(@QueryParam("user") User user);
+}
diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterServiceImpl.java
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterServiceImpl.java
new file mode 100644
index 0000000000..2b0bedfd21
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/compatible/rest/ParamConverterServiceImpl.java
@@ -0,0 +1,26 @@
+/*
+ * 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.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest;
+
+import org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.User;
+
+public class ParamConverterServiceImpl implements ParamConverterService {
+    @Override
+    public User convert(User user) {
+        return user;
+    }
+}
diff --git 
a/dubbo-plugin/dubbo-rest-jaxrs/src/test/resources/META-INF/services/javax.ws.rs.ext.ParamConverterProvider
 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/resources/META-INF/services/javax.ws.rs.ext.ParamConverterProvider
new file mode 100644
index 0000000000..b794deb158
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-rest-jaxrs/src/test/resources/META-INF/services/javax.ws.rs.ext.ParamConverterProvider
@@ -0,0 +1 @@
+org.apache.dubbo.rpc.protocol.tri.rest.support.jaxrs.compatible.rest.ParamConverterProviderImpl

Reply via email to