/* * Copyright 2015-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.codec.impl; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.hamcrest.Description; import org.hamcrest.TypeSafeDiagnosingMatcher; import org.junit.Before; import org.junit.Test; import org.onlab.packet.EthType; import org.onlab.packet.Ethernet; import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onlab.packet.MplsLabel; import org.onlab.packet.VlanId; import org.onosproject.codec.JsonCodec; import org.onosproject.core.CoreService; import org.onosproject.net.ChannelSpacing; import org.onosproject.net.DeviceId; import org.onosproject.net.GridType; import org.onosproject.net.Lambda; import org.onosproject.net.OchSignal; import org.onosproject.net.OchSignalType; import org.onosproject.net.OduSignalType; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultFlowRule; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.FlowRule; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.criteria.Criterion; import org.onosproject.net.flow.criteria.EthCriterion; import org.onosproject.net.flow.criteria.EthTypeCriterion; import org.onosproject.net.flow.criteria.IPCriterion; import org.onosproject.net.flow.criteria.IPDscpCriterion; import org.onosproject.net.flow.criteria.IPEcnCriterion; import org.onosproject.net.flow.criteria.IPProtocolCriterion; import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion; import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion; import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion; import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion; import org.onosproject.net.flow.criteria.IcmpCodeCriterion; import org.onosproject.net.flow.criteria.IcmpTypeCriterion; import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion; import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion; import org.onosproject.net.flow.criteria.MplsCriterion; import org.onosproject.net.flow.criteria.OchSignalCriterion; import org.onosproject.net.flow.criteria.OchSignalTypeCriterion; import org.onosproject.net.flow.criteria.OduSignalIdCriterion; import org.onosproject.net.flow.criteria.OduSignalTypeCriterion; import org.onosproject.net.flow.criteria.PortCriterion; import org.onosproject.net.flow.criteria.SctpPortCriterion; import org.onosproject.net.flow.criteria.TcpPortCriterion; import org.onosproject.net.flow.criteria.TunnelIdCriterion; import org.onosproject.net.flow.criteria.UdpPortCriterion; import org.onosproject.net.flow.criteria.VlanIdCriterion; import org.onosproject.net.flow.criteria.VlanPcpCriterion; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.Instructions; import org.onosproject.net.flow.instructions.L0ModificationInstruction; import org.onosproject.net.flow.instructions.L2ModificationInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction; import org.onosproject.net.flow.instructions.L4ModificationInstruction; import java.io.IOException; import java.io.InputStream; import java.util.SortedMap; import java.util.TreeMap; import static org.easymock.EasyMock.anyShort; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.onosproject.net.NetTestTools.APP_ID; /** * Flow rule codec unit tests. */ public class FlowRuleCodecTest { MockCodecContext context; JsonCodec<FlowRule> flowRuleCodec; final CoreService mockCoreService = createMock(CoreService.class); /** * Sets up for each test. Creates a context and fetches the flow rule * codec. */ @Before public void setUp() { context = new MockCodecContext(); flowRuleCodec = context.codec(FlowRule.class); assertThat(flowRuleCodec, notNullValue()); expect(mockCoreService.registerApplication(FlowRuleCodec.REST_APP_ID)) .andReturn(APP_ID).anyTimes(); expect(mockCoreService.getAppId(anyShort())).andReturn(APP_ID).anyTimes(); replay(mockCoreService); context.registerService(CoreService.class, mockCoreService); } /** * Reads in a rule from the given resource and decodes it. * * @param resourceName resource to use to read the JSON for the rule * @return decoded flow rule * @throws IOException if processing the resource fails */ private FlowRule getRule(String resourceName) throws IOException { InputStream jsonStream = FlowRuleCodecTest.class .getResourceAsStream(resourceName); JsonNode json = context.mapper().readTree(jsonStream); assertThat(json, notNullValue()); FlowRule rule = flowRuleCodec.decode((ObjectNode) json, context); assertThat(rule, notNullValue()); return rule; } /** * Checks that the data shared by all the resources is correct for a * given rule. * * @param rule rule to check */ private void checkCommonData(FlowRule rule) { assertThat(rule.appId(), is(APP_ID.id())); assertThat(rule.isPermanent(), is(false)); assertThat(rule.timeout(), is(1)); assertThat(rule.priority(), is(1)); assertThat(rule.tableId(), is(1)); assertThat(rule.deviceId().toString(), is("of:0000000000000001")); } /** * Checks that a simple rule decodes properly. * * @throws IOException if the resource cannot be processed */ @Test public void codecSimpleFlowTest() throws IOException { FlowRule rule = getRule("simple-flow.json"); checkCommonData(rule); assertThat(rule.selector().criteria().size(), is(1)); Criterion criterion1 = rule.selector().criteria().iterator().next(); assertThat(criterion1.type(), is(Criterion.Type.ETH_TYPE)); assertThat(((EthTypeCriterion) criterion1).ethType(), is(new EthType(2054))); assertThat(rule.treatment().allInstructions().size(), is(1)); Instruction instruction1 = rule.treatment().allInstructions().get(0); assertThat(instruction1.type(), is(Instruction.Type.OUTPUT)); assertThat(((Instructions.OutputInstruction) instruction1).port(), is(PortNumber.CONTROLLER)); } SortedMap<String, Instruction> instructions = new TreeMap<>(); /** * Checks that a simple rule encodes properly. */ @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)); } private static final class FlowRuleJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> { private final FlowRule flowRule; private FlowRuleJsonMatcher(FlowRule flowRule) { this.flowRule = flowRule; } @Override protected boolean matchesSafely(JsonNode jsonNode, Description description) { // check id long jsonId = jsonNode.get("id").asLong(); long id = flowRule.id().id(); if (jsonId != id) { description.appendText("flow rule id was " + jsonId); return false; } // TODO: need to check application ID // check tableId int jsonTableId = jsonNode.get("tableId").asInt(); int tableId = flowRule.tableId(); if (jsonTableId != tableId) { description.appendText("table id was " + jsonId); return false; } // check priority int jsonPriority = jsonNode.get("priority").asInt(); int priority = flowRule.priority(); if (jsonPriority != priority) { description.appendText("priority was " + jsonPriority); return false; } // check timeout int jsonTimeout = jsonNode.get("timeout").asInt(); int timeout = flowRule.timeout(); if (jsonTimeout != timeout) { description.appendText("timeout was " + jsonTimeout); return false; } // check isPermanent boolean jsonIsPermanent = jsonNode.get("isPermanent").asBoolean(); boolean isPermanent = flowRule.isPermanent(); if (jsonIsPermanent != isPermanent) { description.appendText("isPermanent was " + jsonIsPermanent); return false; } // check deviceId String jsonDeviceId = jsonNode.get("deviceId").asText(); String deviceId = flowRule.deviceId().toString(); if (!jsonDeviceId.equals(deviceId)) { description.appendText("deviceId was " + jsonDeviceId); return false; } // check traffic treatment JsonNode jsonTreatment = jsonNode.get("treatment"); TrafficTreatmentCodecTest.TrafficTreatmentJsonMatcher treatmentMatcher = TrafficTreatmentCodecTest.TrafficTreatmentJsonMatcher .matchesTrafficTreatment(flowRule.treatment()); if (!treatmentMatcher.matches(jsonTreatment)) { description.appendText("treatment is not matched"); return false; } // check traffic selector JsonNode jsonSelector = jsonNode.get("selector"); TrafficSelectorCodecTest.TrafficSelectorJsonMatcher selectorMatcher = TrafficSelectorCodecTest.TrafficSelectorJsonMatcher .matchesTrafficSelector(flowRule.selector()); if (!selectorMatcher.matches(jsonSelector)) { description.appendText("selector is not matched"); return false; } return true; } @Override public void describeTo(Description description) { description.appendText(flowRule.toString()); } /** * Factory to allocate a flow rule matcher. * * @param flowRule flow rule object we are looking for * @return matcher */ public static FlowRuleJsonMatcher matchesFlowRule(FlowRule flowRule) { return new FlowRuleJsonMatcher(flowRule); } } /** * Looks up an instruction in the instruction map based on type and subtype. * * @param type type string * @param subType subtype string * @return instruction that matches */ private Instruction getInstruction(Instruction.Type type, String subType) { Instruction instruction = instructions.get(type.name() + "/" + subType); assertThat(instruction, notNullValue()); assertThat(instruction.type(), is(type)); return instruction; } /** * Checks that a rule with one of each instruction type decodes properly. * * @throws IOException if the resource cannot be processed */ @Test public void decodeInstructionsFlowTest() throws Exception { FlowRule rule = getRule("instructions-flow.json"); checkCommonData(rule); rule.treatment().allInstructions() .forEach(instruction -> { String subType; if (instruction.type() == Instruction.Type.L0MODIFICATION) { subType = ((L0ModificationInstruction) instruction) .subtype().name(); } else if (instruction.type() == Instruction.Type.L2MODIFICATION) { subType = ((L2ModificationInstruction) instruction) .subtype().name(); } else if (instruction.type() == Instruction.Type.L3MODIFICATION) { subType = ((L3ModificationInstruction) instruction) .subtype().name(); } else if (instruction.type() == Instruction.Type.L4MODIFICATION) { subType = ((L4ModificationInstruction) instruction) .subtype().name(); } else { subType = ""; } instructions.put( instruction.type().name() + "/" + subType, instruction); }); assertThat(rule.treatment().allInstructions().size(), is(23)); Instruction instruction; instruction = getInstruction(Instruction.Type.OUTPUT, ""); assertThat(instruction.type(), is(Instruction.Type.OUTPUT)); assertThat(((Instructions.OutputInstruction) instruction).port(), is(PortNumber.CONTROLLER)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.ETH_SRC.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(), is(MacAddress.valueOf("12:34:56:78:90:12"))); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.ETH_DST.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModEtherInstruction) instruction).mac(), is(MacAddress.valueOf("98:76:54:32:01:00"))); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_ID.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModVlanIdInstruction) instruction).vlanId().toShort(), is((short) 22)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_PCP.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModVlanPcpInstruction) instruction).vlanPcp(), is((byte) 1)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.MPLS_LABEL.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModMplsLabelInstruction) instruction) .label().toInt(), is(MplsLabel.MAX_MPLS)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.MPLS_PUSH.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModMplsHeaderInstruction) instruction) .ethernetType().toShort(), is(Ethernet.MPLS_UNICAST)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.MPLS_POP.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModMplsHeaderInstruction) instruction) .ethernetType().toShort(), is(Ethernet.MPLS_UNICAST)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.DEC_MPLS_TTL.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(instruction, instanceOf(L2ModificationInstruction.ModMplsTtlInstruction.class)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_POP.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(instruction, instanceOf(L2ModificationInstruction.ModVlanHeaderInstruction.class)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.VLAN_PUSH.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(instruction, instanceOf(L2ModificationInstruction.ModVlanHeaderInstruction.class)); instruction = getInstruction(Instruction.Type.L2MODIFICATION, L2ModificationInstruction.L2SubType.TUNNEL_ID.name()); assertThat(instruction.type(), is(Instruction.Type.L2MODIFICATION)); assertThat(((L2ModificationInstruction.ModTunnelIdInstruction) instruction) .tunnelId(), is(100L)); instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV4_SRC.name()); assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION)); assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.4"))); instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV4_DST.name()); assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION)); assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.3"))); instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV6_SRC.name()); assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION)); assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.2"))); instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV6_DST.name()); assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION)); assertThat(((L3ModificationInstruction.ModIPInstruction) instruction).ip(), is(IpAddress.valueOf("1.2.3.1"))); instruction = getInstruction(Instruction.Type.L3MODIFICATION, L3ModificationInstruction.L3SubType.IPV6_FLABEL.name()); assertThat(instruction.type(), is(Instruction.Type.L3MODIFICATION)); assertThat(((L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction) .flowLabel(), is(8)); instruction = getInstruction(Instruction.Type.L0MODIFICATION, L0ModificationInstruction.L0SubType.OCH.name()); assertThat(instruction.type(), is(Instruction.Type.L0MODIFICATION)); L0ModificationInstruction.ModOchSignalInstruction och = (L0ModificationInstruction.ModOchSignalInstruction) instruction; assertThat(och.lambda().spacingMultiplier(), is(4)); assertThat(och.lambda().slotGranularity(), is(8)); assertThat(och.lambda().gridType(), is(GridType.DWDM)); assertThat(och.lambda().channelSpacing(), is(ChannelSpacing.CHL_100GHZ)); instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.TCP_DST.name()); assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION)); assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction) .port().toInt(), is(40001)); instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.TCP_SRC.name()); assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION)); assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction) .port().toInt(), is(40002)); instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.UDP_DST.name()); assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION)); assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction) .port().toInt(), is(40003)); instruction = getInstruction(Instruction.Type.L4MODIFICATION, L4ModificationInstruction.L4SubType.UDP_SRC.name()); assertThat(instruction.type(), is(Instruction.Type.L4MODIFICATION)); assertThat(((L4ModificationInstruction.ModTransportPortInstruction) instruction) .port().toInt(), is(40004)); } SortedMap<String, Criterion> criteria = new TreeMap<>(); /** * Looks up a criterion in the instruction map based on type and subtype. * * @param type type string * @return criterion that matches */ private Criterion getCriterion(Criterion.Type type) { Criterion criterion = criteria.get(type.name()); assertThat(criterion.type(), is(type)); return criterion; } /** * Checks that a rule with one of each kind of criterion decodes properly. * * @throws IOException if the resource cannot be processed */ @Test public void codecCriteriaFlowTest() throws Exception { FlowRule rule = getRule("criteria-flow.json"); checkCommonData(rule); assertThat(rule.selector().criteria().size(), is(35)); rule.selector().criteria() .forEach(criterion -> criteria.put(criterion.type().name(), criterion)); Criterion criterion; criterion = getCriterion(Criterion.Type.ETH_TYPE); assertThat(((EthTypeCriterion) criterion).ethType(), is(new EthType(2054))); criterion = getCriterion(Criterion.Type.ETH_DST); assertThat(((EthCriterion) criterion).mac(), is(MacAddress.valueOf("00:11:22:33:44:55"))); criterion = getCriterion(Criterion.Type.ETH_SRC); assertThat(((EthCriterion) criterion).mac(), is(MacAddress.valueOf("00:11:22:33:44:55"))); criterion = getCriterion(Criterion.Type.IN_PORT); assertThat(((PortCriterion) criterion).port(), is(PortNumber.portNumber(23))); criterion = getCriterion(Criterion.Type.IN_PHY_PORT); assertThat(((PortCriterion) criterion).port(), is(PortNumber.portNumber(44))); criterion = getCriterion(Criterion.Type.VLAN_VID); assertThat(((VlanIdCriterion) criterion).vlanId(), is(VlanId.vlanId((short) 777))); criterion = getCriterion(Criterion.Type.VLAN_PCP); assertThat(((VlanPcpCriterion) criterion).priority(), is(((byte) 3))); criterion = getCriterion(Criterion.Type.IP_DSCP); assertThat(((IPDscpCriterion) criterion).ipDscp(), is(((byte) 2))); criterion = getCriterion(Criterion.Type.IP_ECN); assertThat(((IPEcnCriterion) criterion).ipEcn(), is(((byte) 1))); criterion = getCriterion(Criterion.Type.IP_PROTO); assertThat(((IPProtocolCriterion) criterion).protocol(), is(((short) 4))); criterion = getCriterion(Criterion.Type.IPV4_SRC); assertThat(((IPCriterion) criterion).ip(), is((IpPrefix.valueOf("1.2.0.0/32")))); criterion = getCriterion(Criterion.Type.IPV4_DST); assertThat(((IPCriterion) criterion).ip(), is((IpPrefix.valueOf("2.2.0.0/32")))); criterion = getCriterion(Criterion.Type.IPV6_SRC); assertThat(((IPCriterion) criterion).ip(), is((IpPrefix.valueOf("3.2.0.0/32")))); criterion = getCriterion(Criterion.Type.IPV6_DST); assertThat(((IPCriterion) criterion).ip(), is((IpPrefix.valueOf("4.2.0.0/32")))); criterion = getCriterion(Criterion.Type.TCP_SRC); assertThat(((TcpPortCriterion) criterion).tcpPort().toInt(), is(80)); criterion = getCriterion(Criterion.Type.TCP_DST); assertThat(((TcpPortCriterion) criterion).tcpPort().toInt(), is(443)); criterion = getCriterion(Criterion.Type.UDP_SRC); assertThat(((UdpPortCriterion) criterion).udpPort().toInt(), is(180)); criterion = getCriterion(Criterion.Type.UDP_DST); assertThat(((UdpPortCriterion) criterion).udpPort().toInt(), is(1443)); criterion = getCriterion(Criterion.Type.SCTP_SRC); assertThat(((SctpPortCriterion) criterion).sctpPort().toInt(), is(280)); criterion = getCriterion(Criterion.Type.SCTP_DST); assertThat(((SctpPortCriterion) criterion).sctpPort().toInt(), is(2443)); criterion = getCriterion(Criterion.Type.ICMPV4_TYPE); assertThat(((IcmpTypeCriterion) criterion).icmpType(), is((short) 24)); criterion = getCriterion(Criterion.Type.ICMPV4_CODE); assertThat(((IcmpCodeCriterion) criterion).icmpCode(), is((short) 16)); criterion = getCriterion(Criterion.Type.ICMPV6_TYPE); assertThat(((Icmpv6TypeCriterion) criterion).icmpv6Type(), is((short) 14)); criterion = getCriterion(Criterion.Type.ICMPV6_CODE); assertThat(((Icmpv6CodeCriterion) criterion).icmpv6Code(), is((short) 6)); criterion = getCriterion(Criterion.Type.IPV6_FLABEL); assertThat(((IPv6FlowLabelCriterion) criterion).flowLabel(), is(8)); criterion = getCriterion(Criterion.Type.IPV6_ND_TARGET); assertThat(((IPv6NDTargetAddressCriterion) criterion) .targetAddress().toString(), is("1111:2222:3333:4444:5555:6666:7777:8888")); criterion = getCriterion(Criterion.Type.IPV6_ND_SLL); assertThat(((IPv6NDLinkLayerAddressCriterion) criterion).mac(), is(MacAddress.valueOf("00:11:22:33:44:56"))); criterion = getCriterion(Criterion.Type.IPV6_ND_TLL); assertThat(((IPv6NDLinkLayerAddressCriterion) criterion).mac(), is(MacAddress.valueOf("00:11:22:33:44:57"))); criterion = getCriterion(Criterion.Type.MPLS_LABEL); assertThat(((MplsCriterion) criterion).label(), is(MplsLabel.mplsLabel(123))); criterion = getCriterion(Criterion.Type.IPV6_EXTHDR); assertThat(((IPv6ExthdrFlagsCriterion) criterion).exthdrFlags(), is(99)); criterion = getCriterion(Criterion.Type.TUNNEL_ID); assertThat(((TunnelIdCriterion) criterion).tunnelId(), is(100L)); criterion = getCriterion(Criterion.Type.OCH_SIGTYPE); assertThat(((OchSignalTypeCriterion) criterion).signalType(), is(OchSignalType.FIXED_GRID)); criterion = getCriterion(Criterion.Type.ODU_SIGTYPE); assertThat(((OduSignalTypeCriterion) criterion).signalType(), is(OduSignalType.ODU4)); criterion = getCriterion(Criterion.Type.ODU_SIGID); assertThat(((OduSignalIdCriterion) criterion).oduSignalId().tributaryPortNumber(), is(1)); assertThat(((OduSignalIdCriterion) criterion).oduSignalId().tributarySlotLength(), is(80)); assertThat(((OduSignalIdCriterion) criterion).oduSignalId().tributarySlotBitmap(), is(new byte[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1})); } /** * Checks that a rule with a SigId criterion decodes properly. * * @throws IOException if the resource cannot be processed */ @Test public void codecSigIdCriteriaFlowTest() throws Exception { FlowRule rule = getRule("sigid-flow.json"); checkCommonData(rule); assertThat(rule.selector().criteria().size(), is(1)); Criterion criterion = rule.selector().criteria().iterator().next(); assertThat(criterion.type(), is(Criterion.Type.OCH_SIGID)); Lambda lambda = ((OchSignalCriterion) criterion).lambda(); assertThat(lambda, instanceOf(OchSignal.class)); OchSignal ochSignal = (OchSignal) lambda; assertThat(ochSignal.spacingMultiplier(), is(3)); assertThat(ochSignal.slotGranularity(), is(4)); assertThat(ochSignal.gridType(), is(GridType.CWDM)); assertThat(ochSignal.channelSpacing(), is(ChannelSpacing.CHL_25GHZ)); } }