Ray Milkey
Committed by Gerrit Code Review

Fix ONOS-2090 - Improvements to Intent JSON

- Intents are now identified by the name portion of the appId rather than
  the number
- removed the now useless "details" field which had a toString()
  dump of the intent for when we didn't support all intent types
- Single Intent GET operations now accept a decimal or hexadecimal
  value for the Intent key.

Change-Id: I39d635e68cccf2e59d0d11307b93329a2dc0bc96
......@@ -28,6 +28,7 @@ import org.onosproject.net.intent.PointToPointIntent;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.net.UrlEscapers;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
......@@ -40,7 +41,6 @@ public final class IntentCodec extends JsonCodec<Intent> {
protected static final String TYPE = "type";
protected static final String ID = "id";
protected static final String APP_ID = "appId";
protected static final String DETAILS = "details";
protected static final String STATE = "state";
protected static final String PRIORITY = "priority";
protected static final String RESOURCES = "resources";
......@@ -50,11 +50,12 @@ public final class IntentCodec extends JsonCodec<Intent> {
@Override
public ObjectNode encode(Intent intent, CodecContext context) {
checkNotNull(intent, "Intent cannot be null");
final ObjectNode result = context.mapper().createObjectNode()
.put(TYPE, intent.getClass().getSimpleName())
.put(ID, intent.id().toString())
.put(APP_ID, intent.appId().toString())
.put(DETAILS, intent.toString());
.put(APP_ID, UrlEscapers.urlPathSegmentEscaper()
.escape(intent.appId().name()));
final ArrayNode jsonResources = result.putArray(RESOURCES);
......@@ -98,8 +99,8 @@ public final class IntentCodec extends JsonCodec<Intent> {
*/
public static void intentAttributes(ObjectNode json, CodecContext context,
Intent.Builder builder) {
short appId = (short) nullIsIllegal(json.get(IntentCodec.APP_ID),
IntentCodec.TYPE + IntentCodec.MISSING_MEMBER_MESSAGE).asInt();
String appId = nullIsIllegal(json.get(IntentCodec.APP_ID),
IntentCodec.APP_ID + IntentCodec.MISSING_MEMBER_MESSAGE).asText();
CoreService service = context.getService(CoreService.class);
builder.appId(service.getAppId(appId));
......
......@@ -103,8 +103,8 @@ public class IntentCodecTest extends AbstractIntentTest {
final IntentService mockIntentService = new IntentServiceAdapter();
context.registerService(IntentService.class, mockIntentService);
context.registerService(CoreService.class, mockCoreService);
expect(mockCoreService.getAppId((short) 2))
.andReturn(new DefaultApplicationId(2, "app"));
expect(mockCoreService.getAppId(appId.name()))
.andReturn(appId);
replay(mockCoreService);
}
......
......@@ -443,8 +443,10 @@ public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode>
}
// check application id
final String jsonAppId = jsonIntent.get("appId").asText();
final String appId = intent.appId().toString();
final JsonNode jsonAppIdNode = jsonIntent.get("appId");
final String jsonAppId = jsonAppIdNode.asText();
final String appId = intent.appId().name();
if (!jsonAppId.equals(appId)) {
description.appendText("appId was " + jsonAppId);
return false;
......@@ -458,14 +460,6 @@ public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode>
return false;
}
// check details field
final String jsonDetails = jsonIntent.get("details").asText();
final String details = intent.toString();
if (!jsonDetails.equals(details)) {
description.appendText("details were " + jsonDetails);
return false;
}
// check resources array
final JsonNode jsonResources = jsonIntent.get("resources");
if (intent.resources() != null) {
......
{
"type": "HostToHostIntent",
"appId": 2,
"appId": "test",
"selector": {"criteria": []},
"treatment": {
"instructions": [],
......
{
"type": "PointToPointIntent",
"appId": 2,
"appId": "test",
"selector": {
"criteria": [
{
......
......@@ -91,14 +91,14 @@ public class IntentsWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{appId}/{key}")
public Response getIntentById(@PathParam("appId") Short appId,
public Response getIntentById(@PathParam("appId") String appId,
@PathParam("key") String key) {
final ApplicationId app = get(CoreService.class).getAppId(appId);
Intent intent = get(IntentService.class).getIntent(Key.of(key, app));
if (intent == null) {
intent = get(IntentService.class)
.getIntent(Key.of(Long.parseLong(key), app));
long numericalKey = Long.decode(key);
intent = get(IntentService.class).getIntent(Key.of(numericalKey, app));
}
nullIsNotFound(intent, INTENT_NOT_FOUND);
......@@ -140,7 +140,7 @@ public class IntentsWebResource extends AbstractWebResource {
*/
@DELETE
@Path("{appId}/{key}")
public void deleteIntentById(@PathParam("appId") Short appId,
public void deleteIntentById(@PathParam("appId") String appId,
@PathParam("key") String keyString) {
final ApplicationId app = get(CoreService.class).getAppId(appId);
......
......@@ -110,9 +110,11 @@ public class IntentsResourceTest extends ResourceTest {
}
// check application id
final String jsonAppId = jsonIntent.get("appId").asString();
if (!jsonAppId.equals(intent.appId().toString())) {
reason = "appId " + intent.appId().toString();
final String appId = intent.appId().name();
if (!jsonAppId.equals(appId)) {
reason = "appId was " + jsonAppId;
return false;
}
......@@ -123,13 +125,6 @@ public class IntentsResourceTest extends ResourceTest {
return false;
}
// check details field
final String jsonDetails = jsonIntent.get("details").asString();
if (!jsonDetails.equals(intent.toString())) {
reason = "details " + intent.toString();
return false;
}
// check state field
final String jsonState = jsonIntent.get("state").asString();
if (!jsonState.equals("INSTALLED")) {
......@@ -196,7 +191,7 @@ public class IntentsResourceTest extends ResourceTest {
@Override
public boolean matchesSafely(JsonArray json) {
boolean intentFound = false;
final int expectedAttributes = 6;
final int expectedAttributes = 5;
for (int jsonIntentIndex = 0; jsonIntentIndex < json.size();
jsonIntentIndex++) {
......@@ -336,11 +331,12 @@ public class IntentsResourceTest extends ResourceTest {
.andReturn(intent)
.anyTimes();
replay(mockIntentService);
expect(mockCoreService.getAppId(APP_ID.id()))
expect(mockCoreService.getAppId(APP_ID.name()))
.andReturn(APP_ID).anyTimes();
replay(mockCoreService);
final WebResource rs = resource();
final String response = rs.path("intents/1/0").get(String.class);
final String response = rs.path("intents/" + APP_ID.name()
+ "/0").get(String.class);
final JsonObject result = JsonObject.readFrom(response);
assertThat(result, matchesIntent(intent));
}
......@@ -371,8 +367,9 @@ public class IntentsResourceTest extends ResourceTest {
*/
@Test
public void testPost() {
expect(mockCoreService.getAppId((short) 2))
.andReturn(new DefaultApplicationId(2, "app"));
ApplicationId testId = new DefaultApplicationId(2, "myApp");
expect(mockCoreService.getAppId("myApp"))
.andReturn(testId);
replay(mockCoreService);
mockIntentService.submit(anyObject());
......
{
"type": "PointToPointIntent",
"appId": 2,
"appId": "myApp",
"selector": {
"criteria": [
{
......