com.rabbitmq.tools.jsonrpc.JacksonJsonRpcMapper Maven / Gradle / Ivy
Show all versions of amqp-client Show documentation
// Copyright (c) 2018-2023 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
//
// This software, the RabbitMQ Java client library, is triple-licensed under the
// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
// please see LICENSE-APACHE2.
//
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
// either express or implied. See the LICENSE file for specific language governing
// rights and limitations of this software.
//
// If you have any questions regarding licensing, please contact us at
// [email protected].
package com.rabbitmq.tools.jsonrpc;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ValueNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* {@link JsonRpcMapper} based on Jackson.
*
* Uses the streaming and databind modules. You need to add the appropriate dependency
* to the classpath if you want to use this class, as the RabbitMQ Java client
* library does not pull Jackson automatically when using a dependency management
* tool like Maven or Gradle.
*
* Make sure to use the latest version of the Jackson library, as the version used in the
* RabbitMQ Java client can be a little bit behind.
*
* @see JsonRpcMapper
* @since 5.4.0
*/
public class JacksonJsonRpcMapper implements JsonRpcMapper {
private static final Logger LOGGER = LoggerFactory.getLogger(JacksonJsonRpcMapper.class);
private final ObjectMapper mapper;
public JacksonJsonRpcMapper(ObjectMapper mapper) {
this.mapper = mapper;
}
public JacksonJsonRpcMapper() {
this(new ObjectMapper());
}
@Override
public JsonRpcRequest parse(String requestBody, ServiceDescription description) {
JsonFactory jsonFactory = new MappingJsonFactory();
String method = null, version = null;
final List parameters = new ArrayList<>();
Object id = null;
try (JsonParser parser = jsonFactory.createParser(requestBody)) {
while (parser.nextToken() != null) {
JsonToken token = parser.currentToken();
if (token == JsonToken.FIELD_NAME) {
String name = parser.currentName();
token = parser.nextToken();
if ("method".equals(name)) {
method = parser.getValueAsString();
} else if ("id".equals(name)) {
TreeNode node = parser.readValueAsTree();
if (node instanceof ValueNode) {
ValueNode idNode = (ValueNode) node;
if (idNode.isNull()) {
id = null;
} else if (idNode.isTextual()) {
id = idNode.asText();
} else if (idNode.isNumber()) {
id = Long.valueOf(idNode.asLong());
} else {
LOGGER.warn("ID type not null, text, or number {}, ignoring", idNode);
}
} else {
LOGGER.warn("ID not a scalar value {}, ignoring", node);
}
} else if ("version".equals(name)) {
version = parser.getValueAsString();
} else if ("params".equals(name)) {
if (token == JsonToken.START_ARRAY) {
while (parser.nextToken() != JsonToken.END_ARRAY) {
parameters.add(parser.readValueAsTree());
}
} else {
throw new IllegalStateException("Field params must be an array");
}
}
}
}
} catch (IOException e) {
throw new JsonRpcMappingException("Error during JSON parsing", e);
}
if (method == null) {
throw new IllegalArgumentException("Could not find method to invoke in request");
}
List