[ONOS-6465] gRPC Protocol and controller

Change-Id: I0ae997f234ce95a78db2db1917f2cbbe3696ccfd
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java
new file mode 100644
index 0000000..4b76067
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.bmv2;
+
+import io.grpc.stub.StreamObserver;
+import org.onosproject.grpc.api.GrpcChannelId;
+import org.onosproject.grpc.api.GrpcController;
+import org.onosproject.grpc.api.GrpcObserverHandler;
+import org.onosproject.grpc.api.GrpcServiceId;
+import org.onosproject.grpc.api.GrpcStreamObserverId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketProgrammable;
+
+import java.util.Optional;
+
+/**
+ * Packet Programmable behaviour for BMv2 devices.
+ */
+public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements PacketProgrammable {
+    @Override
+    public void emit(OutboundPacket packet) {
+        DriverHandler handler = handler();
+        GrpcController controller = handler.get(GrpcController.class);
+        DeviceId deviceId = handler.data().deviceId();
+        GrpcChannelId channelId = GrpcChannelId.of(deviceId, "bmv2");
+        GrpcServiceId serviceId = GrpcServiceId.of(channelId, "p4runtime");
+        GrpcStreamObserverId observerId = GrpcStreamObserverId.of(serviceId,
+                this.getClass().getSimpleName());
+        Optional<GrpcObserverHandler> manager = controller.getObserverManager(observerId);
+        if (!manager.isPresent()) {
+            //this is the first time the behaviour is called
+            controller.addObserver(observerId, new Bmv2PacketInObserverHandler());
+        }
+        //other already registered the observer for us.
+        Optional<StreamObserver> observer = manager.get().requestStreamObserver();
+        observer.ifPresent(objectStreamObserver -> objectStreamObserver.onNext(packet));
+    }
+}