This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit c719cc9b563507cb715f9c9e670ec28919143cd7 Author: yaohaishi <yaohai...@huawei.com> AuthorDate: Fri Jul 13 10:06:12 2018 +0800 [SCB-708] pass necessary swagger operation information into ArgumentsMapperFactory --- .../definition/schema/ProducerSchemaFactory.java | 13 +++- swagger/swagger-invocation/invocation-core/pom.xml | 4 + .../swagger/engine/SwaggerEnvironment.java | 33 +++++++- .../swagger/engine/bootstrap/BootstrapNormal.java | 2 + .../arguments/ArgumentsMapperConfig.java | 37 +++++++++ .../arguments/ArgumentsMapperFactory.java | 90 ++++++++++++++++++---- .../invocation/arguments/ProviderParameter.java | 33 +++++++- .../consumer/ConsumerArgumentsMapperFactory.java | 7 +- .../producer/ProducerArgumentsMapperFactory.java | 7 +- .../engine/SwaggerEnvironmentForTest.java | 5 +- 10 files changed, 203 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/org/apache/servicecomb/core/definition/schema/ProducerSchemaFactory.java b/core/src/main/java/org/apache/servicecomb/core/definition/schema/ProducerSchemaFactory.java index 1334332..a3b0a38 100644 --- a/core/src/main/java/org/apache/servicecomb/core/definition/schema/ProducerSchemaFactory.java +++ b/core/src/main/java/org/apache/servicecomb/core/definition/schema/ProducerSchemaFactory.java @@ -17,6 +17,8 @@ package org.apache.servicecomb.core.definition.schema; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; @@ -41,6 +43,7 @@ import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectWriter; +import io.swagger.models.Operation; import io.swagger.models.Swagger; import io.swagger.util.Yaml; @@ -79,7 +82,8 @@ public class ProducerSchemaFactory extends AbstractSchemaFactory<ProducerSchemaC SchemaMeta schemaMeta = getOrCreateSchema(context); - SwaggerProducer producer = swaggerEnv.createProducer(producerInstance, schemaMeta.getSwaggerIntf()); + SwaggerProducer producer = swaggerEnv.createProducer(producerInstance, schemaMeta.getSwaggerIntf(), + convertSwaggerOperationMap(schemaMeta)); Executor reactiveExecutor = BeanUtils.getBean(ExecutorManager.EXECUTOR_REACTIVE); for (OperationMeta operationMeta : schemaMeta.getOperations()) { SwaggerProducerOperation producerOperation = producer.findOperation(operationMeta.getOperationId()); @@ -93,6 +97,13 @@ public class ProducerSchemaFactory extends AbstractSchemaFactory<ProducerSchemaC return schemaMeta; } + private Map<String, Operation> convertSwaggerOperationMap(SchemaMeta schemaMeta) { + Map<String, Operation> operationMap = new LinkedHashMap<>(schemaMeta.getOperations().size()); + schemaMeta.getOperations().forEach( + operationMeta -> operationMap.put(operationMeta.getOperationId(), operationMeta.getSwaggerOperation())); + return operationMap; + } + protected SchemaMeta createSchema(ProducerSchemaContext context) { // 尝试从规划的目录加载契约 Swagger swagger = loadSwagger(context); diff --git a/swagger/swagger-invocation/invocation-core/pom.xml b/swagger/swagger-invocation/invocation-core/pom.xml index 6dfa293..816afbb 100644 --- a/swagger/swagger-invocation/invocation-core/pom.xml +++ b/swagger/swagger-invocation/invocation-core/pom.xml @@ -47,5 +47,9 @@ <artifactId>log4j</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java index 5224d70..e0ba98f 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java @@ -25,6 +25,8 @@ import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.ReflectUtils; +import org.apache.servicecomb.swagger.generator.core.CompositeSwaggerGeneratorContext; +import org.apache.servicecomb.swagger.invocation.arguments.ArgumentsMapperConfig; import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgumentsMapper; import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgumentsMapperFactory; import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper; @@ -40,12 +42,16 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import io.swagger.annotations.ApiOperation; +import io.swagger.models.Operation; @Component public class SwaggerEnvironment { private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerEnvironment.class); @Inject + protected CompositeSwaggerGeneratorContext compositeSwaggerGeneratorContext; + + @Inject private ProducerArgumentsMapperFactory producerArgumentsFactory; private ResponseMapperFactorys<ProducerResponseMapper> producerResponseMapperFactorys = @@ -63,6 +69,15 @@ public class SwaggerEnvironment { producerResponseMapperFactorys.setConverterMgr(converterMgr); } + public CompositeSwaggerGeneratorContext getCompositeSwaggerGeneratorContext() { + return compositeSwaggerGeneratorContext; + } + + public void setCompositeSwaggerGeneratorContext( + CompositeSwaggerGeneratorContext compositeSwaggerGeneratorContext) { + this.compositeSwaggerGeneratorContext = compositeSwaggerGeneratorContext; + } + public ProducerArgumentsMapperFactory getProducerArgumentsFactory() { return producerArgumentsFactory; } @@ -101,8 +116,12 @@ public class SwaggerEnvironment { continue; } + ArgumentsMapperConfig config = new ArgumentsMapperConfig(); + config.setSwaggerMethod(swaggerMethod); + config.setProviderMethod(consumerMethod); + ConsumerArgumentsMapper argsMapper = - consumerArgumentsFactory.createArgumentsMapper(swaggerMethod, consumerMethod); + consumerArgumentsFactory.createArgumentsMapper(config); ConsumerResponseMapper responseMapper = consumerResponseMapperFactorys.createResponseMapper( swaggerMethod.getGenericReturnType(), consumerMethod.getGenericReturnType()); @@ -129,7 +148,8 @@ public class SwaggerEnvironment { return apiOperationAnnotation.nickname(); } - public SwaggerProducer createProducer(Object producerInstance, Class<?> swaggerIntf) { + public SwaggerProducer createProducer(Object producerInstance, Class<?> swaggerIntf, + Map<String, Operation> swaggerOperationMap) { Class<?> producerCls = BeanUtils.getImplClassFromBean(producerInstance); Map<String, Method> visibleProducerMethods = retrieveVisibleMethods(producerCls); @@ -148,8 +168,13 @@ public class SwaggerEnvironment { throw new Error(msg); } - ProducerArgumentsMapper argsMapper = producerArgumentsFactory.createArgumentsMapper(swaggerMethod, - producerMethod); + ArgumentsMapperConfig config = new ArgumentsMapperConfig(); + config.setSwaggerMethod(swaggerMethod); + config.setProviderMethod(producerMethod); + config.setSwaggerOperation(swaggerOperationMap.get(methodName)); + config.setSwaggerGeneratorContext(compositeSwaggerGeneratorContext.selectContext(producerCls)); + + ProducerArgumentsMapper argsMapper = producerArgumentsFactory.createArgumentsMapper(config); ProducerResponseMapper responseMapper = producerResponseMapperFactorys.createResponseMapper( swaggerMethod.getGenericReturnType(), producerMethod.getGenericReturnType()); diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/bootstrap/BootstrapNormal.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/bootstrap/BootstrapNormal.java index 83e32aa..9ed501a 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/bootstrap/BootstrapNormal.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/bootstrap/BootstrapNormal.java @@ -20,6 +20,7 @@ import java.util.Arrays; import org.apache.servicecomb.swagger.engine.SwaggerBootstrap; import org.apache.servicecomb.swagger.engine.SwaggerEnvironment; +import org.apache.servicecomb.swagger.generator.core.CompositeSwaggerGeneratorContext; import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgumentsMapperFactory; import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerInvocationContextMapperFactory; import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapperFactory; @@ -43,6 +44,7 @@ public class BootstrapNormal implements SwaggerBootstrap { env.setConsumerArgumentsFactory(consumerArgumentsFactory); env.setConverterMgr(converterMgr); + env.setCompositeSwaggerGeneratorContext(new CompositeSwaggerGeneratorContext()); return env; } diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperConfig.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperConfig.java index fcb89d5..da27083 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperConfig.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperConfig.java @@ -21,12 +21,20 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext; + +import io.swagger.models.Operation; + public class ArgumentsMapperConfig { // input private Method swaggerMethod; private Method providerMethod; + private Operation swaggerOperation; + + private SwaggerGeneratorContext swaggerGeneratorContext; + // output private List<ArgumentMapper> argumentMapperList = new ArrayList<>(); @@ -46,6 +54,23 @@ public class ArgumentsMapperConfig { this.providerMethod = providerMethod; } + public Operation getSwaggerOperation() { + return swaggerOperation; + } + + public void setSwaggerOperation(Operation swaggerOperation) { + this.swaggerOperation = swaggerOperation; + } + + public SwaggerGeneratorContext getSwaggerGeneratorContext() { + return swaggerGeneratorContext; + } + + public void setSwaggerGeneratorContext( + SwaggerGeneratorContext swaggerGeneratorContext) { + this.swaggerGeneratorContext = swaggerGeneratorContext; + } + public List<ArgumentMapper> getArgumentMapperList() { return argumentMapperList; } @@ -57,4 +82,16 @@ public class ArgumentsMapperConfig { public void addArgumentMapper(ArgumentMapper argumentMapper) { argumentMapperList.add(argumentMapper); } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("ArgumentsMapperConfig{"); + sb.append("swaggerMethod=").append(swaggerMethod); + sb.append(", providerMethod=").append(providerMethod); + sb.append(", swaggerOperation=").append(swaggerOperation); + sb.append(", swaggerGeneratorContext=").append(swaggerGeneratorContext); + sb.append(", argumentMapperList=").append(argumentMapperList); + sb.append('}'); + return sb.toString(); + } } diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperFactory.java index 8e4f183..3d86a49 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperFactory.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ArgumentsMapperFactory.java @@ -17,6 +17,7 @@ package org.apache.servicecomb.swagger.invocation.arguments; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -26,14 +27,30 @@ import java.util.List; import java.util.Map; import javax.inject.Inject; +import javax.ws.rs.CookieParam; +import javax.ws.rs.FormParam; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils; import org.apache.servicecomb.swagger.invocation.InvocationType; import org.apache.servicecomb.swagger.invocation.converter.Converter; import org.apache.servicecomb.swagger.invocation.converter.ConverterMgr; import org.apache.servicecomb.swagger.invocation.converter.impl.ConverterCommon; import org.springframework.util.TypeUtils; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; -public abstract class ArgumentsMapperFactory { + +/** + * @param <T> type of the generated ArgumentsMapper + */ +public abstract class ArgumentsMapperFactory<T> { @Inject protected ConverterMgr converterMgr; @@ -59,16 +76,6 @@ public abstract class ArgumentsMapperFactory { return null; } - public <T> T createArgumentsMapper(Method swaggerMethod, Method providerMethod) { - ArgumentsMapperConfig config = new ArgumentsMapperConfig(); - config.setSwaggerMethod(swaggerMethod); - config.setProviderMethod(providerMethod); - - collectArgumentsMapper(config); - - return createArgumentsMapper(config); - } - protected void collectArgumentsMapper(ArgumentsMapperConfig config) { List<ProviderParameter> providerNormalParams = collectContextArgumentsMapper(config); if (providerNormalParams.isEmpty()) { @@ -128,13 +135,70 @@ public abstract class ArgumentsMapperFactory { continue; } - ProviderParameter pp = new ProviderParameter(providerIdx, parameterType); + ProviderParameter pp = new ProviderParameter(providerIdx, parameterType, + retrieveVisibleParamName(config.getProviderMethod(), providerIdx)); providerNormalParams.add(pp); } return providerNormalParams; } + /** + * Try to get the swagger param name of the corresponding producer/consumer method param + * @param method producer/consumer method + * @param paramIndex index of the producer/consumer method + * @return the param name specified by param annotations, or the param name defined in code + */ + public static String retrieveVisibleParamName(Method method, int paramIndex) { + final Annotation[] annotations = method.getParameterAnnotations()[paramIndex]; + String paramName = null; + for (Annotation annotation : annotations) { + paramName = retrieveVisibleParamName(annotation); + } + if (null == paramName) { + paramName = ParamUtils.getParameterName(method, paramIndex); + } + return paramName; + } + + public static String retrieveVisibleParamName(Annotation annotation) { + if (CookieParam.class.isInstance(annotation)) { + return ((CookieParam) annotation).value(); + } + if (CookieValue.class.isInstance(annotation)) { + return ((CookieValue) annotation).name(); + } + if (FormParam.class.isInstance(annotation)) { + return ((FormParam) annotation).value(); + } + if (HeaderParam.class.isInstance(annotation)) { + return ((HeaderParam) annotation).value(); + } + if (PathParam.class.isInstance(annotation)) { + return ((PathParam) annotation).value(); + } + if (PathVariable.class.isInstance(annotation)) { + return ((PathVariable) annotation).value(); + } + if (QueryParam.class.isInstance(annotation)) { + return ((QueryParam) annotation).value(); + } + if (RequestAttribute.class.isInstance(annotation)) { + return ((RequestAttribute) annotation).name(); + } + if (RequestHeader.class.isInstance(annotation)) { + return ((RequestHeader) annotation).name(); + } + if (RequestParam.class.isInstance(annotation)) { + return ((RequestParam) annotation).name(); + } + if (RequestPart.class.isInstance(annotation)) { + return ((RequestPart) annotation).name(); + } + + return null; + } + protected void collectSwaggerArgumentsMapper(ArgumentsMapperConfig config, List<ProviderParameter> providerNormalParams) { Method swaggerMethod = config.getSwaggerMethod(); @@ -180,7 +244,7 @@ public abstract class ArgumentsMapperFactory { config.addArgumentMapper(bodyFieldArg); } - protected abstract <T> T createArgumentsMapper(ArgumentsMapperConfig config); + public abstract T createArgumentsMapper(ArgumentsMapperConfig config); protected abstract ArgumentMapper createArgumentMapperWithConverter(int swaggerIdx, int providerIdx, Converter converter); diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ProviderParameter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ProviderParameter.java index 3382a97..299c02f 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ProviderParameter.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ProviderParameter.java @@ -23,24 +23,51 @@ public class ProviderParameter { private Type type; - public ProviderParameter(int index, Type type) { + /** + * the param name specified by param annotations(i.e. the param name in schema), or the param name defined in code + */ + private String name; + + public ProviderParameter(int index, Type type, String name) { this.index = index; this.type = type; + this.name = name; } public int getIndex() { return index; } - public void setIndex(int index) { + public ProviderParameter setIndex(int index) { this.index = index; + return this; } public Type getType() { return type; } - public void setType(Type type) { + public ProviderParameter setType(Type type) { this.type = type; + return this; + } + + public String getName() { + return name; + } + + public ProviderParameter setName(String name) { + this.name = name; + return this; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("ProviderParameter{"); + sb.append("index=").append(index); + sb.append(", type=").append(type); + sb.append(", name='").append(name).append('\''); + sb.append('}'); + return sb.toString(); } } diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperFactory.java index 7d77890..54a69ca 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperFactory.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperFactory.java @@ -33,7 +33,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component -public class ConsumerArgumentsMapperFactory extends ArgumentsMapperFactory { +public class ConsumerArgumentsMapperFactory extends ArgumentsMapperFactory<ConsumerArgumentsMapper> { public ConsumerArgumentsMapperFactory() { type = InvocationType.CONSUMER; } @@ -46,8 +46,9 @@ public class ConsumerArgumentsMapperFactory extends ArgumentsMapperFactory { @SuppressWarnings("unchecked") @Override - protected <T> T createArgumentsMapper(ArgumentsMapperConfig config) { - return (T) new ConsumerArgumentsMapper(config.getArgumentMapperList(), + public ConsumerArgumentsMapper createArgumentsMapper(ArgumentsMapperConfig config) { + collectArgumentsMapper(config); + return new ConsumerArgumentsMapper(config.getArgumentMapperList(), config.getSwaggerMethod().getParameterCount()); } diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperFactory.java index c3d47ea..fa40e3e 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperFactory.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperFactory.java @@ -33,7 +33,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component -public class ProducerArgumentsMapperFactory extends ArgumentsMapperFactory { +public class ProducerArgumentsMapperFactory extends ArgumentsMapperFactory<ProducerArgumentsMapper> { public ProducerArgumentsMapperFactory() { type = InvocationType.PRODUCER; } @@ -46,8 +46,9 @@ public class ProducerArgumentsMapperFactory extends ArgumentsMapperFactory { @SuppressWarnings("unchecked") @Override - protected <T> T createArgumentsMapper(ArgumentsMapperConfig config) { - return (T) new ProducerArgumentsMapper(config.getArgumentMapperList(), + public ProducerArgumentsMapper createArgumentsMapper(ArgumentsMapperConfig config) { + collectArgumentsMapper(config); + return new ProducerArgumentsMapper(config.getArgumentMapperList(), config.getProviderMethod().getParameterCount()); } diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/engine/SwaggerEnvironmentForTest.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/engine/SwaggerEnvironmentForTest.java index 72eb40d..b2c6d00 100644 --- a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/engine/SwaggerEnvironmentForTest.java +++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/engine/SwaggerEnvironmentForTest.java @@ -16,6 +16,8 @@ */ package org.apache.servicecomb.engine; +import java.util.LinkedHashMap; + import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.swagger.converter.SwaggerToClassGenerator; import org.apache.servicecomb.swagger.engine.SwaggerEnvironment; @@ -47,6 +49,7 @@ public class SwaggerEnvironmentForTest { SwaggerToClassGenerator swaggerToClassGenerator = new SwaggerToClassGenerator(classLoader, swagger, producerInstance.getClass().getPackage().getName()); - return swaggerEnvironment.createProducer(producerInstance, swaggerToClassGenerator.convert()); + return swaggerEnvironment.createProducer(producerInstance, swaggerToClassGenerator.convert(), + new LinkedHashMap<>()); } }