blob: de5c0c99b69c12c267aefdb9119a91ce5ebf29d8 [file] [log] [blame]
Jian Lic87b23b2017-04-24 15:28:10 +09001/*
2 * Copyright 2017-present 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.mapping.cli;
17
Jian Lida1dfa62017-04-25 01:56:19 +090018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.ObjectNode;
Jian Lic87b23b2017-04-24 15:28:10 +090022import org.apache.karaf.shell.commands.Argument;
23import org.apache.karaf.shell.commands.Command;
24import org.apache.karaf.shell.commands.Option;
25import org.onosproject.cli.AbstractShellCommand;
Jian Lida1dfa62017-04-25 01:56:19 +090026import org.onosproject.mapping.MappingEntry;
Jian Lic87b23b2017-04-24 15:28:10 +090027import org.onosproject.mapping.MappingKey;
28import org.onosproject.mapping.MappingTreatment;
29import org.onosproject.mapping.MappingValue;
30import org.onosproject.mapping.MappingService;
31import org.onosproject.mapping.MappingStore;
32import org.onosproject.net.Device;
33import org.onosproject.net.DeviceId;
34import org.onosproject.net.device.DeviceService;
35
36import java.util.List;
37
38import static com.google.common.collect.Lists.newArrayList;
39
40/**
41 * A command for querying mapping information.
42 */
43@Command(scope = "onos", name = "mappings",
44 description = "Lists mappings")
45public class MappingsListCommand extends AbstractShellCommand {
46
47 private static final String DB = "map_database";
48 private static final String CACHE = "map_cache";
49
50 private static final String SUMMARY_FORMAT = "deviceId=%s, mappingCount=%d";
51 private static final String MAPPING_ID_FORMAT = " id=%s";
Jian Lida1dfa62017-04-25 01:56:19 +090052 private static final String MAPPING_STATE_FORMAT = " state=%s";
Jian Lic87b23b2017-04-24 15:28:10 +090053 private static final String MAPPING_KEY_FORMAT = " key=%s";
54 private static final String MAPPING_VALUE_FORMAT = " value=";
55 private static final String MAPPING_ACTION_FORMAT = " action=%s";
56 private static final String MAPPING_TREATMENTS_FORMAT = " treatments=";
57 private static final String MAPPING_TREATMENT_LONG_FORMAT =
58 " address=%s, instructions=%s";
59 private static final String MAPPING_TREATMENT_SHORT_FORMAT = " %s";
Jian Lida1dfa62017-04-25 01:56:19 +090060 private static final String JSON_FORMAT = "%s";
Jian Lic87b23b2017-04-24 15:28:10 +090061
62 @Argument(index = 0, name = "type",
63 description = "Shows mappings with specified type",
64 required = true, multiValued = false)
65 private String type = null;
66
67 @Argument(index = 1, name = "deviceId", description = "Device identity",
68 required = false, multiValued = false)
69 private String deviceId = null;
70
71 @Option(name = "-s", aliases = "--short",
72 description = "Print more succinct output for each mapping",
73 required = false, multiValued = false)
74 private boolean shortOutput = false;
75
76 private MappingService mappingService =
77 AbstractShellCommand.get(MappingService.class);
Jian Lida1dfa62017-04-25 01:56:19 +090078 private List<MappingEntry> mappings;
Jian Lic87b23b2017-04-24 15:28:10 +090079
80 @Override
81 protected void execute() {
82
83 MappingStore.Type typeEnum = null;
84
85 if (type.equals(DB)) {
86 typeEnum = MappingStore.Type.MAP_DATABASE;
87 } else if (type.equals(CACHE)) {
88 typeEnum = MappingStore.Type.MAP_CACHE;
89 }
90
91 DeviceService deviceService = get(DeviceService.class);
92 Iterable<Device> devices = deviceService.getDevices();
93
Jian Lida1dfa62017-04-25 01:56:19 +090094 if (outputJson()) {
95 print(JSON_FORMAT, json(typeEnum, devices));
Jian Lic87b23b2017-04-24 15:28:10 +090096 } else {
Jian Lida1dfa62017-04-25 01:56:19 +090097 if (deviceId != null) {
98 mappings = newArrayList(mappingService.getMappingEntries(typeEnum,
99 DeviceId.deviceId(deviceId)));
100 printMappings(DeviceId.deviceId(deviceId), mappings);
Jian Lic87b23b2017-04-24 15:28:10 +0900101
Jian Lida1dfa62017-04-25 01:56:19 +0900102 } else {
103
104 for (Device d : devices) {
105 mappings = newArrayList(mappingService.getMappingEntries(typeEnum, d.id()));
106 printMappings(d.id(), mappings);
107 }
Jian Lic87b23b2017-04-24 15:28:10 +0900108 }
109 }
110 }
111
112 /**
113 * Prints out mapping information.
114 *
115 * @param deviceId device identifier
116 * @param mappings a collection of mapping
117 */
Jian Lida1dfa62017-04-25 01:56:19 +0900118 private void printMappings(DeviceId deviceId, List<MappingEntry> mappings) {
Jian Lic87b23b2017-04-24 15:28:10 +0900119
120 print(SUMMARY_FORMAT, deviceId, mappings.size());
121
Jian Lida1dfa62017-04-25 01:56:19 +0900122 for (MappingEntry m : mappings) {
Jian Lic87b23b2017-04-24 15:28:10 +0900123 print(MAPPING_ID_FORMAT, Long.toHexString(m.id().value()));
Jian Lida1dfa62017-04-25 01:56:19 +0900124 print(MAPPING_STATE_FORMAT, m.state().name());
Jian Lic87b23b2017-04-24 15:28:10 +0900125 print(MAPPING_KEY_FORMAT, printMappingKey(m.key()));
126 printMappingValue(m.value());
127 }
128 }
129
130 /**
131 * Prints out mapping key.
132 *
133 * @param key mapping key
134 * @return string format of mapping key
135 */
136 private String printMappingKey(MappingKey key) {
137 StringBuilder builder = new StringBuilder();
138
139 if (key.address() != null) {
140 builder.append(key.address().toString());
141 }
142
143 return builder.toString();
144 }
145
146 /**
147 * Prints out mapping value.
148 *
149 * @param value mapping value
150 * @return string format of mapping value
151 */
152 private void printMappingValue(MappingValue value) {
153
154 print(MAPPING_VALUE_FORMAT);
155
156 if (value.action() != null) {
157 print(MAPPING_ACTION_FORMAT, value.action().toString());
158 }
159
160 if (!value.treatments().isEmpty()) {
161 print(MAPPING_TREATMENTS_FORMAT);
162 for (MappingTreatment treatment : value.treatments()) {
163 printMappingTreatment(treatment);
164 }
165 }
166
167 }
168
169 /**
170 * Prints out mapping treatment.
171 *
172 * @param treatment mapping treatment
173 * @return string format of mapping treatment
174 */
175 private void printMappingTreatment(MappingTreatment treatment) {
176 if (treatment != null) {
177 if (shortOutput) {
178 print(MAPPING_TREATMENT_SHORT_FORMAT, treatment.address());
179 } else {
180 print(MAPPING_TREATMENT_LONG_FORMAT, treatment.address(),
181 treatment.instructions());
182 }
183 }
184 }
Jian Lida1dfa62017-04-25 01:56:19 +0900185
186 /**
187 * Generates JSON object with the mappings of the given device.
188 *
189 * @param mapper object mapper
190 * @param device device
191 * @param mappings a collection of mappings
192 * @return JSON object
193 */
194 private ObjectNode json(ObjectMapper mapper, Device device, List<MappingEntry> mappings) {
195 ObjectNode result = mapper.createObjectNode();
196 ArrayNode array = mapper.createArrayNode();
197
198 mappings.forEach(mapping -> array.add(jsonForEntity(mapping, MappingEntry.class)));
199
200 result.put("device", device.id().toString())
201 .put("mappingCount", mappings.size())
202 .set("mappings", array);
203 return result;
204 }
205
206 /**
207 * Generates JSON object with the mappings of all devices.
208 *
209 * @param type mapping store type
210 * @param devices a collection of devices
211 * @return JSON object
212 */
213 private JsonNode json(MappingStore.Type type, Iterable<Device> devices) {
214 ObjectMapper mapper = new ObjectMapper();
215 ArrayNode result = mapper.createArrayNode();
216 for (Device device : devices) {
217 result.add(json(mapper, device,
218 newArrayList(mappingService.getMappingEntries(type, device.id()))));
219 }
220 return result;
221 }
222}