blob: 29543bfe028f43a419b51b71e28fe4e19a3dcef2 [file] [log] [blame]
Carmelo Cascone0831efb2016-05-31 14:50:19 -07001/*
2 * Copyright 2016-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 */
16
17package org.onosproject.drivers.bmv2;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
Carmelo Casconefbc577b2016-06-17 23:19:09 -070021import org.onlab.osgi.ServiceNotFoundException;
Carmelo Cascone0831efb2016-05-31 14:50:19 -070022import org.onlab.packet.ChassisId;
23import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent;
24import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
25import org.onosproject.bmv2.api.service.Bmv2Controller;
26import org.onosproject.net.AnnotationKeys;
27import org.onosproject.net.DefaultAnnotations;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.PortNumber;
30import org.onosproject.net.device.DefaultDeviceDescription;
31import org.onosproject.net.device.DefaultPortDescription;
32import org.onosproject.net.device.DeviceDescription;
33import org.onosproject.net.device.DeviceDescriptionDiscovery;
34import org.onosproject.net.device.PortDescription;
35import org.onosproject.net.driver.AbstractHandlerBehaviour;
36import org.slf4j.Logger;
37import org.slf4j.LoggerFactory;
38
39import java.math.BigInteger;
40import java.util.List;
41
42import static org.onosproject.bmv2.api.runtime.Bmv2Device.*;
43import static org.onosproject.net.Device.Type.SWITCH;
44
45/**
46 * Implementation of the device description discovery behaviour for BMv2.
47 */
48public class Bmv2DeviceDescriptionDiscovery extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery {
49
50 private static final String JSON_CONFIG_MD5 = "bmv2JsonConfigMd5";
51 private static final String PROCESS_INSTANCE_ID = "bmv2ProcessInstanceId";
52
53 private final Logger log = LoggerFactory.getLogger(this.getClass());
54
55 private Bmv2Controller controller;
56
57 private boolean init() {
Carmelo Casconefbc577b2016-06-17 23:19:09 -070058 try {
59 controller = handler().get(Bmv2Controller.class);
60 return true;
61 } catch (ServiceNotFoundException e) {
62 log.warn(e.getMessage());
Carmelo Cascone0831efb2016-05-31 14:50:19 -070063 return false;
64 }
Carmelo Cascone0831efb2016-05-31 14:50:19 -070065 }
66
67 @Override
68 public DeviceDescription discoverDeviceDetails() {
69
70 if (!init()) {
71 return null;
72 }
73
74 DeviceId deviceId = handler().data().deviceId();
75
76 Bmv2DeviceAgent deviceAgent;
77 try {
78 deviceAgent = controller.getAgent(deviceId);
79 } catch (Bmv2RuntimeException e) {
80 log.error("Failed to connect to Bmv2 device", e);
81 return null;
82 }
83
84 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder();
85
86 try {
87 String md5 = deviceAgent.getJsonConfigMd5();
88 BigInteger i = new BigInteger(1, md5.getBytes());
89 annotationsBuilder.set(JSON_CONFIG_MD5, String.format("%1$032X", i).toLowerCase());
90 } catch (Bmv2RuntimeException e) {
91 log.warn("Unable to dump JSON configuration from {}: {}", deviceId, e.explain());
92 }
93 try {
94 int instanceId = deviceAgent.getProcessInstanceId();
95 annotationsBuilder.set(PROCESS_INSTANCE_ID, String.valueOf(instanceId));
96 } catch (Bmv2RuntimeException e) {
97 log.warn("Unable to get process instance ID from {}: {}", deviceId, e.explain());
98 }
99
100 annotationsBuilder.set(AnnotationKeys.PROTOCOL, PROTOCOL);
101
102 return new DefaultDeviceDescription(deviceId.uri(),
103 SWITCH,
104 MANUFACTURER,
105 HW_VERSION,
106 SW_VERSION,
107 SERIAL_NUMBER,
108 new ChassisId(),
109 annotationsBuilder.build());
110 }
111
112 @Override
113 public List<PortDescription> discoverPortDetails() {
114
115 if (!init()) {
116 return null;
117 }
118
119 DeviceId deviceId = handler().data().deviceId();
120
121 Bmv2DeviceAgent deviceAgent;
122 try {
123 deviceAgent = controller.getAgent(deviceId);
124 } catch (Bmv2RuntimeException e) {
125 log.error("Failed to connect to Bmv2 device", e);
126 return null;
127 }
128
129 List<PortDescription> portDescriptions = Lists.newArrayList();
130
131 try {
132 deviceAgent.getPortsInfo().forEach(p -> {
133 PortNumber portNumber = PortNumber.portNumber((long) p.number(), p.ifaceName());
134 portDescriptions.add(new DefaultPortDescription(portNumber, p.isUp(), DefaultAnnotations.EMPTY));
135 });
136 } catch (Bmv2RuntimeException e) {
137 log.error("Unable to get port descriptions of {}: {}", deviceId, e);
138 }
139
140 return ImmutableList.copyOf(portDescriptions);
141 }
142}