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