blob: fd0610199ea0d69f6bf23136791ced08b8af0010 [file] [log] [blame]
Jian Lib68b9a82016-02-23 10:25:54 +09001/*
2 * Copyright 2016 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.codec.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.collect.BiMap;
22import com.google.common.collect.HashBiMap;
23import com.google.common.collect.Sets;
24import org.onosproject.cluster.NodeId;
25import org.onosproject.codec.CodecContext;
26import org.onosproject.codec.JsonCodec;
27import org.onosproject.net.region.DefaultRegion;
28import org.onosproject.net.region.Region;
29import org.onosproject.net.region.RegionId;
30
31import java.util.ArrayList;
32import java.util.List;
33import java.util.Set;
34import java.util.stream.IntStream;
35
36import static com.google.common.base.Preconditions.checkNotNull;
37import static org.onlab.util.Tools.nullIsIllegal;
38
39/**
40 * Codec for the Region class.
41 */
42public class RegionCodec extends JsonCodec<Region> {
43
44 // JSON field names
45 private static final String REGION_ID = "id";
46 private static final String NAME = "name";
47 private static final String TYPE = "type";
48 private static final String MASTERS = "masters";
49 private static final String NODE_ID = "nodeId";
50 private static final String REGION_NOT_NULL_MSG = "Region cannot be null";
51 private static final String MISSING_MEMBER_MESSAGE = " member is required in Region";
52
53 private static final BiMap<String, Region.Type> REGION_TYPE_MAP = HashBiMap.create();
54
55 static {
56 // key is String representation of Region.Type
57 // value is Region.Type
58 REGION_TYPE_MAP.put("CONTINENT", Region.Type.CONTINENT);
59 REGION_TYPE_MAP.put("COUNTRY", Region.Type.COUNTRY);
60 REGION_TYPE_MAP.put("METRO", Region.Type.METRO);
61 REGION_TYPE_MAP.put("CAMPUS", Region.Type.CAMPUS);
62 REGION_TYPE_MAP.put("BUILDING", Region.Type.BUILDING);
63 REGION_TYPE_MAP.put("FLOOR", Region.Type.FLOOR);
64 REGION_TYPE_MAP.put("ROOM", Region.Type.ROOM);
65 REGION_TYPE_MAP.put("RACK", Region.Type.RACK);
66 REGION_TYPE_MAP.put("LOGICAL_GROUP", Region.Type.LOGICAL_GROUP);
67 }
68
69 @Override
70 public ObjectNode encode(Region region, CodecContext context) {
71 checkNotNull(region, REGION_NOT_NULL_MSG);
72
73 ObjectNode result = context.mapper().createObjectNode()
74 .put(REGION_ID, region.id().toString())
75 .put(NAME, region.name())
76 .put(TYPE, region.type().toString());
77
78 ArrayNode masters = context.mapper().createArrayNode();
79
80 region.masters().forEach(sets -> {
81 ArrayNode setsJson = context.mapper().createArrayNode();
82 sets.forEach(nodeId -> setsJson.add(nodeId.toString()));
83 masters.add(setsJson);
84 });
85 result.set(MASTERS, masters);
86 return result;
87 }
88
89 @Override
90 public Region decode(ObjectNode json, CodecContext context) {
91 if (json == null || !json.isObject()) {
92 return null;
93 }
94
95 // parse masters
96 List<Set<NodeId>> masters = new ArrayList<>();
97 JsonNode mastersJson = json.get(MASTERS);
98 checkNotNull(mastersJson);
99
100 if (mastersJson != null) {
101 IntStream.range(0, mastersJson.size()).forEach(i -> {
102 ObjectNode setsJson = get(mastersJson, i);
103 final Set<NodeId> nodeIds = Sets.newHashSet();
104 if (setsJson != null && setsJson.isArray()) {
105 Set<NodeId> localNodeIds = Sets.newHashSet();
106 IntStream.range(0, mastersJson.size()).forEach(j -> {
107 ObjectNode nodeIdJson = get(setsJson, j);
108 localNodeIds.add(decodeNodeId(nodeIdJson));
109 });
110 nodeIds.addAll(localNodeIds);
111 }
112 masters.add(nodeIds);
113 });
114 }
115
116 // parse region id
117 RegionId regionId = RegionId.regionId(nullIsIllegal(json.get(REGION_ID),
118 REGION_ID + MISSING_MEMBER_MESSAGE).asText());
119
120 // parse region name
121 String name = nullIsIllegal(json.get(NAME), NAME +
122 MISSING_MEMBER_MESSAGE).asText();
123
124 // parse region type
125 String typeText = nullIsIllegal(json.get(TYPE), TYPE +
126 MISSING_MEMBER_MESSAGE).asText();
127
128 Region.Type type = REGION_TYPE_MAP.get(typeText);
129
130 return new DefaultRegion(regionId, name, type, masters);
131 }
132
133 /**
134 * Decodes node id json to node id object.
135 *
136 * @param json json object
137 * @return decoded node id object
138 */
139 private NodeId decodeNodeId(ObjectNode json) {
140 NodeId nodeId = NodeId.nodeId(nullIsIllegal(json, NODE_ID +
141 MISSING_MEMBER_MESSAGE).asText());
142
143 return nodeId;
144 }
145}