[ONOS-5795] OFDeviceProvider: save driver info in Device object

The Device object has an annotation field that can store driver
information. Doing so prevents us from extremely frequent calls
to find out which driver to use for a Device.

Calls to "getDrivers" can be responsible for a relevant part of
CPU usage in larger topologies.

Change-Id: Ie9d54f86efed75206639d270373361b4ea060a8a
diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index 0df2c8c..dc5ef97 100644
--- a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -76,7 +76,9 @@
 import org.onosproject.net.device.DeviceProviderService;
 import org.onosproject.net.device.PortDescription;
 import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.driver.Driver;
 import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
 import org.onosproject.net.driver.HandlerBehaviour;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
@@ -152,6 +154,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ComponentConfigService cfgService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
     private DeviceProviderService providerService;
 
     private final InternalDeviceProvider listener = new InternalDeviceProvider();
@@ -374,11 +379,19 @@
 
             ChassisId cId = new ChassisId(dpid.value());
 
-            SparseAnnotations annotations = DefaultAnnotations.builder()
+            DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
                     .set(AnnotationKeys.PROTOCOL, sw.factory().getVersion().toString())
                     .set(AnnotationKeys.CHANNEL_ID, sw.channelId())
-                    .set(AnnotationKeys.MANAGEMENT_ADDRESS, sw.channelId().split(":")[0])
-                    .build();
+                    .set(AnnotationKeys.MANAGEMENT_ADDRESS, sw.channelId().split(":")[0]);
+
+            Driver driver = driverService.getDriver(sw.manufacturerDescription(),
+                    sw.hardwareDescription(),
+                    sw.softwareDescription());
+            if (driver != null) {
+                annotationsBuilder.set(AnnotationKeys.DRIVER, driver.name());
+            }
+
+            SparseAnnotations annotations = annotationsBuilder.build();
 
             DeviceDescription description =
                     new DefaultDeviceDescription(did.uri(), sw.deviceType(),
diff --git a/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java b/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java
index 9dd27a0..f8e4ffd 100644
--- a/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java
+++ b/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java
@@ -34,6 +34,7 @@
 import org.onosproject.net.device.DeviceProviderService;
 import org.onosproject.net.device.PortDescription;
 import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.driver.DriverServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.OpenFlowController;
@@ -89,6 +90,7 @@
         provider.providerRegistry = registry;
         provider.controller = controller;
         provider.cfgService = new ComponentConfigAdapter();
+        provider.driverService = new DriverServiceAdapter();
         controller.switchMap.put(DPID1, SW1);
         provider.activate(null);
         assertNotNull("provider should be registered", registry.provider);