blob: 111372cb59a89c4bcee24e291910cc31776eeeba [file] [log] [blame]
Jian Lic87b23b2017-04-24 15:28:10 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Jian Lic87b23b2017-04-24 15:28:10 +09003 *
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;
Ray Milkey86ad7bb2018-09-27 12:32:28 -070022import org.apache.karaf.shell.api.action.Argument;
23import org.apache.karaf.shell.api.action.Command;
24import org.apache.karaf.shell.api.action.Option;
Jian Lic87b23b2017-04-24 15:28:10 +090025import 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
Jian Li6e960ef2017-05-03 16:38:19 +090047 private static final String DB = "database";
48 private static final String CACHE = "cache";
Jian Lic87b23b2017-04-24 15:28:10 +090049
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
Jian Li6e960ef2017-05-03 16:38:19 +090062 private static final String TYPE_NOT_NULL = "Mapping store type should not be null";
63 private static final String TYPE_ILLEGAL = "Mapping store type is not correct";
64
Jian Lic87b23b2017-04-24 15:28:10 +090065 @Argument(index = 0, name = "type",
66 description = "Shows mappings with specified type",
67 required = true, multiValued = false)
68 private String type = null;
69
70 @Argument(index = 1, name = "deviceId", description = "Device identity",
71 required = false, multiValued = false)
72 private String deviceId = null;
73
74 @Option(name = "-s", aliases = "--short",
75 description = "Print more succinct output for each mapping",
76 required = false, multiValued = false)
77 private boolean shortOutput = false;
78
79 private MappingService mappingService =
80 AbstractShellCommand.get(MappingService.class);
Jian Lida1dfa62017-04-25 01:56:19 +090081 private List<MappingEntry> mappings;
Jian Lic87b23b2017-04-24 15:28:10 +090082
83 @Override
Ray Milkey86ad7bb2018-09-27 12:32:28 -070084 protected void doExecute() {
Jian Lic87b23b2017-04-24 15:28:10 +090085
Jian Li6e960ef2017-05-03 16:38:19 +090086 MappingStore.Type typeEnum = getTypeEnum(type);
Jian Lic87b23b2017-04-24 15:28:10 +090087
88 DeviceService deviceService = get(DeviceService.class);
89 Iterable<Device> devices = deviceService.getDevices();
90
Jian Lida1dfa62017-04-25 01:56:19 +090091 if (outputJson()) {
92 print(JSON_FORMAT, json(typeEnum, devices));
Jian Lic87b23b2017-04-24 15:28:10 +090093 } else {
Jian Lida1dfa62017-04-25 01:56:19 +090094 if (deviceId != null) {
95 mappings = newArrayList(mappingService.getMappingEntries(typeEnum,
96 DeviceId.deviceId(deviceId)));
97 printMappings(DeviceId.deviceId(deviceId), mappings);
Jian Lic87b23b2017-04-24 15:28:10 +090098
Jian Lida1dfa62017-04-25 01:56:19 +090099 } else {
100
101 for (Device d : devices) {
102 mappings = newArrayList(mappingService.getMappingEntries(typeEnum, d.id()));
103 printMappings(d.id(), mappings);
104 }
Jian Lic87b23b2017-04-24 15:28:10 +0900105 }
106 }
107 }
108
109 /**
110 * Prints out mapping information.
111 *
112 * @param deviceId device identifier
113 * @param mappings a collection of mapping
114 */
Jian Lida1dfa62017-04-25 01:56:19 +0900115 private void printMappings(DeviceId deviceId, List<MappingEntry> mappings) {
Jian Lic87b23b2017-04-24 15:28:10 +0900116
117 print(SUMMARY_FORMAT, deviceId, mappings.size());
118
Jian Lida1dfa62017-04-25 01:56:19 +0900119 for (MappingEntry m : mappings) {
Jian Lic87b23b2017-04-24 15:28:10 +0900120 print(MAPPING_ID_FORMAT, Long.toHexString(m.id().value()));
Jian Lida1dfa62017-04-25 01:56:19 +0900121 print(MAPPING_STATE_FORMAT, m.state().name());
Jian Lic87b23b2017-04-24 15:28:10 +0900122 print(MAPPING_KEY_FORMAT, printMappingKey(m.key()));
123 printMappingValue(m.value());
124 }
125 }
126
127 /**
128 * Prints out mapping key.
129 *
130 * @param key mapping key
131 * @return string format of mapping key
132 */
133 private String printMappingKey(MappingKey key) {
134 StringBuilder builder = new StringBuilder();
135
136 if (key.address() != null) {
137 builder.append(key.address().toString());
138 }
139
140 return builder.toString();
141 }
142
143 /**
144 * Prints out mapping value.
145 *
146 * @param value mapping value
147 * @return string format of mapping value
148 */
149 private void printMappingValue(MappingValue value) {
150
151 print(MAPPING_VALUE_FORMAT);
152
153 if (value.action() != null) {
154 print(MAPPING_ACTION_FORMAT, value.action().toString());
155 }
156
157 if (!value.treatments().isEmpty()) {
158 print(MAPPING_TREATMENTS_FORMAT);
159 for (MappingTreatment treatment : value.treatments()) {
160 printMappingTreatment(treatment);
161 }
162 }
163
164 }
165
166 /**
167 * Prints out mapping treatment.
168 *
169 * @param treatment mapping treatment
170 * @return string format of mapping treatment
171 */
172 private void printMappingTreatment(MappingTreatment treatment) {
173 if (treatment != null) {
174 if (shortOutput) {
175 print(MAPPING_TREATMENT_SHORT_FORMAT, treatment.address());
176 } else {
177 print(MAPPING_TREATMENT_LONG_FORMAT, treatment.address(),
178 treatment.instructions());
179 }
180 }
181 }
Jian Lida1dfa62017-04-25 01:56:19 +0900182
183 /**
Jian Li6e960ef2017-05-03 16:38:19 +0900184 * Returns corresponding type enumeration based on the given
185 * string formatted type.
186 *
187 * @param type string formatted type
188 * @return type enumeration
189 */
190 private MappingStore.Type getTypeEnum(String type) {
191
192 if (type == null) {
193 throw new IllegalArgumentException(TYPE_NOT_NULL);
194 }
195
196 switch (type) {
197 case DB:
198 return MappingStore.Type.MAP_DATABASE;
199 case CACHE:
200 return MappingStore.Type.MAP_CACHE;
201 default:
202 throw new IllegalArgumentException(TYPE_ILLEGAL);
203 }
204 }
205
206 /**
Jian Lida1dfa62017-04-25 01:56:19 +0900207 * Generates JSON object with the mappings of the given device.
208 *
209 * @param mapper object mapper
210 * @param device device
211 * @param mappings a collection of mappings
212 * @return JSON object
213 */
214 private ObjectNode json(ObjectMapper mapper, Device device, List<MappingEntry> mappings) {
215 ObjectNode result = mapper.createObjectNode();
216 ArrayNode array = mapper.createArrayNode();
217
218 mappings.forEach(mapping -> array.add(jsonForEntity(mapping, MappingEntry.class)));
219
220 result.put("device", device.id().toString())
221 .put("mappingCount", mappings.size())
222 .set("mappings", array);
223 return result;
224 }
225
226 /**
227 * Generates JSON object with the mappings of all devices.
228 *
229 * @param type mapping store type
230 * @param devices a collection of devices
231 * @return JSON object
232 */
233 private JsonNode json(MappingStore.Type type, Iterable<Device> devices) {
234 ObjectMapper mapper = new ObjectMapper();
235 ArrayNode result = mapper.createArrayNode();
236 for (Device device : devices) {
237 result.add(json(mapper, device,
238 newArrayList(mappingService.getMappingEntries(type, device.id()))));
239 }
240 return result;
241 }
242}