You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2017/12/26 07:18:39 UTC

[incubator-servicecomb-java-chassis] 01/10: JAV-591 create new mechanism for ResponseMapper

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

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit a5e7a16fb33405099756c523b5305a30ee120ba9
Author: wujimin <wu...@huawei.com>
AuthorDate: Sat Dec 23 16:44:55 2017 +0800

    JAV-591 create new mechanism for ResponseMapper
---
 .../invocation/response/ResponseMapperFactory.java | 36 ++--------
 .../response/ResponseMapperFactorys.java           | 64 +++++++++++++++++
 .../response/TestResponseMapperFactorys.java       | 83 ++++++++++++++++++++++
 3 files changed, 154 insertions(+), 29 deletions(-)

diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java
index c737f97..5faf2b5 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactory.java
@@ -16,42 +16,20 @@
  */
 package io.servicecomb.swagger.invocation.response;
 
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
 
-import javax.inject.Inject;
-
-import io.servicecomb.swagger.invocation.converter.Converter;
 import io.servicecomb.swagger.invocation.converter.ConverterMgr;
 
-public abstract class ResponseMapperFactory<MAPPER> {
-  @Inject
-  protected ConverterMgr converterMgr;
-
-  // 特殊的应答,比如ResponseEntity/cse Response之类
-  protected Map<Class<?>, MAPPER> mappers = new HashMap<>();
-
-  public void setConverterMgr(ConverterMgr converterMgr) {
-    this.converterMgr = converterMgr;
+public interface ResponseMapperFactory<MAPPER> {
+  default int getOrder() {
+    return 0;
   }
 
-  public MAPPER createResponseMapper(Type src, Type target) {
-    Type type = choose(src, target);
-    if (ParameterizedType.class.isAssignableFrom(type.getClass())) {
-      type = ((ParameterizedType) type).getRawType();
-    }
-    MAPPER mapper = mappers.get(type);
-    if (mapper != null) {
-      return mapper;
-    }
-
-    Converter converter = converterMgr.findConverter(src, target);
-    return doCreateResponseMapper(converter);
+  default void setConverterMgr(ConverterMgr converterMgr) {
   }
 
-  protected abstract Type choose(Type src, Type target);
+  boolean isMatch(Type swaggerType, Type providerType);
 
-  protected abstract MAPPER doCreateResponseMapper(Converter converter);
+  MAPPER createResponseMapper(ResponseMapperFactorys<MAPPER> factorys, Type swaggerType,
+      Type providerType);
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactorys.java b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactorys.java
new file mode 100644
index 0000000..1d5e400
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/io/servicecomb/swagger/invocation/response/ResponseMapperFactorys.java
@@ -0,0 +1,64 @@
+/*
+ * 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 io.servicecomb.swagger.invocation.response;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.servicecomb.foundation.common.utils.SPIServiceUtils;
+import io.servicecomb.swagger.invocation.converter.ConverterMgr;
+
+public class ResponseMapperFactorys<MAPPER> {
+  private static final Logger LOGGER = LoggerFactory.getLogger(ResponseMapperFactorys.class);
+
+  private List<ResponseMapperFactory<MAPPER>> factorys;
+
+  public ResponseMapperFactorys(Class<? extends ResponseMapperFactory<MAPPER>> factoryCls, ConverterMgr converterMgr) {
+    this(factoryCls);
+    this.setConverterMgr(converterMgr);
+  }
+
+  @SuppressWarnings("unchecked")
+  public ResponseMapperFactorys(Class<? extends ResponseMapperFactory<MAPPER>> factoryCls) {
+    factorys = (List<ResponseMapperFactory<MAPPER>>) SPIServiceUtils.getSortedService(factoryCls);
+    factorys.forEach(factory -> {
+      LOGGER.info("found factory {} of {}:", factory.getClass().getName(), factoryCls.getName());
+    });
+  }
+
+  public void setConverterMgr(ConverterMgr converterMgr) {
+    factorys.forEach(factory -> factory.setConverterMgr(converterMgr));
+  }
+
+  public MAPPER createResponseMapper(Type swaggerType, Type providerType) {
+    for (ResponseMapperFactory<MAPPER> factory : factorys) {
+      if (!factory.isMatch(swaggerType, providerType)) {
+        continue;
+      }
+
+      return factory.createResponseMapper(this, swaggerType, providerType);
+    }
+
+    throw new IllegalStateException(
+        String.format("can not find response mapper for %s and %s, this should never happened.",
+            swaggerType.getTypeName(),
+            providerType.getTypeName()));
+  }
+}
diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/response/TestResponseMapperFactorys.java b/swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/response/TestResponseMapperFactorys.java
new file mode 100644
index 0000000..bb0173f
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/response/TestResponseMapperFactorys.java
@@ -0,0 +1,83 @@
+/*
+ * 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 io.servicecomb.swagger.invocation.response;
+
+import java.util.List;
+
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import io.servicecomb.swagger.invocation.Response;
+import io.servicecomb.swagger.invocation.converter.Converter;
+import io.servicecomb.swagger.invocation.converter.ConverterMgr;
+import io.servicecomb.swagger.invocation.converter.impl.ConverterSame;
+import io.servicecomb.swagger.invocation.response.consumer.CompletableFutureConsumerResponseMapperFactory;
+import io.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;
+import io.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory;
+import io.servicecomb.swagger.invocation.response.consumer.CseResponseConsumerResponseMapperFactory;
+import io.servicecomb.swagger.invocation.response.consumer.DefaultConsumerResponseMapper;
+import io.servicecomb.swagger.invocation.response.consumer.DefaultConsumerResponseMapperFactory;
+import mockit.Deencapsulation;
+
+public class TestResponseMapperFactorys {
+  ResponseMapperFactorys<ConsumerResponseMapper> consumerResponseMapperFactorys =
+      new ResponseMapperFactorys<>(ConsumerResponseMapperFactory.class);
+
+  List<ResponseMapperFactory<ConsumerResponseMapper>> factorys =
+      Deencapsulation.getField(consumerResponseMapperFactorys, "factorys");
+
+  ConverterMgr converterMgr = new ConverterMgr();
+
+  @Before
+  public void setup() {
+    consumerResponseMapperFactorys.setConverterMgr(converterMgr);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void construct() {
+    Assert.assertThat(factorys,
+        Matchers.contains(Matchers.instanceOf(CseResponseConsumerResponseMapperFactory.class),
+            Matchers.instanceOf(CompletableFutureConsumerResponseMapperFactory.class),
+            Matchers.instanceOf(DefaultConsumerResponseMapperFactory.class)));
+  }
+
+  @Test
+  public void setConverterMgr() {
+    Assert.assertSame(converterMgr, Deencapsulation.getField(factorys.get(2), "converterMgr"));
+  }
+
+  @Test
+  public void createResponseMapper_default() {
+    ConsumerResponseMapper mapper = consumerResponseMapperFactorys.createResponseMapper(String.class, String.class);
+    Assert.assertThat(mapper, Matchers.instanceOf(DefaultConsumerResponseMapper.class));
+
+    Converter converter = Deencapsulation.getField(mapper, "converter");
+    Assert.assertSame(ConverterSame.getInstance(), converter);
+  }
+
+  @Test
+  public void createResponseMapper_cseResponse() {
+    ConsumerResponseMapper mapper = consumerResponseMapperFactorys.createResponseMapper(String.class, Response.class);
+
+    Response response = Response.ok(null);
+    Object result = mapper.mapResponse(response);
+    Assert.assertSame(response, result);
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.