You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/07/04 09:01:32 UTC

[servicecomb-java-chassis] branch weak-contract-type updated: [SCB-1346][WIP][WEAK] only special type need convert logic

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

liubao pushed a commit to branch weak-contract-type
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/weak-contract-type by this push:
     new d7c08e5  [SCB-1346][WIP][WEAK] only special type need convert logic
d7c08e5 is described below

commit d7c08e59e1a36568dace02239427d992e80e2828
Author: wujimin <wu...@huawei.com>
AuthorDate: Wed Jul 3 01:23:08 2019 +0800

    [SCB-1346][WIP][WEAK] only special type need convert logic
---
 .../swagger/invocation/converter/Converter.java    |   6 +
 .../swagger/invocation/converter/ConverterMgr.java | 197 ---------------------
 .../invocation/converter/CustomizedConverter.java  |  25 ---
 .../invocation/converter/impl/ConverterCommon.java |  38 ----
 .../converter/impl/part/BytesToPartConverter.java  |   6 +-
 .../converter/impl/part/FileToPartConverter.java   |   6 +-
 .../impl/part/InputStreamToPartConverter.java      |   6 +-
 .../PartListToPartArrayConverter.java}             |  27 +--
 .../PartListToPartListConverter.java}              |  27 +--
 .../PartToPartConverter.java}                      |  20 ++-
 .../impl/part/ResourceToPartConverter.java         |   6 +-
 ...vicecomb.swagger.invocation.converter.Converter |  23 +++
 .../invocation/converter/ConverterMgrTest.java     |  44 -----
 .../part/PartListToPartArrayConverterTest.java}    |  44 ++---
 .../part/PartListToPartListConverterTest.java}     |  37 ++--
 .../impl/part/PartToPartConverterTest.java}        |  39 ++--
 16 files changed, 141 insertions(+), 410 deletions(-)

diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/Converter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/Converter.java
index 34cc5ab..f3b2753 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/Converter.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/Converter.java
@@ -16,6 +16,12 @@
  */
 package org.apache.servicecomb.swagger.invocation.converter;
 
+import java.lang.reflect.Type;
+
 public interface Converter {
+  Type getSrcType();
+
+  Type getTargetType();
+
   Object convert(Object value);
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java
deleted file mode 100644
index ec0e2b6..0000000
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgr.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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.servicecomb.swagger.invocation.converter;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.commons.lang3.reflect.TypeUtils;
-import org.apache.servicecomb.swagger.invocation.InvocationType;
-import org.apache.servicecomb.swagger.invocation.converter.impl.ConverterCommon;
-import org.apache.servicecomb.swagger.invocation.converter.impl.ConverterSame;
-import org.apache.servicecomb.swagger.invocation.converter.impl.SameElementArrayToList;
-import org.apache.servicecomb.swagger.invocation.converter.impl.SameElementArrayToSet;
-import org.apache.servicecomb.swagger.invocation.converter.impl.SameElementCollectionToArray;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import com.google.inject.util.Types;
-
-@Component
-public class ConverterMgr {
-  private static final Logger LOGGER = LoggerFactory.getLogger(ConverterMgr.class);
-
-  //  第一层key是src type,第二层key是target type
-  private Map<Type, Map<Type, Converter>> srcTargetMap = new HashMap<>();
-
-  // key为target type,这个场景,不关注源实例类型,直接用jackson convert
-  // 效率最低,走到这个处理流程的,都需要打印日志,说明这是很坏的实践
-  // 但是如果不做这个功能,又会有一堆人觉得约束太多
-  private Map<Type, Converter> commonMap = new ConcurrentHashMap<>();
-
-  private Converter same = ConverterSame.getInstance();
-
-  private Converter arrayToList = SameElementArrayToList.getInstance();
-
-  private Converter arrayToSet = SameElementArrayToSet.getInstance();
-
-  // array的构造需要有类型,不能使用统一的处理
-  private Map<Type, Converter> collectionToArrayMap = new ConcurrentHashMap<>();
-
-  @Autowired(required = false)
-  public void setCustomizedConverters(List<CustomizedConverter> converters) {
-    for (CustomizedConverter converter : converters) {
-      Map<Type, Converter> map = srcTargetMap.computeIfAbsent(converter.getSrcType(), k -> new HashMap<>());
-      map.put(converter.getTargetType(), converter);
-    }
-  }
-
-  public Converter findConverter(InvocationType invocationType, Type provider, Type swagger) {
-    if (InvocationType.CONSUMER.equals(invocationType)) {
-      return findConverter(provider, swagger);
-    }
-
-    return findConverter(swagger, provider);
-  }
-
-  public Converter findConverter(Type src, Type target) {
-    Converter converter = findSrcTarget(src, target);
-    if (converter != null) {
-      return converter;
-    }
-
-    converter = findAssignable(src, target);
-    if (converter != null) {
-      return converter;
-    }
-
-    converter = findCollectionToArray(src, target);
-    if (converter != null) {
-      return converter;
-    }
-
-    converter = findArrayToCollection(src, target);
-    if (converter != null) {
-      return converter;
-    }
-
-    LOGGER.warn("Bad practice, low performance, convert from {} to {}", src, target);
-    return findCommonConverter(target);
-  }
-
-
-  protected Converter findSrcTarget(Type src, Type target) {
-    Map<Type, Converter> map = srcTargetMap.get(src);
-    if (map != null) {
-      Converter converter = map.get(target);
-      if (converter == null) {
-        //maybe target class is ArrayList...
-        Type realTarget = checkAndGetType(target);
-        if (realTarget != null) {
-          converter = map.get(realTarget);
-        }
-      }
-      return converter;
-    }
-    return null;
-  }
-
-  // check whether is ArrayList , LinkedList ...  or not
-  private Type checkAndGetType(Type type) {
-    if (ParameterizedType.class.isAssignableFrom(type.getClass())) {
-      ParameterizedType targetType = (ParameterizedType) type;
-      Class<?> targetCls = (Class<?>) targetType.getRawType();
-      if (List.class.isAssignableFrom(targetCls)) {
-        return Types.newParameterizedType(List.class, targetType.getActualTypeArguments()[0]);
-      }
-    }
-    return null;
-  }
-
-  protected Converter findCommonConverter(Type target) {
-    Converter converter = commonMap.get(target);
-    if (converter != null) {
-      return converter;
-    }
-
-    // 并发导致重复创建没有问题
-    converter = new ConverterCommon(target);
-    commonMap.put(target, converter);
-    return converter;
-  }
-
-  protected Converter findArrayToCollection(Type src, Type target) {
-    if (src.getClass().equals(Class.class) && ParameterizedType.class.isAssignableFrom(target.getClass())) {
-      Class<?> srcCls = (Class<?>) src;
-      ParameterizedType targetType = (ParameterizedType) target;
-      Class<?> targetCls = (Class<?>) targetType.getRawType();
-
-      if (srcCls.isArray() && srcCls.getComponentType().equals(targetType.getActualTypeArguments()[0])) {
-        if (List.class.isAssignableFrom(targetCls)) {
-          return arrayToList;
-        }
-        if (Set.class.isAssignableFrom(targetCls)) {
-          return arrayToSet;
-        }
-      }
-    }
-
-    return null;
-  }
-
-  protected Converter findAssignable(Type src, Type target) {
-    if (isAssignable(src, target)) {
-      return same;
-    }
-
-    return null;
-  }
-
-  boolean isAssignable(Type src, Type target) {
-    boolean assignable = TypeUtils.isAssignable(src, target);
-    if (!assignable) {
-      // void <--> java.lang.Void convert should be covered
-      assignable = (src == void.class || src == Void.class) && (target == void.class || target == Void.class);
-    }
-    return assignable;
-  }
-
-  protected Converter findCollectionToArray(Type src, Type target) {
-    if (ParameterizedType.class.isAssignableFrom(src.getClass()) && target.getClass().equals(Class.class)) {
-      ParameterizedType srcType = (ParameterizedType) src;
-      Class<?> srcCls = (Class<?>) srcType.getRawType();
-      Class<?> targetCls = (Class<?>) target;
-
-      if (Collection.class.isAssignableFrom(srcCls) && targetCls.isArray()
-          && srcType.getActualTypeArguments()[0].equals(targetCls.getComponentType())) {
-        Converter converter = collectionToArrayMap
-            .computeIfAbsent(target, k -> new SameElementCollectionToArray(targetCls.getComponentType()));
-        return converter;
-      }
-    }
-
-    return null;
-  }
-}
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/CustomizedConverter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/CustomizedConverter.java
deleted file mode 100644
index 02417b7..0000000
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/CustomizedConverter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.servicecomb.swagger.invocation.converter;
-
-import java.lang.reflect.Type;
-
-public interface CustomizedConverter extends Converter {
-  Type getSrcType();
-
-  Type getTargetType();
-}
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/ConverterCommon.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/ConverterCommon.java
deleted file mode 100644
index 1ab9e65..0000000
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/ConverterCommon.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.servicecomb.swagger.invocation.converter.impl;
-
-import java.lang.reflect.Type;
-
-import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.swagger.invocation.converter.Converter;
-
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-
-public class ConverterCommon implements Converter {
-  private JavaType targetJavaType;
-
-  public ConverterCommon(Type targetType) {
-    targetJavaType = TypeFactory.defaultInstance().constructType(targetType);
-  }
-
-  @Override
-  public Object convert(Object value) {
-    return JsonUtils.OBJ_MAPPER.convertValue(value, targetJavaType);
-  }
-}
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/BytesToPartConverter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/BytesToPartConverter.java
index 4426504..4be57eb 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/BytesToPartConverter.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/BytesToPartConverter.java
@@ -23,11 +23,9 @@ import java.lang.reflect.Type;
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.foundation.common.part.InputStreamPart;
-import org.apache.servicecomb.swagger.invocation.converter.CustomizedConverter;
-import org.springframework.stereotype.Component;
+import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-@Component
-public class BytesToPartConverter implements CustomizedConverter {
+public class BytesToPartConverter implements Converter {
   @Override
   public Type getSrcType() {
     return byte[].class;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
index 40ea0eb..9261f67 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
@@ -23,11 +23,9 @@ import java.lang.reflect.Type;
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.foundation.common.part.FilePart;
-import org.apache.servicecomb.swagger.invocation.converter.CustomizedConverter;
-import org.springframework.stereotype.Component;
+import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-@Component
-public class FileToPartConverter implements CustomizedConverter {
+public class FileToPartConverter implements Converter {
   @Override
   public Type getSrcType() {
     return File.class;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/InputStreamToPartConverter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/InputStreamToPartConverter.java
index fca6edf..06faa72 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/InputStreamToPartConverter.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/InputStreamToPartConverter.java
@@ -23,11 +23,9 @@ import java.lang.reflect.Type;
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.foundation.common.part.InputStreamPart;
-import org.apache.servicecomb.swagger.invocation.converter.CustomizedConverter;
-import org.springframework.stereotype.Component;
+import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-@Component
-public class InputStreamToPartConverter implements CustomizedConverter {
+public class InputStreamToPartConverter implements Converter {
   @Override
   public Type getSrcType() {
     return InputStream.class;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementCollectionToArray.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverter.java
similarity index 69%
rename from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementCollectionToArray.java
rename to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverter.java
index 44afe3c..5f64d70 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementCollectionToArray.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverter.java
@@ -14,18 +14,26 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.invocation.converter.impl;
+package org.apache.servicecomb.swagger.invocation.converter.impl.part;
 
-import java.lang.reflect.Array;
-import java.util.Collection;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import javax.servlet.http.Part;
 
 import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-public class SameElementCollectionToArray implements Converter {
-  private Class<?> elementCls;
+import com.google.inject.util.Types;
 
-  public SameElementCollectionToArray(Class<?> elementCls) {
-    this.elementCls = elementCls;
+public class PartListToPartArrayConverter implements Converter {
+  @Override
+  public Type getSrcType() {
+    return Types.newParameterizedType(List.class, Part.class);
+  }
+
+  @Override
+  public Type getTargetType() {
+    return Part[].class;
   }
 
   @Override
@@ -35,8 +43,7 @@ public class SameElementCollectionToArray implements Converter {
     }
 
     @SuppressWarnings("unchecked")
-    Collection<Object> collection = (Collection<Object>) value;
-    Object array = Array.newInstance(elementCls, collection.size());
-    return collection.toArray((Object[]) array);
+    List<Part> partList = (List<Part>) value;
+    return partList.toArray(new Part[partList.size()]);
   }
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementArrayToList.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverter.java
similarity index 70%
rename from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementArrayToList.java
rename to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverter.java
index f5323bc..add08a6 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementArrayToList.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverter.java
@@ -14,29 +14,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.invocation.converter.impl;
+package org.apache.servicecomb.swagger.invocation.converter.impl.part;
 
-import java.util.Arrays;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import javax.servlet.http.Part;
 
 import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-public final class SameElementArrayToList implements Converter {
-  private static final Converter INSTANCE = new SameElementArrayToList();
+import com.google.inject.util.Types;
 
-  public static Converter getInstance() {
-    return INSTANCE;
+public class PartListToPartListConverter implements Converter {
+  @Override
+  public Type getSrcType() {
+    return Types.newParameterizedType(List.class, Part.class);
   }
 
-  private SameElementArrayToList() {
+  @Override
+  public Type getTargetType() {
+    return Types.newParameterizedType(List.class, Part.class);
   }
 
   @Override
   public Object convert(Object value) {
-    if (value == null) {
-      return null;
-    }
-
-    Object[] array = (Object[]) value;
-    return Arrays.asList(array);
+    return value;
   }
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/ConverterSame.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverter.java
similarity index 79%
rename from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/ConverterSame.java
rename to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverter.java
index e856c0d..c61997b 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/ConverterSame.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverter.java
@@ -14,18 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.invocation.converter.impl;
 
-import org.apache.servicecomb.swagger.invocation.converter.Converter;
+package org.apache.servicecomb.swagger.invocation.converter.impl.part;
+
+import java.lang.reflect.Type;
+
+import javax.servlet.http.Part;
 
-public final class ConverterSame implements Converter {
-  private static final Converter INSTANCE = new ConverterSame();
+import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-  public static Converter getInstance() {
-    return INSTANCE;
+public class PartToPartConverter implements Converter {
+  @Override
+  public Type getSrcType() {
+    return Part.class;
   }
 
-  private ConverterSame() {
+  @Override
+  public Type getTargetType() {
+    return Part.class;
   }
 
   @Override
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/ResourceToPartConverter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/ResourceToPartConverter.java
index 58e99c5..ca5384b 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/ResourceToPartConverter.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/ResourceToPartConverter.java
@@ -22,12 +22,10 @@ import java.lang.reflect.Type;
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.foundation.common.part.ResourcePart;
-import org.apache.servicecomb.swagger.invocation.converter.CustomizedConverter;
+import org.apache.servicecomb.swagger.invocation.converter.Converter;
 import org.springframework.core.io.Resource;
-import org.springframework.stereotype.Component;
 
-@Component
-public class ResourceToPartConverter implements CustomizedConverter {
+public class ResourceToPartConverter implements Converter {
   @Override
   public Type getSrcType() {
     return Resource.class;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.converter.Converter b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.converter.Converter
new file mode 100644
index 0000000..8e08ad1
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.converter.Converter
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.swagger.invocation.converter.impl.part.InputStreamToPartConverter
+org.apache.servicecomb.swagger.invocation.converter.impl.part.BytesToPartConverter
+org.apache.servicecomb.swagger.invocation.converter.impl.part.FileToPartConverter
+org.apache.servicecomb.swagger.invocation.converter.impl.part.PartToPartConverter
+org.apache.servicecomb.swagger.invocation.converter.impl.part.PartListToPartArrayConverter
+org.apache.servicecomb.swagger.invocation.converter.impl.part.PartListToPartListConverter
\ No newline at end of file
diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgrTest.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgrTest.java
deleted file mode 100644
index b19fa964..0000000
--- a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/ConverterMgrTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.servicecomb.swagger.invocation.converter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ConverterMgrTest {
-  @Test
-  public void isAssignable() {
-    ConverterMgr converterMgr = new ConverterMgr();
-    // simple type
-    Assert.assertTrue(converterMgr.isAssignable(String.class, String.class));
-    Assert.assertTrue(converterMgr.isAssignable(int.class, Integer.class));
-    Assert.assertTrue(converterMgr.isAssignable(long.class, Long.class));
-    Assert.assertTrue(converterMgr.isAssignable(void.class, Void.class));
-    // simple type reverse
-    Assert.assertTrue(converterMgr.isAssignable(String.class, String.class));
-    Assert.assertTrue(converterMgr.isAssignable(Integer.class, int.class));
-    Assert.assertTrue(converterMgr.isAssignable(Long.class, long.class));
-    Assert.assertTrue(converterMgr.isAssignable(Void.class, void.class));
-    // Object type
-    Assert.assertTrue(converterMgr.isAssignable(ArrayList.class, List.class));
-    Assert.assertFalse(converterMgr.isAssignable(List.class, ArrayList.class));
-  }
-}
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverterTest.java
similarity index 54%
copy from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
copy to swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverterTest.java
index 40ea0eb..c65fde1 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
+++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartArrayConverterTest.java
@@ -14,34 +14,38 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.servicecomb.swagger.invocation.converter.impl.part;
 
-import java.io.File;
-import java.lang.reflect.Type;
+import java.util.Arrays;
 
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.foundation.common.part.FilePart;
-import org.apache.servicecomb.swagger.invocation.converter.CustomizedConverter;
-import org.springframework.stereotype.Component;
-
-@Component
-public class FileToPartConverter implements CustomizedConverter {
-  @Override
-  public Type getSrcType() {
-    return File.class;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PartListToPartArrayConverterTest {
+  PartListToPartArrayConverter converter = new PartListToPartArrayConverter();
+
+  @Test
+  public void getSrcType() {
+    Assert.assertEquals("java.util.List<javax.servlet.http.Part>", converter.getSrcType().getTypeName());
+  }
+
+  @Test
+  public void getTargetType() {
+    Assert.assertEquals(Part[].class.getCanonicalName(), converter.getTargetType().getTypeName());
   }
 
-  @Override
-  public Type getTargetType() {
-    return Part.class;
+  @Test
+  public void convert() {
+    Object parts = converter.convert(Arrays.asList(new FilePart("name", "file")));
+    Assert.assertThat(parts, Matchers.instanceOf(Part[].class));
   }
 
-  @Override
-  public Object convert(Object value) {
-    // not set name, because not easy to get parameter name in this place
-    // org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl not depend on the name
-    return new FilePart(null, (File) value);
+  @Test
+  public void should_got_null_when_convert_null() {
+    Assert.assertNull(converter.convert(null));
   }
-}
+}
\ No newline at end of file
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverterTest.java
similarity index 59%
copy from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
copy to swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverterTest.java
index 40ea0eb..d0869f5 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/FileToPartConverter.java
+++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartListToPartListConverterTest.java
@@ -14,34 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.servicecomb.swagger.invocation.converter.impl.part;
 
-import java.io.File;
-import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
 
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.foundation.common.part.FilePart;
-import org.apache.servicecomb.swagger.invocation.converter.CustomizedConverter;
-import org.springframework.stereotype.Component;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PartListToPartListConverterTest {
+  PartListToPartListConverter converter = new PartListToPartListConverter();
 
-@Component
-public class FileToPartConverter implements CustomizedConverter {
-  @Override
-  public Type getSrcType() {
-    return File.class;
+  @Test
+  public void getSrcType() {
+    Assert.assertEquals("java.util.List<javax.servlet.http.Part>", converter.getSrcType().getTypeName());
   }
 
-  @Override
-  public Type getTargetType() {
-    return Part.class;
+  @Test
+  public void getTargetType() {
+    Assert.assertEquals("java.util.List<javax.servlet.http.Part>", converter.getTargetType().getTypeName());
   }
 
-  @Override
-  public Object convert(Object value) {
-    // not set name, because not easy to get parameter name in this place
-    // org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl not depend on the name
-    return new FilePart(null, (File) value);
+  @Test
+  public void convert() {
+    List<Part> parts = Arrays.asList(new FilePart("name", "file"));
+    Assert.assertSame(parts, converter.convert(parts));
   }
-}
+}
\ No newline at end of file
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementArrayToSet.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverterTest.java
similarity index 58%
rename from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementArrayToSet.java
rename to swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverterTest.java
index 767697d..203d277 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/converter/impl/SameElementArrayToSet.java
+++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/converter/impl/part/PartToPartConverterTest.java
@@ -14,33 +14,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.invocation.converter.impl;
+package org.apache.servicecomb.swagger.invocation.converter.impl.part;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
+import javax.servlet.http.Part;
 
-import org.apache.servicecomb.swagger.invocation.converter.Converter;
+import org.apache.servicecomb.foundation.common.part.FilePart;
+import org.junit.Assert;
+import org.junit.Test;
 
-public final class SameElementArrayToSet implements Converter {
-  private static final Converter INSTANCE = new SameElementArrayToSet();
+public class PartToPartConverterTest {
+  PartToPartConverter converter = new PartToPartConverter();
 
-  public static Converter getInstance() {
-    return INSTANCE;
+  @Test
+  public void getSrcType() {
+    Assert.assertEquals(Part.class.getName(), converter.getSrcType().getTypeName());
   }
 
-  private SameElementArrayToSet() {
+  @Test
+  public void getTargetType() {
+    Assert.assertEquals(Part.class.getName(), converter.getTargetType().getTypeName());
   }
 
-  @Override
-  public Object convert(Object value) {
-    if (value == null) {
-      return null;
-    }
-
-    Object[] array = (Object[]) value;
-    Set<Object> set = new HashSet<>();
-    set.addAll(Arrays.asList(array));
-    return set;
+  @Test
+  public void convert() {
+    Part part = new FilePart("name", "file");
+    Assert.assertSame(part, converter.convert(part));
   }
-}
+}
\ No newline at end of file