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/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new d484b5a86 [SCB-2847]support configure default encoding for request and
response (#4167)
d484b5a86 is described below
commit d484b5a86c5f17adabbf3bb3517ec909e27022d1
Author: liubao68 <[email protected]>
AuthorDate: Tue Dec 26 20:28:41 2023 +0800
[SCB-2847]support configure default encoding for request and response
(#4167)
---
.../utils/ScopedProtobufSchemaManager.java | 14 ++-
.../rest/codec/param/BodyProcessorCreator.java | 107 +++++++++++++++------
.../codec/produce/ProduceProcessorManager.java | 31 ++++--
.../common/rest/definition/RestOperationMeta.java | 38 --------
.../jaxrs/client/MultiErrorCodeServiceClient.java | 5 +-
.../protobuf/internal/schema/SchemaManager.java | 41 +++-----
.../deserializer/DeserializerSchemaManager.java | 2 +-
.../schema/serializer/MessageWriteSchema.java | 6 +-
.../schema/serializer/SerializerSchemaManager.java | 2 +-
9 files changed, 123 insertions(+), 123 deletions(-)
diff --git
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
index e1f08b0dd..3c7e5adbb 100644
---
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
+++
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ScopedProtobufSchemaManager.java
@@ -42,12 +42,15 @@ public class ScopedProtobufSchemaManager {
static class SchemaKey {
String schemaId;
+ String rootMessage;
+
Schema<?> schema;
int hashCode = -1;
- SchemaKey(String schemaId, Schema<?> schema) {
+ SchemaKey(String schemaId, String rootMessage, Schema<?> schema) {
this.schemaId = schemaId;
+ this.rootMessage = rootMessage;
this.schema = schema;
}
@@ -60,7 +63,7 @@ public class ScopedProtobufSchemaManager {
return false;
}
SchemaKey other = (SchemaKey) o;
- return StringUtils.equals(schemaId, other.schemaId)
+ return StringUtils.equals(schemaId, other.schemaId) &&
StringUtils.equals(rootMessage, other.rootMessage)
&& SwaggerUtils.schemaEquals(schema, other.schema);
}
@@ -69,7 +72,7 @@ public class ScopedProtobufSchemaManager {
if (hashCode != -1) {
return hashCode;
}
- hashCode = schemaId.hashCode() ^ SwaggerUtils.schemaHashCode(schema);
+ hashCode = schemaId.hashCode() ^ rootMessage.hashCode() ^
SwaggerUtils.schemaHashCode(schema);
return hashCode;
}
}
@@ -100,8 +103,9 @@ public class ScopedProtobufSchemaManager {
/**
* get the ProtoMapper from Schema
*/
- public ProtoMapper getOrCreateProtoMapper(OpenAPI openAPI, String schemaId,
String rootMessageName, Schema<?> schema) {
- SchemaKey schemaKey = new SchemaKey(schemaId, schema);
+ public ProtoMapper getOrCreateProtoMapper(OpenAPI openAPI, String schemaId,
String rootMessageName,
+ Schema<?> schema) {
+ SchemaKey schemaKey = new SchemaKey(schemaId, rootMessageName, schema);
return schemaMapperCache.computeIfAbsent(schemaKey, key -> {
SchemaToProtoGenerator generator = new
SchemaToProtoGenerator("scb.schema", openAPI,
key.schema, rootMessageName);
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index 78d171121..44a4d3467 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -80,6 +80,12 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
// Do not use it if you are sure how it works. And may be deleted in the
future.
public static final String PARAM_DECODE_AS_OBJECT =
"servicecomb.rest.parameter.decodeAsObject";
+ public static final String PARAM_DEFAULT_REQUEST_ENCODING =
"servicecomb.rest.parameter.default-request-encoding";
+
+ private static Boolean decodeAsObject;
+
+ private static String defaultRequestEncoding;
+
public static class BodyProcessor implements ParamValueProcessor {
// Producer target type. For consumer, is null.
protected JavaType targetType;
@@ -176,9 +182,24 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
return null;
}
- if (!supportedContentTypes.contains(contentType)) {
- throw new IllegalArgumentException(String.format("operation %s not
support content-type %s",
- operationMeta.getSchemaQualifiedName(), contentType));
+ if (MediaType.APPLICATION_JSON.equals(contentType)) {
+ try {
+ ObjectReader reader = serialViewClass != null
+ ?
RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)
+ : RestObjectMapperFactory.getRestObjectMapper().reader();
+ if (decodeAsObject()) {
+ return reader.forType(OBJECT_TYPE).readValue(inputStream);
+ }
+ return reader.forType(targetType == null ? OBJECT_TYPE : targetType)
+ .readValue(inputStream);
+ } catch (MismatchedInputException e) {
+ // there is no way to detect InputStream is empty, so have to catch
the exception
+ if (!isRequired && e.getMessage().contains("No content to map due to
end-of-input")) {
+ LOGGER.info("Empty content and required is false, taken as null");
+ return null;
+ }
+ throw e;
+ }
}
if (SwaggerConst.PROTOBUF_TYPE.equals(contentType)) {
@@ -187,38 +208,37 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
REQUEST_BODY_NAME,
requestBody.getContent().get(SwaggerConst.PROTOBUF_TYPE).getSchema());
RootDeserializer<PropertyWrapper<Object>> deserializer =
protoMapper.getDeserializerSchemaManager()
-
.createRootDeserializer(protoMapper.getProto().getMessage(REQUEST_BODY_NAME),
targetType);
+
.createRootDeserializer(protoMapper.getProto().getMessage(REQUEST_BODY_NAME),
+ targetType == null ? OBJECT_TYPE : targetType);
PropertyWrapper<Object> result =
deserializer.deserialize(inputStream.readAllBytes());
return result.getValue();
}
- // For application/json and text/plain
- try {
- if (MediaType.TEXT_PLAIN.equals(contentType) &&
- targetType != null &&
String.class.equals(targetType.getRawClass())) {
- return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
- }
- ObjectReader reader = serialViewClass != null
- ?
RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)
- : RestObjectMapperFactory.getRestObjectMapper().reader();
- if (decodeAsObject()) {
- return reader.forType(OBJECT_TYPE).readValue(inputStream);
- }
- return reader.forType(targetType == null ? OBJECT_TYPE : targetType)
- .readValue(inputStream);
- } catch (MismatchedInputException e) {
- // there is no way to detect InputStream is empty, so have to catch
the exception
- if (!isRequired && e.getMessage().contains("No content to map due to
end-of-input")) {
- LOGGER.info("Empty content and required is false, taken as null");
- return null;
+ if (MediaType.TEXT_PLAIN.equals(contentType)) {
+ try {
+ if (targetType != null &&
String.class.equals(targetType.getRawClass())) {
+ return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+ }
+ ObjectReader reader = serialViewClass != null
+ ?
RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)
+ : RestObjectMapperFactory.getRestObjectMapper().reader();
+ if (decodeAsObject()) {
+ return reader.forType(OBJECT_TYPE).readValue(inputStream);
+ }
+ return reader.forType(targetType == null ? OBJECT_TYPE : targetType)
+ .readValue(inputStream);
+ } catch (MismatchedInputException e) {
+ // there is no way to detect InputStream is empty, so have to catch
the exception
+ if (!isRequired && e.getMessage().contains("No content to map due to
end-of-input")) {
+ LOGGER.info("Empty content and required is false, taken as null");
+ return null;
+ }
+ throw e;
}
- throw e;
}
- }
- private boolean decodeAsObject() {
- return LegacyPropertyFactory
- .getBooleanProperty(PARAM_DECODE_AS_OBJECT, false);
+ throw new IllegalArgumentException(String.format("operation %s not
support content-type %s",
+ operationMeta.getSchemaQualifiedName(), contentType));
}
private String validContentType(String type) {
@@ -226,8 +246,8 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
if (supportedContentTypes.size() == 0) {
throw new IllegalArgumentException("operation do not have any
content type support.");
}
- if (supportedContentTypes.contains(MediaType.APPLICATION_JSON)) {
- return MediaType.APPLICATION_JSON;
+ if (supportedContentTypes.contains(clientEncodingDefault())) {
+ return clientEncodingDefault();
}
return supportedContentTypes.get(0);
}
@@ -252,6 +272,13 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
* Serialize body object into body buffer, according to the Content-Type.
*/
private Buffer createBodyBuffer(String contentType, Object arg) throws
IOException {
+ if (MediaType.APPLICATION_JSON.equals(contentType)) {
+ try (BufferOutputStream output = new BufferOutputStream()) {
+ RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output,
arg);
+ return output.getBuffer();
+ }
+ }
+
if (SwaggerConst.PROTOBUF_TYPE.equals(contentType)) {
ProtoMapper protoMapper = scopedProtobufSchemaManager
.getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),
@@ -265,9 +292,9 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
return new BufferImpl().appendBytes(serializer.serialize(bodyArg));
}
- // For application/json and text/plain
+ // For text/plain
try (BufferOutputStream output = new BufferOutputStream()) {
- if (MediaType.TEXT_PLAIN.equals(contentType) && (arg instanceof
String)) {
+ if (arg instanceof String) {
output.write(((String) arg).getBytes(StandardCharsets.UTF_8));
} else {
RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output,
arg);
@@ -366,4 +393,20 @@ public class BodyProcessorCreator implements
ParamValueProcessorCreator<RequestB
return new BodyProcessor(operationMeta, targetType, parameter);
}
+
+ private static boolean decodeAsObject() {
+ if (decodeAsObject == null) {
+ decodeAsObject = LegacyPropertyFactory
+ .getBooleanProperty(PARAM_DECODE_AS_OBJECT, false);
+ }
+ return decodeAsObject;
+ }
+
+ private static String clientEncodingDefault() {
+ if (defaultRequestEncoding == null) {
+ defaultRequestEncoding = LegacyPropertyFactory
+ .getStringProperty(PARAM_DEFAULT_REQUEST_ENCODING,
MediaType.APPLICATION_JSON);
+ }
+ return defaultRequestEncoding;
+ }
}
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
index 36b9a8c3e..7182aff20 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.http.entity.ContentType;
import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.common.LegacyPropertyFactory;
import org.apache.servicecomb.foundation.common.RegisterManager;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.swagger.generator.SwaggerConst;
@@ -45,6 +46,10 @@ public final class ProduceProcessorManager extends
RegisterManager<String, Map<S
public static final ProduceProcessorManager INSTANCE = new
ProduceProcessorManager();
+ public static final String PARAM_DEFAULT_RESPONSE_ENCODING =
"servicecomb.rest.parameter.default-response-encoding";
+
+ private static String defaultResponseEncoding;
+
private final Map<String, ProduceProcessor> jsonProcessorMap;
private final Map<String, ProduceProcessor> plainProcessorMap;
@@ -77,6 +82,14 @@ public final class ProduceProcessorManager extends
RegisterManager<String, Map<S
return produceViewMap.get(DEFAULT_SERIAL_CLASS);
}
+ private static String defaultResponseEncoding() {
+ if (defaultResponseEncoding == null) {
+ defaultResponseEncoding = LegacyPropertyFactory
+ .getStringProperty(PARAM_DEFAULT_RESPONSE_ENCODING,
MediaType.APPLICATION_JSON);
+ }
+ return defaultResponseEncoding;
+ }
+
public ProduceProcessor findJsonProcessorByViewClass(Class<?>
serialViewClass) {
if (serialViewClass == null) {
return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);
@@ -115,8 +128,8 @@ public final class ProduceProcessorManager extends
RegisterManager<String, Map<S
}
String actualAccept = accept;
if (actualAccept == null) {
- if (response.getContent().get(MediaType.APPLICATION_JSON) != null) {
- actualAccept = MediaType.APPLICATION_JSON;
+ if (response.getContent().get(defaultResponseEncoding()) != null) {
+ actualAccept = defaultResponseEncoding();
} else {
actualAccept = response.getContent().keySet().iterator().next();
}
@@ -125,8 +138,8 @@ public final class ProduceProcessorManager extends
RegisterManager<String, Map<S
actualAccept = contentType.getMimeType();
if (MediaType.WILDCARD.equals(contentType.getMimeType()) ||
MediaType.MEDIA_TYPE_WILDCARD.equals(contentType.getMimeType())) {
- if (response.getContent().get(MediaType.APPLICATION_JSON) != null) {
- actualAccept = MediaType.APPLICATION_JSON;
+ if (response.getContent().get(defaultResponseEncoding()) != null) {
+ actualAccept = defaultResponseEncoding();
} else {
actualAccept = response.getContent().keySet().iterator().next();
}
@@ -135,14 +148,14 @@ public final class ProduceProcessorManager extends
RegisterManager<String, Map<S
LOGGER.warn("Operation do not support accept type {}/{}", accept,
actualAccept);
return findDefaultProcessor();
}
+ if (MediaType.APPLICATION_JSON.equals(actualAccept)) {
+ return findJsonProcessorByViewClass(serialViewClass);
+ }
if (SwaggerConst.PROTOBUF_TYPE.equals(actualAccept)) {
return new ProduceProtoBufferProcessor(operationMeta,
operationMeta.getSchemaMeta().getSwagger(),
response.getContent().get(actualAccept).getSchema());
}
- if (MediaType.TEXT_PLAIN.equals(actualAccept)) {
- return findPlainProcessorByViewClass(serialViewClass);
- }
- // json
- return findJsonProcessorByViewClass(serialViewClass);
+ // text plain
+ return findPlainProcessorByViewClass(serialViewClass);
}
}
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
index 42e2db348..259095e6a 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
@@ -23,8 +23,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
import
org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.PartProcessor;
import org.apache.servicecomb.common.rest.definition.path.PathRegExp;
import org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;
@@ -35,18 +33,12 @@ import
org.apache.servicecomb.swagger.generator.SwaggerConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
-import io.swagger.v3.oas.models.media.MapSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
-import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
-import jakarta.ws.rs.core.MediaType;
@SuppressWarnings("rawtypes")
public class RestOperationMeta {
@@ -112,7 +104,6 @@ public class RestOperationMeta {
private void addRestParamByName(OperationMeta operationMeta, String name,
Operation operation) {
Type type = operationMeta.getSwaggerProducerOperation() != null ?
operationMeta.getSwaggerProducerOperation()
.getSwaggerParameterTypes().get(name) : null;
- type = correctFormBodyType(operation.getRequestBody(), type);
RestParam param = new RestParam(operationMeta, name,
operation.getRequestBody(), formData, type);
addParam(param);
}
@@ -129,35 +120,6 @@ public class RestOperationMeta {
return
operation.getRequestBody().getContent().get(SwaggerConst.FILE_MEDIA_TYPE).getSchema();
}
- /**
- * EdgeService cannot recognize the map type form body whose value type is
String,
- * so there should be this additional setting.
- * @param parameter the swagger information of the parameter
- * @param type the resolved param type
- * @return the corrected param type
- */
- private Type correctFormBodyType(RequestBody parameter, Type type) {
- if (null != type || parameter == null) {
- return type;
- }
- if (parameter.getContent().get(MediaType.APPLICATION_JSON) == null
- ||
!(parameter.getContent().get(MediaType.APPLICATION_JSON).getSchema() instanceof
MapSchema)) {
- return null;
- }
- String className = SwaggerUtils.getClassName(parameter.getExtensions());
- if (!StringUtils.isEmpty(className)) {
- try {
- JavaType javaType =
TypeFactory.defaultInstance().constructFromCanonical(className);
- return RestObjectMapperFactory.getRestObjectMapper().getTypeFactory()
- .constructMapType(Map.class, String.class, javaType.getRawClass());
- } catch (Throwable e) {
- // ignore
- }
- }
- return RestObjectMapperFactory.getRestObjectMapper().getTypeFactory()
- .constructMapType(Map.class, String.class, Object.class);
- }
-
public boolean isDownloadFile() {
return downloadFile;
}
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/MultiErrorCodeServiceClient.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/MultiErrorCodeServiceClient.java
index 104e5b8e4..5eba5b94c 100644
---
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/MultiErrorCodeServiceClient.java
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/MultiErrorCodeServiceClient.java
@@ -70,7 +70,6 @@ public class MultiErrorCodeServiceClient implements
CategorizedTestCase {
headers.setContentType(MediaType.APPLICATION_JSON);
String body = "{\"message\":\"hello\",\"code\":\"wrongType\"";
HttpEntity<String> entity = new HttpEntity<>(body, headers);
- ResponseEntity<MultiResponse200> result;
try {
template
.postForEntity(SERVER + "/MultiErrorCodeService/errorCode", entity,
MultiResponse200.class);
@@ -83,7 +82,7 @@ public class MultiErrorCodeServiceClient implements
CategorizedTestCase {
try {
template
.postForEntity(SERVER + "/MultiErrorCodeService/errorCode", entity,
MultiResponse200.class);
- TestMgr.check(590, 200);
+ TestMgr.fail("expect failed.");
} catch (InvocationException e) {
TestMgr.check(e.getStatusCode(), 400);
}
@@ -94,7 +93,7 @@ public class MultiErrorCodeServiceClient implements
CategorizedTestCase {
try {
template
.postForEntity(SERVER + "/MultiErrorCodeService/errorCode", entity,
MultiResponse200.class);
- TestMgr.check(590, 200);
+ TestMgr.fail("expect failed.");
} catch (InvocationException e) {
TestMgr.check(e.getStatusCode(), 400);
}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
index 3beaa0074..331c6b632 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
@@ -55,15 +55,14 @@ public abstract class SchemaManager {
// key is canonical message name + ":" + canonical type name
protected final Map<String, SchemaEx<?>> canonicalSchemas = new
ConcurrentHashMapEx<>();
+ // key is canonical message name + ":" + canonical type name
+ protected final Map<String, SchemaEx<?>> canonicalSchemasCreated = new
ConcurrentHashMapEx<>();
+
public SchemaManager(ProtoMapper protoMapper) {
this.protoMapper = protoMapper;
this.proto = protoMapper.getProto();
}
- public Map<String, SchemaEx<?>> getCanonicalSchemas() {
- return canonicalSchemas;
- }
-
protected String generateCacheKey(Message message, JavaType javaType) {
return message.getCanonicalName() + ":" + javaType.toCanonical();
}
@@ -72,44 +71,25 @@ public abstract class SchemaManager {
protected abstract <T> SchemaEx<T> newMessageSchema(Message message,
Map<String, Type> types);
- /**
- *
- * @param protoField
- * @param propertyDescriptor provide getter/setter/javaType
- * @return
- */
protected abstract <T> FieldSchema<T> createScalarField(Field protoField,
PropertyDescriptor propertyDescriptor);
@SuppressWarnings("unchecked")
protected <T> SchemaEx<T> getOrCreateMessageSchema(Message message,
Map<String, Type> types) {
String cacheKey = generateCacheKey(message, ProtoConst.MAP_TYPE);
- SchemaEx<T> messageSchema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);
- if (messageSchema == null) {
- // messageSchema already put into canonicalSchemas inside
createMessageSchema
- messageSchema = createMessageSchema(message, types);
- }
- return messageSchema;
+ return (SchemaEx<T>) canonicalSchemasCreated.computeIfAbsent(cacheKey, key
-> createMessageSchema(message, types));
}
@SuppressWarnings("unchecked")
protected <T> SchemaEx<T> getOrCreateMessageSchema(Message message, JavaType
javaType) {
String cacheKey = generateCacheKey(message, javaType);
- SchemaEx<T> messageSchema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);
- if (messageSchema == null) {
- // messageSchema already put into canonicalSchemas inside
createMessageSchema
- messageSchema = createMessageSchema(message, javaType);
- }
- return messageSchema;
+ return (SchemaEx<T>) canonicalSchemasCreated.computeIfAbsent(cacheKey,
+ key -> createMessageSchema(message, javaType));
}
@SuppressWarnings("unchecked")
- protected <T> SchemaEx<T> findSchema(String key) {
- return (SchemaEx<T>) canonicalSchemas.get(key);
- }
-
protected <T> SchemaEx<T> createMessageSchema(Message message, Map<String,
Type> types) {
String cacheKey = generateCacheKey(message, ProtoConst.MAP_TYPE);
- SchemaEx<T> schema = findSchema(cacheKey);
+ SchemaEx<T> schema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);
if (schema != null) {
return schema;
}
@@ -121,9 +101,10 @@ public abstract class SchemaManager {
return schema;
}
+ @SuppressWarnings("unchecked")
protected <T> SchemaEx<T> createMessageSchema(Message message, JavaType
javaType) {
String cacheKey = generateCacheKey(message, javaType);
- SchemaEx<T> schema = findSchema(cacheKey);
+ SchemaEx<T> schema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);
if (schema != null) {
return schema;
}
@@ -144,7 +125,7 @@ public abstract class SchemaManager {
JavaType entryType =
TypeFactory.defaultInstance().constructParametricType(MapEntry.class,
javaType.getKeyType(),
javaType.getContentType());
- SchemaEx<Entry<Object, Object>> entrySchema =
getOrCreateMessageSchema((Message) protoField.getType(),
+ SchemaEx<Entry<Object, Object>> entrySchema =
createMessageSchema((Message) protoField.getType(),
entryType);
return new MapSchema<>(protoField, propertyDescriptor, entrySchema);
}
@@ -215,7 +196,7 @@ public abstract class SchemaManager {
// message
if (protoField.getType().isMessage()) {
- SchemaEx<Object> messageSchema = getOrCreateMessageSchema((Message)
protoField.getType(),
+ SchemaEx<Object> messageSchema = createMessageSchema((Message)
protoField.getType(),
propertyDescriptor.getJavaType());
if (isWrapProperty((Message) protoField.getType())) {
return new PropertyWrapperAsFieldSchema<>(protoField,
propertyDescriptor, messageSchema);
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
index a86d2aa4f..23b9d85a0 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
@@ -249,7 +249,7 @@ public class DeserializerSchemaManager extends
SchemaManager {
if (contentType == null) {
contentType = ProtoConst.OBJECT_TYPE;
}
- SchemaEx<Object> contentSchema = getOrCreateMessageSchema((Message)
protoField.getType(), contentType);
+ SchemaEx<Object> contentSchema = createMessageSchema((Message)
protoField.getType(), contentType);
if (isWrapProperty((Message) protoField.getType())) {
return PropertyWrapperRepeatedReadSchemas.create(protoField,
propertyDescriptor, contentSchema);
}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
index 49b2154cb..ccab4d81f 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
@@ -101,6 +101,8 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
@Override
public void init() {
+ this.mapFieldMaps =
protoMapper.getSerializerSchemaManager().createMapFields(message);
+
if (ProtoUtils.isWrapProperty(message)) {
this.mainPojoFieldMaps = createPropertyWrapperFields(javaType);
return;
@@ -178,10 +180,6 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
}
protected final void writeFromMap(OutputEx output, Map<String, Object> map)
throws IOException {
- if (mapFieldMaps == null) {
- mapFieldMaps =
protoMapper.getSerializerSchemaManager().createMapFields(message);
- }
-
for (Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() == null) {
continue;
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
index 97ea2af2b..d63944e34 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
@@ -226,7 +226,7 @@ public class SerializerSchemaManager extends SchemaManager {
if (contentType == null) {
contentType = ProtoConst.OBJECT_TYPE;
}
- SchemaEx<Object> contentSchema = getOrCreateMessageSchema((Message)
protoField.getType(), contentType);
+ SchemaEx<Object> contentSchema = createMessageSchema((Message)
protoField.getType(), contentType);
if (isWrapProperty((Message) protoField.getType())) {
return PropertyWrapperRepeatedWriteSchemas.create(protoField,
propertyDescriptor, contentSchema);
}