*/
public class JsonRpcDecoder extends ByteToMessageDecoder {
- protected static final Logger logger = LoggerFactory.getLogger(JsonRpcDecoder.class);
-
+ private static final Logger LOG = LoggerFactory.getLogger(JsonRpcDecoder.class);
private int maxFrameLength;
-
+ //Indicates if the frame limit warning was issued
+ private boolean maxFrameLimitWasReached = false;
private JsonFactory jacksonJsonFactory = new MappingJsonFactory();
private IOContext jacksonIOContext = new IOContext(new BufferRecycler(), null, false);
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
- logger.trace("readable bytes {}, records read {}, incomplete record bytes {}",
+ LOG.trace("readable bytes {}, records read {}, incomplete record bytes {}",
buf.readableBytes(), recordsRead, lastRecordBytes);
if (lastRecordBytes == 0) {
}
}
- int i = lastRecordBytes + buf.readerIndex();
+ int index = lastRecordBytes + buf.readerIndex();
- for (; i < buf.writerIndex(); i++) {
- switch (buf.getByte(i)) {
+ for (; index < buf.writerIndex(); index++) {
+ switch (buf.getByte(index)) {
case '{':
- if (!inS) leftCurlies++;
+ if (!inS) {
+ leftCurlies++;
+ }
break;
case '}':
- if (!inS) rightCurlies++;
+ if (!inS) {
+ rightCurlies++;
+ }
break;
- case '"': {
- if (buf.getByte(i - 1) != '\\') inS = !inS;
+ case '"':
+ if (buf.getByte(index - 1) != '\\') {
+ inS = !inS;
+ }
+ break;
+ default:
break;
- }
}
if (leftCurlies != 0 && leftCurlies == rightCurlies && !inS) {
- ByteBuf slice = buf.readSlice(1 + i - buf.readerIndex());
+ ByteBuf slice = buf.readSlice(1 + index - buf.readerIndex());
JsonParser jp = jacksonJsonFactory.createParser(new ByteBufInputStream(slice));
JsonNode root = jp.readValueAsTree();
out.add(root);
break;
}
- if (i - buf.readerIndex() >= maxFrameLength) {
- fail(ctx, i - buf.readerIndex());
+ if (index - buf.readerIndex() >= maxFrameLength) {
+ /*
+ * Changing this limit to being a warning, we do not wish to "break" in scale environment
+ * and currently this limits the ovs of having only around 50 ports defined...
+ * I do acknowledge the fast that this might be risky in case of huge amount of strings
+ * in which the controller can crash with an OOM, however seems that we need a really huge
+ * ovs to reach that limit.
+ */
+
+ //We do not want to issue a log message on every extent of the buffer
+ //hence logging only once
+ if (!maxFrameLimitWasReached) {
+ maxFrameLimitWasReached = true;
+ LOG.warn("***** OVSDB Frame limit of {} bytes has been reached! *****", this.maxFrameLength);
+ }
}
}
// end of stream, save the incomplete record index to avoid reexamining the whole on next run
- if (i >= buf.writerIndex()) {
+ if (index >= buf.writerIndex()) {
lastRecordBytes = buf.readableBytes();
return;
}
return recordsRead;
}
- private static void skipSpaces(ByteBuf b) throws IOException {
- while (b.isReadable()) {
- int ch = b.getByte(b.readerIndex()) & 0xFF;
+ private static void skipSpaces(ByteBuf byteBuf) throws IOException {
+ while (byteBuf.isReadable()) {
+ int ch = byteBuf.getByte(byteBuf.readerIndex()) & 0xFF;
if (!(ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t')) {
return;
} else {
- b.readByte(); //move the read index
+ byteBuf.readByte(); //move the read index
}
}
}
}
private void print(ByteBuf buf, int startPos, int chars, String message) {
- if (null == message) message = "";
+ if (null == message) {
+ message = "";
+ }
if (startPos > buf.writerIndex()) {
- logger.trace("startPos out of bounds");
+ LOG.trace("startPos out of bounds");
}
- byte[] b = new byte[startPos + chars <= buf.writerIndex() ? chars : buf.writerIndex() - startPos];
- buf.getBytes(startPos, b);
- logger.trace("{} ={}", message, new String(b));
+ byte[] bytes = new byte[startPos + chars <= buf.writerIndex() ? chars : buf.writerIndex() - startPos];
+ buf.getBytes(startPos, bytes);
+ LOG.trace("{} ={}", message, new String(bytes));
}
// copied from Netty decoder
if (frameLength > 0) {
ctx.fireExceptionCaught(
new TooLongFrameException(
- "frame length exceeds " + maxFrameLength +
- ": " + frameLength + " - discarded"));
+ "frame length exceeds " + maxFrameLength + ": " + frameLength + " - discarded"));
} else {
ctx.fireExceptionCaught(
new TooLongFrameException(
- "frame length exceeds " + maxFrameLength +
- " - discarding"));
+ "frame length exceeds " + maxFrameLength + " - discarding"));
}
}
}