[ONOS-4530] Allow to specify appId when insert FlowRule through REST
- Augment FlowRuleCodec to encode FlowRule
- Add unit test for encode method of FlowRuleCodec
- Add getFlowByAppId and removeFlowByAppId methods in FlowsWebResource
- Add more unit tests for FlowWebResource
- Add FlowRules.json swagger doc
- Rename Flows.json to FlowEntries.json, correct FlowEntries.json
Change-Id: Ic3ec390c13a349e51ae4208adbc478564b6724ba
diff --git a/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java b/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java
index 9c5e3fd..11b7eb6 100644
--- a/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java
+++ b/core/common/src/test/java/org/onosproject/codec/impl/FlowRuleCodecTest.java
@@ -17,6 +17,8 @@
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;
@@ -29,12 +31,14 @@
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.FlowRule;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
@@ -75,6 +79,7 @@
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;
@@ -105,6 +110,7 @@
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);
}
@@ -166,6 +172,118 @@
SortedMap<String, Instruction> instructions = new TreeMap<>();
/**
+ * Checks that a simple rule encodes properly.
+ */
+ @Test
+ public void testFlowRuleEncode() {
+
+ DeviceId deviceId = DeviceId.deviceId("of:000000000000000a");
+ FlowRule permFlowRule = DefaultFlowRule.builder()
+ .withCookie(1)
+ .forTable(1)
+ .withPriority(1)
+ .makePermanent()
+ .forDevice(deviceId).build();
+
+ FlowRule tempFlowRule = DefaultFlowRule.builder()
+ .withCookie(1)
+ .forTable(1)
+ .withPriority(1)
+ .makeTemporary(1000)
+ .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;
+ }
+
+ // TODO: need to check traffic treatment
+
+ // TODO: need to check selector
+
+ 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