blob: f560c8328ea49a09f518389e08099e3eef774a89 [file] [log] [blame]
Thomas Vachuska9252bc32014-10-23 02:33:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska9252bc32014-10-23 02:33:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska9252bc32014-10-23 02:33:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska9252bc32014-10-23 02:33:25 -070015 */
16package org.onlab.onos.rest;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import org.onlab.onos.net.ConnectPoint;
20import org.onlab.onos.net.DefaultAnnotations;
21import org.onlab.onos.net.Device;
22import org.onlab.onos.net.Host;
23import org.onlab.onos.net.HostId;
24import org.onlab.onos.net.HostLocation;
25import org.onlab.onos.net.Link;
26import org.onlab.onos.net.MastershipRole;
27import org.onlab.onos.net.SparseAnnotations;
28import org.onlab.onos.net.device.DefaultDeviceDescription;
29import org.onlab.onos.net.device.DeviceDescription;
30import org.onlab.onos.net.device.DeviceProvider;
31import org.onlab.onos.net.device.DeviceProviderRegistry;
32import org.onlab.onos.net.device.DeviceProviderService;
33import org.onlab.onos.net.host.DefaultHostDescription;
34import org.onlab.onos.net.host.HostProvider;
35import org.onlab.onos.net.host.HostProviderRegistry;
36import org.onlab.onos.net.host.HostProviderService;
37import org.onlab.onos.net.link.DefaultLinkDescription;
38import org.onlab.onos.net.link.LinkProvider;
39import org.onlab.onos.net.link.LinkProviderRegistry;
40import org.onlab.onos.net.link.LinkProviderService;
41import org.onlab.onos.net.provider.ProviderId;
42import org.onlab.packet.ChassisId;
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -070043import org.onlab.packet.IpAddress;
Thomas Vachuska9252bc32014-10-23 02:33:25 -070044import org.onlab.packet.MacAddress;
45import org.onlab.packet.VlanId;
46
47import java.net.URI;
48import java.util.Iterator;
49
50import static com.google.common.base.Preconditions.checkNotNull;
51import static org.onlab.onos.net.DeviceId.deviceId;
52import static org.onlab.onos.net.PortNumber.portNumber;
53
54/**
55 * Provider of devices and links parsed from a JSON configuration structure.
56 */
57class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
58
59 private static final ProviderId PID =
60 new ProviderId("cfg", "org.onlab.onos.rest", true);
61
62 private final JsonNode cfg;
63 private final DeviceProviderRegistry deviceProviderRegistry;
64 private final LinkProviderRegistry linkProviderRegistry;
65 private final HostProviderRegistry hostProviderRegistry;
66
67 /**
68 * Creates a new configuration provider.
69 *
70 * @param cfg JSON configuration
71 * @param deviceProviderRegistry device provider registry
72 * @param linkProviderRegistry link provider registry
73 * @param hostProviderRegistry host provider registry
74 */
75 ConfigProvider(JsonNode cfg,
76 DeviceProviderRegistry deviceProviderRegistry,
77 LinkProviderRegistry linkProviderRegistry,
78 HostProviderRegistry hostProviderRegistry) {
79 this.cfg = checkNotNull(cfg, "Configuration cannot be null");
80 this.deviceProviderRegistry = checkNotNull(deviceProviderRegistry, "Device provider registry cannot be null");
81 this.linkProviderRegistry = checkNotNull(linkProviderRegistry, "Link provider registry cannot be null");
82 this.hostProviderRegistry = checkNotNull(hostProviderRegistry, "Host provider registry cannot be null");
83 }
84
85 /**
86 * Parses the given JSON and provides links as configured.
87 */
88 void parse() {
89 parseDevices();
90 parseLinks();
91 parseHosts();
92 }
93
94 // Parses the given JSON and provides devices.
95 private void parseDevices() {
96 try {
97 DeviceProviderService dps = deviceProviderRegistry.register(this);
98 JsonNode nodes = cfg.get("devices");
99 if (nodes != null) {
100 for (JsonNode node : nodes) {
101 parseDevice(dps, node);
102 }
103 }
104 } finally {
105 deviceProviderRegistry.unregister(this);
106 }
107 }
108
109 // Parses the given node with device data and supplies the device.
110 private void parseDevice(DeviceProviderService dps, JsonNode node) {
111 URI uri = URI.create(get(node, "uri"));
112 Device.Type type = Device.Type.valueOf(get(node, "type"));
113 String mfr = get(node, "mfr");
114 String hw = get(node, "hw");
115 String sw = get(node, "sw");
116 String serial = get(node, "serial");
117 ChassisId cid = new ChassisId(get(node, "mac"));
118 SparseAnnotations annotations = annotations(node.get("annotations"));
119
120 DeviceDescription desc =
121 new DefaultDeviceDescription(uri, type, mfr, hw, sw, serial,
122 cid, annotations);
123 dps.deviceConnected(deviceId(uri), desc);
124 }
125
126 // Parses the given JSON and provides links as configured.
127 private void parseLinks() {
128 try {
129 LinkProviderService lps = linkProviderRegistry.register(this);
130 JsonNode nodes = cfg.get("links");
131 if (nodes != null) {
132 for (JsonNode node : nodes) {
133 parseLink(lps, node, false);
134 if (!node.has("halfplex")) {
135 parseLink(lps, node, true);
136 }
137 }
138 }
139 } finally {
140 linkProviderRegistry.unregister(this);
141 }
142 }
143
144 // Parses the given node with link data and supplies the link.
145 private void parseLink(LinkProviderService lps, JsonNode node, boolean reverse) {
146 ConnectPoint src = connectPoint(get(node, "src"));
147 ConnectPoint dst = connectPoint(get(node, "dst"));
148 Link.Type type = Link.Type.valueOf(get(node, "type"));
149 SparseAnnotations annotations = annotations(node.get("annotations"));
150
151 DefaultLinkDescription desc = reverse ?
152 new DefaultLinkDescription(dst, src, type, annotations) :
153 new DefaultLinkDescription(src, dst, type, annotations);
154 lps.linkDetected(desc);
155 }
156
157 // Parses the given JSON and provides hosts as configured.
158 private void parseHosts() {
159 try {
160 HostProviderService hps = hostProviderRegistry.register(this);
161 JsonNode nodes = cfg.get("hosts");
162 if (nodes != null) {
163 for (JsonNode node : nodes) {
164 parseHost(hps, node);
165 }
166 }
167 } finally {
168 hostProviderRegistry.unregister(this);
169 }
170 }
171
172 // Parses the given node with host data and supplies the host.
173 private void parseHost(HostProviderService hps, JsonNode node) {
174 MacAddress mac = MacAddress.valueOf(get(node, "mac"));
175 VlanId vlanId = VlanId.vlanId(node.get("vlan").shortValue());
176 HostId hostId = HostId.hostId(mac, vlanId);
177 SparseAnnotations annotations = annotations(node.get("annotations"));
178 HostLocation location = new HostLocation(connectPoint(get(node, "location")), 0);
Pavlin Radoslavov33f228a2014-10-27 19:33:16 -0700179 IpAddress ip = IpAddress.valueOf(get(node, "ip"));
Thomas Vachuska9252bc32014-10-23 02:33:25 -0700180
181 DefaultHostDescription desc =
182 new DefaultHostDescription(mac, vlanId, location, ip, annotations);
183 hps.hostDetected(hostId, desc);
184 }
185
186 // Produces set of annotations from the given JSON node.
187 private SparseAnnotations annotations(JsonNode node) {
188 if (node == null) {
189 return null;
190 }
191
192 DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
193 Iterator<String> it = node.fieldNames();
194 while (it.hasNext()) {
195 String k = it.next();
196 builder.set(k, node.get(k).asText());
197 }
198 return builder.build();
199 }
200
201 // Produces a connection point from the specified uri/port text.
202 private ConnectPoint connectPoint(String text) {
203 int i = text.lastIndexOf("/");
204 return new ConnectPoint(deviceId(text.substring(0, i)),
205 portNumber(text.substring(i + 1)));
206 }
207
208 // Returns string form of the named property in the given JSON object.
209 private String get(JsonNode node, String name) {
210 return node.path(name).asText();
211 }
212
213 @Override
214 public void triggerProbe(Device device) {
215 }
216
217 @Override
218 public void roleChanged(Device device, MastershipRole newRole) {
219 }
220
221 @Override
222 public void triggerProbe(Host host) {
223 }
224
225 @Override
226 public ProviderId id() {
227 return PID;
228 }
229}