/* * 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.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.onlab.util.HexString; import org.onosproject.codec.CodecContext; import org.onosproject.codec.JsonCodec; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.core.GroupId; import org.onosproject.net.DeviceId; import org.onosproject.net.group.DefaultGroup; import org.onosproject.net.group.DefaultGroupDescription; import org.onosproject.net.group.DefaultGroupKey; import org.onosproject.net.group.Group; import org.onosproject.net.group.GroupBucket; import org.onosproject.net.group.GroupBuckets; import org.onosproject.net.group.GroupDescription; import org.onosproject.net.group.GroupKey; import org.slf4j.Logger; import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; import static com.google.common.base.Preconditions.checkNotNull; import static org.onlab.util.Tools.nullIsIllegal; import static org.slf4j.LoggerFactory.getLogger; /** * Group JSON codec. */ public final class GroupCodec extends JsonCodec<Group> { private final Logger log = getLogger(getClass()); // JSON field names private static final String ID = "id"; private static final String STATE = "state"; private static final String LIFE = "life"; private static final String PACKETS = "packets"; private static final String BYTES = "bytes"; private static final String REFERENCE_COUNT = "referenceCount"; private static final String TYPE = "type"; private static final String GROUP_ID = "groupId"; private static final String DEVICE_ID = "deviceId"; private static final String APP_ID = "appId"; private static final String APP_COOKIE = "appCookie"; private static final String GIVEN_GROUP_ID = "givenGroupId"; private static final String BUCKETS = "buckets"; private static final String MISSING_MEMBER_MESSAGE = " member is required in Group"; public static final String REST_APP_ID = "org.onosproject.rest"; @Override public ObjectNode encode(Group group, CodecContext context) { checkNotNull(group, "Group cannot be null"); ObjectNode result = context.mapper().createObjectNode() .put(ID, group.id().id().toString()) .put(STATE, group.state().toString()) .put(LIFE, group.life()) .put(PACKETS, group.packets()) .put(BYTES, group.bytes()) .put(REFERENCE_COUNT, group.referenceCount()) .put(TYPE, group.type().toString()) .put(DEVICE_ID, group.deviceId().toString()); if (group.appId() != null) { result.put(APP_ID, group.appId().name()); } if (group.appCookie() != null) { result.put(APP_COOKIE, group.appCookie().toString()); } if (group.givenGroupId() != null) { result.put(GIVEN_GROUP_ID, group.givenGroupId().toString()); } ArrayNode buckets = context.mapper().createArrayNode(); group.buckets().buckets().forEach(bucket -> { ObjectNode bucketJson = context.codec(GroupBucket.class).encode(bucket, context); buckets.add(bucketJson); }); result.set(BUCKETS, buckets); return result; } @Override public Group decode(ObjectNode json, CodecContext context) { if (json == null || !json.isObject()) { return null; } final JsonCodec<GroupBucket> groupBucketCodec = context.codec(GroupBucket.class); CoreService coreService = context.getService(CoreService.class); // parse group id int groupIdInt = nullIsIllegal(json.get(GROUP_ID), GROUP_ID + MISSING_MEMBER_MESSAGE).asInt(); GroupId groupId = new GroupId(groupIdInt); // parse group key (appCookie) String groupKeyStr = nullIsIllegal(json.get(APP_COOKIE), APP_COOKIE + MISSING_MEMBER_MESSAGE).asText(); if (!groupKeyStr.startsWith("0x")) { throw new IllegalArgumentException("APP_COOKIE must be a hex string starts with 0x"); } GroupKey groupKey = new DefaultGroupKey(HexString.fromHexString( groupKeyStr.split("0x")[1], "")); // parse device id DeviceId deviceId = DeviceId.deviceId(nullIsIllegal(json.get(DEVICE_ID), DEVICE_ID + MISSING_MEMBER_MESSAGE).asText()); // application id ApplicationId appId = coreService.registerApplication(REST_APP_ID); // parse group type String type = nullIsIllegal(json.get(TYPE), TYPE + MISSING_MEMBER_MESSAGE).asText(); GroupDescription.Type groupType = null; switch (type) { case "SELECT": groupType = Group.Type.SELECT; break; case "INDIRECT": groupType = Group.Type.INDIRECT; break; case "ALL": groupType = Group.Type.ALL; break; case "FAILOVER": groupType = Group.Type.FAILOVER; break; default: nullIsIllegal(groupType, "The requested group type " + type + " is not valid"); } // parse group buckets GroupBuckets buckets = null; List<GroupBucket> groupBucketList = new ArrayList<>(); JsonNode bucketsJson = json.get(BUCKETS); checkNotNull(bucketsJson); if (bucketsJson != null) { IntStream.range(0, bucketsJson.size()) .forEach(i -> { ObjectNode bucketJson = get(bucketsJson, i); bucketJson.put("type", type); groupBucketList.add(groupBucketCodec.decode(bucketJson, context)); }); buckets = new GroupBuckets(groupBucketList); } GroupDescription groupDescription = new DefaultGroupDescription(deviceId, groupType, buckets, groupKey, groupIdInt, appId); return new DefaultGroup(groupId, groupDescription); } }