Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.concurrent.CompletableFuture;

Expand Down Expand Up @@ -46,6 +47,11 @@ public class SwaggerProducerOperation {

private SwaggerOperation swaggerOperation;

// swagger parameter types relate to producer
// because features of @BeanParam/query wrapper/rpc mode parameter wrapper
// types is not direct equals to producerMethod parameter types
private Type[] swaggerParameterTypes;

private ProducerArgumentsMapper argumentsMapper;

private ProducerResponseMapper responseMapper;
Expand Down Expand Up @@ -81,10 +87,22 @@ public void setProducerMethod(Method producerMethod) {
this.producerMethod = producerMethod;
}

public SwaggerOperation getSwaggerOperation() {
return swaggerOperation;
}

public void setSwaggerOperation(SwaggerOperation swaggerOperation) {
this.swaggerOperation = swaggerOperation;
}

public Type[] getSwaggerParameterTypes() {
return swaggerParameterTypes;
}

public void setSwaggerParameterTypes(Type[] swaggerParameterTypes) {
this.swaggerParameterTypes = swaggerParameterTypes;
}

public ProducerArgumentsMapper getArgumentsMapper() {
return argumentsMapper;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ public abstract class AbstractArgumentsMapperCreator {
// body index in swagger parameters
protected int swaggerBodyIdx;

protected BodyParameter bodyParameter;

protected Map<String, Property> swaggerBodyProperties;

public AbstractArgumentsMapperCreator(SerializationConfig serializationConfig,
Expand All @@ -118,7 +120,7 @@ public AbstractArgumentsMapperCreator(SerializationConfig serializationConfig,

this.swaggerParameters = new ArrayList<>(this.swaggerOperation.getOperation().getParameters());

BodyParameter bodyParameter = findSwaggerBodyParameter();
bodyParameter = findSwaggerBodyParameter();
swaggerBodyProperties = SwaggerUtils.getBodyProperties(swaggerOperation.getSwagger(), bodyParameter);
}

Expand Down Expand Up @@ -203,6 +205,17 @@ protected boolean processKnownParameter(int providerParamIdx, java.lang.reflect.
return false;
}

// complex scenes
// swagger: int add(Body x)
// producer: int add(int x, int y)
if (bodyParameter != null &&
!SwaggerUtils.isBean(providerParameter.getType()) &&
swaggerIdx == swaggerBodyIdx &&
SwaggerUtils.isBean(bodyParameter.getSchema())) {
swaggerParameters.set(swaggerIdx, bodyParameter);
return false;
}

ArgumentMapper mapper = createKnownParameterMapper(providerParamIdx, swaggerIdx);
mappers.add(mapper);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.Map;

import org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;
Expand All @@ -36,15 +37,25 @@
import com.fasterxml.jackson.databind.type.TypeFactory;

public class ProducerArgumentsMapperCreator extends AbstractArgumentsMapperCreator {
// swagger parameter types relate to producer
// because features of @BeanParam/query, and rpc mode parameter wrapper
// types is not always equals to producerMethod parameter types directly
private Type[] swaggerParameterTypes;

public ProducerArgumentsMapperCreator(SerializationConfig serializationConfig,
Map<Class<?>, ContextArgumentMapperFactory> contextFactorys,
Method producerMethod, SwaggerOperation swaggerOperation) {
super(serializationConfig, contextFactorys, producerMethod, swaggerOperation);

swaggerParameterTypes = new Type[swaggerOperation.getOperation().getParameters().size()];
}

public Type[] getSwaggerParameterTypes() {
return swaggerParameterTypes;
}

public ProducerArgumentsMapper createArgumentsMapper() {
doCreateArgumentsMapper();

return new ProducerArgumentsMapper(mappers, providerMethod.getParameterCount());
}

Expand All @@ -57,13 +68,16 @@ protected void processUnknownParameter(String parameterName) {

@Override
protected ArgumentMapper createKnownParameterMapper(int producerParamIdx, Integer swaggerIdx) {
return new ProducerArgumentSame(producerParamIdx, swaggerIdx);
swaggerParameterTypes[swaggerIdx] = providerMethod.getGenericParameterTypes()[producerParamIdx];
return new ProducerArgumentSame(swaggerIdx, producerParamIdx);
}

@Override
protected ArgumentMapper createSwaggerBodyFieldMapper(int producerParamIdx, String parameterName,
int swaggerBodyIdx) {
return new SwaggerBodyFieldToProducerArgument(producerParamIdx, parameterName, swaggerBodyIdx);
swaggerParameterTypes[swaggerBodyIdx] = Object.class;
return new SwaggerBodyFieldToProducerArgument(producerParamIdx, parameterName,
providerMethod.getGenericParameterTypes()[producerParamIdx], swaggerBodyIdx);
}

@Override
Expand All @@ -87,6 +101,7 @@ protected void processBeanParameter(int producerParamIdx, Parameter producerPara
setter = LambdaMetafactoryUtils.createSetter(propertyDefinition.getField().getAnnotated());
}

swaggerParameterTypes[swaggerIdx] = propertyDefinition.getPrimaryType();
mapper.addField(swaggerIdx, setter);
}
mappers.add(mapper);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,39 @@

package org.apache.servicecomb.swagger.invocation.arguments.producer;

import java.lang.reflect.Type;
import java.util.Map;

import org.apache.servicecomb.foundation.common.utils.JsonUtils;
import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;

public class SwaggerBodyFieldToProducerArgument implements ArgumentMapper {
public static ObjectMapper mapper = JsonUtils.OBJ_MAPPER;

private final int producerParamIdx;

private final String parameterName;

private final JavaType producerParamType;

private final int swaggerBodyIdx;

public SwaggerBodyFieldToProducerArgument(int producerParamIdx, String parameterName, int swaggerBodyIdx) {
public SwaggerBodyFieldToProducerArgument(int producerParamIdx, String parameterName, Type producerParamType,
int swaggerBodyIdx) {
this.producerParamIdx = producerParamIdx;
this.parameterName = parameterName;
this.producerParamType = TypeFactory.defaultInstance().constructType(producerParamType);
this.swaggerBodyIdx = swaggerBodyIdx;
}

@Override
public void mapArgument(SwaggerInvocation invocation, Object[] producerArguments) {
Map<String, Object> body = invocation.getSwaggerArgument(swaggerBodyIdx);
producerArguments[producerParamIdx] = body.get(parameterName);
producerArguments[producerParamIdx] = mapper.convertValue(body.get(parameterName), producerParamType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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.arguments.producer;

import java.util.Collections;

import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
import org.apache.servicecomb.swagger.engine.SwaggerEnvironment;
import org.apache.servicecomb.swagger.engine.SwaggerProducer;
import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
import org.apache.servicecomb.swagger.invocation.schemas.PojoOneArg;
import org.junit.Assert;
import org.junit.Test;

public class TestPojoOneArg {
@Test
public void should_mapper_swagger_wrapped_body_field_to_producer_enum() {
SwaggerProducer swaggerProducer = new SwaggerEnvironment().createProducer(new PojoOneArg(), null);
SwaggerProducerOperation swaggerProducerOperation = swaggerProducer.findOperation("enumBody");
Assert.assertEquals("color",
swaggerProducerOperation.getSwaggerOperation().getOperation().getParameters().get(0).getName());

ProducerArgumentsMapper mapper = swaggerProducerOperation.getArgumentsMapper();

SwaggerInvocation invocation = new SwaggerInvocation();
invocation.setSwaggerArguments(new Object[] {Collections.singletonMap("color", "BLUE")});

Object[] arguments = mapper.toProducerArgs(invocation);

Assert.assertEquals(1, arguments.length);
Assert.assertSame(Color.BLUE, arguments[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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.schemas;

import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
import org.apache.servicecomb.foundation.test.scaffolding.model.User;

public interface ConsumerOneArg {
void simple(String name);

void bean(User user);

void enumBody(Color color);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.schemas;

import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
import org.apache.servicecomb.foundation.test.scaffolding.model.User;

public class PojoOneArg {
public void simple(String name) {

}

public void bean(User user) {

}

public void enumBody(Color color) {

}
}