org.opendaylight.ovsdb.lib.jsonrpc.JsonRpcDecoder Maven / Gradle / Ivy
/*
* Copyright (c) 2013, 2017 EBay Software Foundation and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.ovsdb.lib.jsonrpc;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper;
import com.fasterxml.jackson.core.util.BufferRecycler;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.opendaylight.ovsdb.lib.error.InvalidEncodingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JSON RPC 1.0 compatible decoder capable of decoding JSON messages from a TCP stream.
* The stream is framed first by inspecting the json for valid end marker (left curly)
* and is passed to a Json parser (jackson) for converting into an object model.
*
* There are no JSON parsers that I am aware of that does non blocking parsing.
* This approach avoids having to run json parser over and over again on the entire
* stream waiting for input. Parser is invoked only when we know of a full JSON message
* in the stream.
*/
public class JsonRpcDecoder extends ByteToMessageDecoder {
private static final Logger LOG = LoggerFactory.getLogger(JsonRpcDecoder.class);
private static final JsonFactory JSON_FACTORY = new MappingJsonFactory();
private final int maxFrameLength;
//Indicates if the frame limit warning was issued
private boolean maxFrameLimitWasReached = false;
private final IOContext jacksonIOContext = new IOContext(new BufferRecycler(), (Object) null, false);
// context for the previously read incomplete records
private int lastRecordBytes = 0;
private int leftCurlies = 0;
private int rightCurlies = 0;
private boolean inS = false;
private int recordsRead;
public JsonRpcDecoder(final int maxFrameLength) {
this.maxFrameLength = maxFrameLength;
}
@Override
protected void decode(final ChannelHandlerContext ctx, final ByteBuf buf, final List