@Override
    public FlowEntry decode(ObjectNode json, CodecContext context) {
        checkNotNull(json, "JSON object cannot be null");

        // decode FlowRule-specific fields using the FlowRule codec
        FlowRule flowRule = context.codec(FlowRule.class).decode(json, context);

        JsonNode stateNode = json.get(STATE);
        FlowEntry.FlowEntryState state = (null == stateNode) ?
                FlowEntry.FlowEntryState.ADDED : FlowEntry.FlowEntryState.valueOf(stateNode.asText());

        JsonNode lifeNode = json.get(LIFE);
        long life = (null == lifeNode) ? 0 : lifeNode.asLong();

        JsonNode liveTypeNode = json.get(LIVE_TYPE);
        FlowEntry.FlowLiveType liveType = (null == liveTypeNode) ?
                FlowEntry.FlowLiveType.UNKNOWN : FlowEntry.FlowLiveType.valueOf(liveTypeNode.asText());

        JsonNode packetsNode = json.get(PACKETS);
        long packets = (null == packetsNode) ? 0 : packetsNode.asLong();

        JsonNode bytesNode = json.get(BYTES);
        long bytes = (null == bytesNode) ? 0 : bytesNode.asLong();

        return new DefaultFlowEntry(flowRule, state, life,
                                    liveType, packets, bytes);
    }
@Test
    public void testDecode() throws IOException {
        InputStream jsonStream = FlowEntryCodec.class.getResourceAsStream(JSON_FILE);
        JsonNode jsonString = context.mapper().readTree(jsonStream);

        FlowEntry expected = flowEntryCodec.decode((ObjectNode) jsonString, context);
        assertEquals(expected, FLOW_ENTRY);
    }