@Override
    public ObjectNode encode(FlowRule flowRule, CodecContext context) {
        checkNotNull(flowRule, "Flow rule cannot be null");

        CoreService service = context.getService(CoreService.class);
        ApplicationId appId = service.getAppId(flowRule.appId());
        String strAppId = (appId == null) ? "<none>" : appId.name();

        final ObjectNode result = context.mapper().createObjectNode()
                .put(ID, Long.toString(flowRule.id().value()))
                .put(APP_ID, strAppId)
                .put(PRIORITY, flowRule.priority())
                .put(TIMEOUT, flowRule.timeout())
                .put(IS_PERMANENT, flowRule.isPermanent())
                .put(DEVICE_ID, flowRule.deviceId().toString())
                .put(TABLE_ID, flowRule.tableId())
                .put(TABLE_NAME, flowRule.table().toString());

        if (flowRule.treatment() != null) {
            final JsonCodec<TrafficTreatment> treatmentCodec =
                    context.codec(TrafficTreatment.class);
            result.set(TREATMENT, treatmentCodec.encode(flowRule.treatment(), context));
        }

        if (flowRule.selector() != null) {
            final JsonCodec<TrafficSelector> selectorCodec =
                    context.codec(TrafficSelector.class);
            result.set(SELECTOR, selectorCodec.encode(flowRule.selector(), context));
        }

        return result;
    }
@Test
    public void testFlowRuleEncode() {

        DeviceId deviceId = DeviceId.deviceId("of:000000000000000a");

        Instruction output = Instructions.createOutput(PortNumber.portNumber(0));
        Instruction modL2Src = Instructions.modL2Src(MacAddress.valueOf("11:22:33:44:55:66"));
        Instruction modL2Dst = Instructions.modL2Dst(MacAddress.valueOf("44:55:66:77:88:99"));
        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
        TrafficTreatment treatment = tBuilder
                .add(output)
                .add(modL2Src)
                .add(modL2Dst)
                .build();

        Criterion inPort = Criteria.matchInPort(PortNumber.portNumber(0));
        Criterion ethSrc = Criteria.matchEthSrc(MacAddress.valueOf("11:22:33:44:55:66"));
        Criterion ethDst = Criteria.matchEthDst(MacAddress.valueOf("44:55:66:77:88:99"));
        Criterion ethType = Criteria.matchEthType(Ethernet.TYPE_IPV4);

        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
        TrafficSelector selector = sBuilder
                .add(inPort)
                .add(ethSrc)
                .add(ethDst)
                .add(ethType)
                .build();

        FlowRule permFlowRule = DefaultFlowRule.builder()
                                                    .withCookie(1)
                                                    .forTable(1)
                                                    .withPriority(1)
                                                    .makePermanent()
                                                    .withTreatment(treatment)
                                                    .withSelector(selector)
                                                    .forDevice(deviceId).build();

        FlowRule tempFlowRule =  DefaultFlowRule.builder()
                                                .withCookie(1)
                                                .forTable(1)
                                                .withPriority(1)
                                                .makeTemporary(1000)
                                                .withTreatment(treatment)
                                                .withSelector(selector)
                                                .forDevice(deviceId).build();

        ObjectNode permFlowRuleJson = flowRuleCodec.encode(permFlowRule, context);
        ObjectNode tempFlowRuleJson = flowRuleCodec.encode(tempFlowRule, context);

        assertThat(permFlowRuleJson, FlowRuleJsonMatcher.matchesFlowRule(permFlowRule));
        assertThat(tempFlowRuleJson, FlowRuleJsonMatcher.matchesFlowRule(tempFlowRule));
    }