From a424a059eba9968b6f71ed100650ad61684f6773 Mon Sep 17 00:00:00 2001 From: Jian Li Date: Mon, 30 May 2016 21:02:33 +0900 Subject: [PATCH] Allow to specify appId through FlowObjective REST API Change-Id: Iadff74d379e1d5ec4f6e8ff2cda2ad96892d2cc1 --- .../codec/impl/FilteringObjectiveCodec.java | 11 +++++--- .../codec/impl/ForwardingObjectiveCodec.java | 9 +++--- .../codec/impl/NextObjectiveCodec.java | 9 +++--- .../impl/FilteringObjectiveCodecTest.java | 12 ++++++-- .../impl/ForwardingObjectiveCodecTest.java | 17 +++++++---- .../codec/impl/NextObjectiveCodecTest.java | 12 ++++++-- .../codec/impl/FilteringObjective.json | 1 + .../codec/impl/ForwardingObjective.json | 1 + .../onosproject/codec/impl/NextObjective.json | 1 + .../resources/FlowObjectiveWebResource.java | 28 +++++++++++++++++-- 10 files changed, 74 insertions(+), 27 deletions(-) diff --git a/core/common/src/main/java/org/onosproject/codec/impl/FilteringObjectiveCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/FilteringObjectiveCodec.java index 67aae37b22..673e4c8b19 100644 --- a/core/common/src/main/java/org/onosproject/codec/impl/FilteringObjectiveCodec.java +++ b/core/common/src/main/java/org/onosproject/codec/impl/FilteringObjectiveCodec.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.onosproject.codec.CodecContext; import org.onosproject.codec.JsonCodec; -import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criterion; @@ -37,7 +36,7 @@ import static org.slf4j.LoggerFactory.getLogger; /** * Filtering Objective Codec. */ -public class FilteringObjectiveCodec extends JsonCodec { +public final class FilteringObjectiveCodec extends JsonCodec { private final Logger log = getLogger(getClass()); // JSON field names @@ -45,6 +44,7 @@ public class FilteringObjectiveCodec extends JsonCodec { private static final String TYPE = "type"; private static final String KEY = "key"; private static final String META = "meta"; + private static final String APP_ID = "appId"; private static final String OPERATION = "operation"; private static final String CONDITIONS = "conditions"; @@ -118,9 +118,12 @@ public class FilteringObjectiveCodec extends JsonCodec { final DefaultFilteringObjective.Builder builder = (DefaultFilteringObjective.Builder) och.decode(json, baseBuilder, context); + + // application id - ApplicationId appId = coreService.registerApplication(REST_APP_ID); - builder.fromApp(appId); + JsonNode appIdJson = json.get(APP_ID); + String appId = appIdJson != null ? appIdJson.asText() : REST_APP_ID; + builder.fromApp(coreService.registerApplication(appId)); // decode type String typeStr = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asText(); diff --git a/core/common/src/main/java/org/onosproject/codec/impl/ForwardingObjectiveCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/ForwardingObjectiveCodec.java index b198fa30f8..864756a3c2 100644 --- a/core/common/src/main/java/org/onosproject/codec/impl/ForwardingObjectiveCodec.java +++ b/core/common/src/main/java/org/onosproject/codec/impl/ForwardingObjectiveCodec.java @@ -19,7 +19,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.onosproject.codec.CodecContext; import org.onosproject.codec.JsonCodec; -import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; @@ -34,11 +33,12 @@ import static org.slf4j.LoggerFactory.getLogger; /** * Forwarding Objective Codec. */ -public class ForwardingObjectiveCodec extends JsonCodec { +public final class ForwardingObjectiveCodec extends JsonCodec { private final Logger log = getLogger(getClass()); // JSON field names private static final String ID = "id"; + private static final String APP_ID = "appId"; private static final String SELECTOR = "selector"; private static final String FLAG = "flag"; private static final String OPERATION = "operation"; @@ -116,8 +116,9 @@ public class ForwardingObjectiveCodec extends JsonCodec { (DefaultForwardingObjective.Builder) och.decode(json, baseBuilder, context); // application id - ApplicationId appId = coreService.registerApplication(REST_APP_ID); - builder.fromApp(appId); + JsonNode appIdJson = json.get(APP_ID); + String appId = appIdJson != null ? appIdJson.asText() : REST_APP_ID; + builder.fromApp(coreService.registerApplication(appId)); // decode flag String flagStr = nullIsIllegal(json.get(FLAG), FLAG + MISSING_MEMBER_MESSAGE).asText(); diff --git a/core/common/src/main/java/org/onosproject/codec/impl/NextObjectiveCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/NextObjectiveCodec.java index 617a1b3a1f..a58ad3fbb3 100644 --- a/core/common/src/main/java/org/onosproject/codec/impl/NextObjectiveCodec.java +++ b/core/common/src/main/java/org/onosproject/codec/impl/NextObjectiveCodec.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.onosproject.codec.CodecContext; import org.onosproject.codec.JsonCodec; -import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; @@ -37,12 +36,13 @@ import static org.slf4j.LoggerFactory.getLogger; /** * Next Objective Codec. */ -public class NextObjectiveCodec extends JsonCodec { +public final class NextObjectiveCodec extends JsonCodec { private final Logger log = getLogger(getClass()); // JSON field names private static final String ID = "id"; + private static final String APP_ID = "appId"; private static final String TYPE = "type"; private static final String OPERATION = "operation"; private static final String TREATMENTS = "treatments"; @@ -121,8 +121,9 @@ public class NextObjectiveCodec extends JsonCodec { builder.withId(idJson.asInt()); // decode application id - ApplicationId appId = coreService.registerApplication(REST_APP_ID); - builder.fromApp(appId); + JsonNode appIdJson = json.get(APP_ID); + String appId = appIdJson != null ? appIdJson.asText() : REST_APP_ID; + builder.fromApp(coreService.registerApplication(appId)); // decode type String typeStr = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asText(); diff --git a/core/common/src/test/java/org/onosproject/codec/impl/FilteringObjectiveCodecTest.java b/core/common/src/test/java/org/onosproject/codec/impl/FilteringObjectiveCodecTest.java index 87918e46d9..7718c811fe 100644 --- a/core/common/src/test/java/org/onosproject/codec/impl/FilteringObjectiveCodecTest.java +++ b/core/common/src/test/java/org/onosproject/codec/impl/FilteringObjectiveCodecTest.java @@ -21,7 +21,9 @@ import org.junit.Before; import org.junit.Test; import org.onlab.packet.VlanId; import org.onosproject.codec.JsonCodec; +import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; +import org.onosproject.core.DefaultApplicationId; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.criteria.Criterion; import org.onosproject.net.flowobjective.DefaultFilteringObjective; @@ -47,6 +49,7 @@ public class FilteringObjectiveCodecTest { MockCodecContext context; JsonCodec filteringObjectiveCodec; final CoreService mockCoreService = createMock(CoreService.class); + static final String SAMPLE_APP_ID = "org.onosproject.sample"; /** * Sets up for each test. @@ -58,9 +61,6 @@ public class FilteringObjectiveCodecTest { filteringObjectiveCodec = context.codec(FilteringObjective.class); assertThat(filteringObjectiveCodec, notNullValue()); - expect(mockCoreService.registerApplication(FilteringObjectiveCodec.REST_APP_ID)) - .andReturn(APP_ID).anyTimes(); - replay(mockCoreService); context.registerService(CoreService.class, mockCoreService); } @@ -93,6 +93,12 @@ public class FilteringObjectiveCodecTest { */ @Test public void testFilteringObjectiveDecode() throws IOException { + + ApplicationId appId = new DefaultApplicationId(0, SAMPLE_APP_ID); + + expect(mockCoreService.registerApplication(SAMPLE_APP_ID)).andReturn(appId).anyTimes(); + replay(mockCoreService); + FilteringObjective filteringObjective = getFilteringObjective("FilteringObjective.json"); assertThat(filteringObjective.type(), is(FilteringObjective.Type.PERMIT)); diff --git a/core/common/src/test/java/org/onosproject/codec/impl/ForwardingObjectiveCodecTest.java b/core/common/src/test/java/org/onosproject/codec/impl/ForwardingObjectiveCodecTest.java index 9b4e2b12b3..b6cc7a6d3a 100644 --- a/core/common/src/test/java/org/onosproject/codec/impl/ForwardingObjectiveCodecTest.java +++ b/core/common/src/test/java/org/onosproject/codec/impl/ForwardingObjectiveCodecTest.java @@ -21,7 +21,9 @@ import org.junit.Before; import org.junit.Test; import org.onlab.packet.VlanId; import org.onosproject.codec.JsonCodec; +import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; +import org.onosproject.core.DefaultApplicationId; import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.criteria.Criteria; @@ -32,9 +34,7 @@ import org.onosproject.net.flowobjective.ForwardingObjective; import java.io.IOException; import java.io.InputStream; -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; @@ -49,6 +49,7 @@ public class ForwardingObjectiveCodecTest { MockCodecContext context; JsonCodec forwardingObjectiveCodec; final CoreService mockCoreService = createMock(CoreService.class); + static final String SAMPLE_APP_ID = "org.onosproject.sample"; /** * Sets up for each test. @@ -60,9 +61,6 @@ public class ForwardingObjectiveCodecTest { forwardingObjectiveCodec = context.codec(ForwardingObjective.class); assertThat(forwardingObjectiveCodec, notNullValue()); - expect(mockCoreService.registerApplication(ForwardingObjectiveCodec.REST_APP_ID)) - .andReturn(APP_ID).anyTimes(); - replay(mockCoreService); context.registerService(CoreService.class, mockCoreService); } @@ -97,6 +95,12 @@ public class ForwardingObjectiveCodecTest { */ @Test public void testForwardingObjectiveDecode() throws IOException { + + ApplicationId appId = new DefaultApplicationId(0, SAMPLE_APP_ID); + + expect(mockCoreService.registerApplication(SAMPLE_APP_ID)).andReturn(appId).anyTimes(); + replay(mockCoreService); + ForwardingObjective forwardingObjective = getForwardingObjective("ForwardingObjective.json"); assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC)); @@ -104,6 +108,7 @@ public class ForwardingObjectiveCodecTest { assertThat(forwardingObjective.timeout(), is(1)); assertThat(forwardingObjective.op(), is(ForwardingObjective.Operation.ADD)); assertThat(forwardingObjective.permanent(), is(false)); + assertThat(forwardingObjective.appId().name(), is(SAMPLE_APP_ID)); } /** diff --git a/core/common/src/test/java/org/onosproject/codec/impl/NextObjectiveCodecTest.java b/core/common/src/test/java/org/onosproject/codec/impl/NextObjectiveCodecTest.java index c0fc138a02..04746dbf80 100644 --- a/core/common/src/test/java/org/onosproject/codec/impl/NextObjectiveCodecTest.java +++ b/core/common/src/test/java/org/onosproject/codec/impl/NextObjectiveCodecTest.java @@ -20,7 +20,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Before; import org.junit.Test; import org.onosproject.codec.JsonCodec; +import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; +import org.onosproject.core.DefaultApplicationId; import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flowobjective.DefaultNextObjective; @@ -46,6 +48,7 @@ public class NextObjectiveCodecTest { MockCodecContext context; JsonCodec nextObjectiveCodec; final CoreService mockCoreService = createMock(CoreService.class); + static final String SAMPLE_APP_ID = "org.onosproject.sample"; /** * Sets up for each test. @@ -57,9 +60,6 @@ public class NextObjectiveCodecTest { nextObjectiveCodec = context.codec(NextObjective.class); assertThat(nextObjectiveCodec, notNullValue()); - expect(mockCoreService.registerApplication(NextObjectiveCodec.REST_APP_ID)) - .andReturn(APP_ID).anyTimes(); - replay(mockCoreService); context.registerService(CoreService.class, mockCoreService); } @@ -89,6 +89,12 @@ public class NextObjectiveCodecTest { */ @Test public void testNextObjectiveDecode() throws IOException { + + ApplicationId appId = new DefaultApplicationId(0, SAMPLE_APP_ID); + + expect(mockCoreService.registerApplication(SAMPLE_APP_ID)).andReturn(appId).anyTimes(); + replay(mockCoreService); + NextObjective nextObjective = getNextObjective("NextObjective.json"); assertThat(nextObjective.type(), is(NextObjective.Type.FAILOVER)); diff --git a/core/common/src/test/resources/org/onosproject/codec/impl/FilteringObjective.json b/core/common/src/test/resources/org/onosproject/codec/impl/FilteringObjective.json index 414e3d68d8..f6c474c943 100644 --- a/core/common/src/test/resources/org/onosproject/codec/impl/FilteringObjective.json +++ b/core/common/src/test/resources/org/onosproject/codec/impl/FilteringObjective.json @@ -1,5 +1,6 @@ { "priority": 60, + "appId": "org.onosproject.sample", "isPermanent": "false", "timeout": 1, "type": "PERMIT", diff --git a/core/common/src/test/resources/org/onosproject/codec/impl/ForwardingObjective.json b/core/common/src/test/resources/org/onosproject/codec/impl/ForwardingObjective.json index e979626a85..63f145d61b 100644 --- a/core/common/src/test/resources/org/onosproject/codec/impl/ForwardingObjective.json +++ b/core/common/src/test/resources/org/onosproject/codec/impl/ForwardingObjective.json @@ -1,5 +1,6 @@ { "priority": 60, + "appId": "org.onosproject.sample", "isPermanent": "false", "timeout": 1, "flag": "SPECIFIC", diff --git a/core/common/src/test/resources/org/onosproject/codec/impl/NextObjective.json b/core/common/src/test/resources/org/onosproject/codec/impl/NextObjective.json index 6f52f116eb..65ba8941a1 100644 --- a/core/common/src/test/resources/org/onosproject/codec/impl/NextObjective.json +++ b/core/common/src/test/resources/org/onosproject/codec/impl/NextObjective.json @@ -1,5 +1,6 @@ { "id": 1, + "appId": "org.onosproject.sample", "type": "FAILOVER", "operation": "ADD", "treatments": [ diff --git a/web/api/src/main/java/org/onosproject/rest/resources/FlowObjectiveWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/FlowObjectiveWebResource.java index 615e5b18b7..712ccae5ad 100644 --- a/web/api/src/main/java/org/onosproject/rest/resources/FlowObjectiveWebResource.java +++ b/web/api/src/main/java/org/onosproject/rest/resources/FlowObjectiveWebResource.java @@ -30,6 +30,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -57,6 +58,7 @@ public class FlowObjectiveWebResource extends AbstractWebResource { /** * Creates and installs a new filtering objective for the specified device. * + * @param appId application identifier * @param deviceId device identifier * @param stream filtering objective JSON * @return status of the request - CREATED if the JSON is correct, @@ -67,12 +69,18 @@ public class FlowObjectiveWebResource extends AbstractWebResource { @Path("{deviceId}/filter") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public Response createFilteringObjective(@PathParam("deviceId") String deviceId, + public Response createFilteringObjective(@QueryParam("appId") String appId, + @PathParam("deviceId") String deviceId, InputStream stream) { try { UriBuilder locationBuilder = null; ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); if (validateDeviceId(deviceId, jsonTree)) { + + if (appId != null) { + jsonTree.put("appId", appId); + } + DeviceId did = DeviceId.deviceId(deviceId); FilteringObjective filteringObjective = codec(FilteringObjective.class).decode(jsonTree, this); @@ -94,6 +102,7 @@ public class FlowObjectiveWebResource extends AbstractWebResource { /** * Creates and installs a new forwarding objective for the specified device. * + * @param appId application identifier * @param deviceId device identifier * @param stream forwarding objective JSON * @return status of the request - CREATED if the JSON is correct, @@ -104,12 +113,18 @@ public class FlowObjectiveWebResource extends AbstractWebResource { @Path("{deviceId}/forward") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public Response createForwardingObjective(@PathParam("deviceId") String deviceId, + public Response createForwardingObjective(@QueryParam("appId") String appId, + @PathParam("deviceId") String deviceId, InputStream stream) { try { UriBuilder locationBuilder = null; ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); if (validateDeviceId(deviceId, jsonTree)) { + + if (appId != null) { + jsonTree.put("appId", appId); + } + DeviceId did = DeviceId.deviceId(deviceId); ForwardingObjective forwardingObjective = codec(ForwardingObjective.class).decode(jsonTree, this); @@ -131,6 +146,7 @@ public class FlowObjectiveWebResource extends AbstractWebResource { /** * Creates and installs a new next objective for the specified device. * + * @param appId application identifier * @param deviceId device identifier * @param stream next objective JSON * @return status of the request - CREATED if the JSON is correct, @@ -141,12 +157,18 @@ public class FlowObjectiveWebResource extends AbstractWebResource { @Path("{deviceId}/next") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public Response createNextObjective(@PathParam("deviceId") String deviceId, + public Response createNextObjective(@QueryParam("appId") String appId, + @PathParam("deviceId") String deviceId, InputStream stream) { try { UriBuilder locationBuilder = null; ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); if (validateDeviceId(deviceId, jsonTree)) { + + if (appId != null) { + jsonTree.put("appId", appId); + } + DeviceId did = DeviceId.deviceId(deviceId); NextObjective nextObjective = codec(NextObjective.class).decode(jsonTree, this);