[ONOS-6465] gRPC Protocol and controller
Change-Id: I0ae997f234ce95a78db2db1917f2cbbe3696ccfd
diff --git a/protocols/grpc/api/BUCK b/protocols/grpc/api/BUCK
new file mode 100644
index 0000000..66efde3
--- /dev/null
+++ b/protocols/grpc/api/BUCK
@@ -0,0 +1,12 @@
+COMPILE_DEPS = [
+ '//lib:CORE_DEPS',
+ '//lib:grpc-core-1.3.0',
+ '//lib:grpc-protobuf-1.3.0',
+ '//lib:grpc-stub-1.3.0',
+ '//lib:grpc-netty-1.3.0',
+ '//lib:grpc-auth-1.3.0',
+]
+
+osgi_jar_with_tests (
+ deps = COMPILE_DEPS,
+)
diff --git a/protocols/grpc/api/pom.xml b/protocols/grpc/api/pom.xml
new file mode 100644
index 0000000..4841ca3
--- /dev/null
+++ b/protocols/grpc/api/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2016-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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>onos-grpc-protocol</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.11.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <packaging>bundle</packaging>
+
+ <artifactId>onos-grpc-protocol-api</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr.annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-serializers</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-stub</artifactId>
+ <version>1.3.0</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcChannelId.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcChannelId.java
new file mode 100644
index 0000000..c1fdbf1
--- /dev/null
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcChannelId.java
@@ -0,0 +1,81 @@
+/*
+ * 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.grpc.api;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+import org.onosproject.net.DeviceId;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * gRPCChannel identifier suitable as an external key.
+ * <p>
+ * This class is immutable.</p>
+ */
+@Beta
+public final class GrpcChannelId extends Identifier<String> {
+
+ private final DeviceId deviceId;
+
+ private final String channelName;
+
+ /**
+ * Instantiates a new GrpcChannel id.
+ *
+ * @param deviceId the device id
+ * @param channelName the name of the channel
+ */
+ private GrpcChannelId(DeviceId deviceId, String channelName) {
+ super(deviceId.toString() + ":" + channelName);
+ checkNotNull(deviceId, "device id must not be null");
+ checkNotNull(channelName, "channel name must not be null");
+ checkArgument(!channelName.isEmpty(), "channel name must not be empty");
+ this.deviceId = deviceId;
+ this.channelName = channelName;
+ }
+
+ /**
+ * Returns the deviceId of the device that uses this channel.
+ *
+ * @return the device Id
+ */
+ public DeviceId deviceId() {
+ return deviceId;
+ }
+
+ /**
+ * Returns the channel name.
+ *
+ * @return the channel name
+ */
+ public String channelName() {
+ return channelName;
+ }
+
+ /**
+ * Creates a grpc channel identifier from the specified device id and name provided.
+ *
+ * @param id device id
+ * @param channelName name of the channel
+ * @return channel name
+ */
+ public static GrpcChannelId of(DeviceId id, String channelName) {
+ return new GrpcChannelId(id, channelName);
+ }
+}
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcController.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcController.java
new file mode 100644
index 0000000..f1e279a
--- /dev/null
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcController.java
@@ -0,0 +1,102 @@
+/*
+ * 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.grpc.api;
+
+import com.google.common.annotations.Beta;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.onosproject.net.DeviceId;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Abstraction of a gRPC controller. Serves as a one stop shop for obtaining
+ * gRCP ManagedChannels to interact with devices and (un)register observers on event streams from the device.
+ */
+@Beta
+public interface GrpcController {
+
+ /**
+ * Adds a StreamObserver on a channel specific for a device.
+ *
+ * @param observerId the id of the observer
+ * @param grpcObserverHandler the manager for the stream.
+ */
+ void addObserver(GrpcStreamObserverId observerId, GrpcObserverHandler grpcObserverHandler);
+
+ /**
+ * Removes the StreamObserver on a channel specific for a device.
+ *
+ * @param observerId the id of the observer
+ */
+ void removeObserver(GrpcStreamObserverId observerId);
+
+ /**
+ * If present returns the stream observer manager previously added for the given device.
+ *
+ * @param observerId the id of the observer.
+ * @return the ObserverManager
+ */
+ Optional<GrpcObserverHandler> getObserverManager(GrpcStreamObserverId observerId);
+
+ /**
+ * Tries to connect to a specific gRPC device, if the connection is successful
+ * returns the ManagedChannel. This method blocks until the channel is setup or a timeout expires.
+ * By default the timeout is 20 seconds. If the timeout expires and thus the channel can't be set up
+ * a IOException is thrown.
+ *
+ * @param channelId the id of the channel
+ * @param channelBuilder the builder for the managed channel.
+ * @return the ManagedChannel created.
+ * @throws IOException if channel can't be setup.
+ */
+ ManagedChannel connectChannel(GrpcChannelId channelId, ManagedChannelBuilder<?> channelBuilder) throws IOException;
+
+ /**
+ * Disconnects a gRPC device by removing it's ManagedChannel from this controller.
+ *
+ * @param channelId id of the service to remove
+ */
+ void disconnectChannel(GrpcChannelId channelId);
+
+ /**
+ * Gets all ManagedChannels for the gRPC devices.
+ *
+ * @return Map of all the ManagedChannels with their identifier saved in this controller
+ */
+ Map<GrpcChannelId, ManagedChannel> getChannels();
+
+ /**
+ * Returns all ManagedChannels associated to the given device identifier.
+ *
+ * @param deviceId the device for which we are interested.
+ * @return collection of all the ManagedChannels saved in this controller
+ */
+ Collection<ManagedChannel> getChannels(DeviceId deviceId);
+
+ /**
+ * If present, returns the managed channel associated with the given identifier.
+ *
+ * @param channelId the id of the channel
+ * @return the ManagedChannel of the device.
+ */
+ Optional<ManagedChannel> getChannel(GrpcChannelId channelId);
+
+}
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcObserverHandler.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcObserverHandler.java
new file mode 100644
index 0000000..46a3967
--- /dev/null
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcObserverHandler.java
@@ -0,0 +1,53 @@
+/*
+ * 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.grpc.api;
+
+import com.google.common.annotations.Beta;
+import io.grpc.ManagedChannel;
+import io.grpc.stub.StreamObserver;
+
+import java.util.Optional;
+
+/**
+ * Implementation to add or remove an observer to the managed channel.
+ *
+ */
+@Beta
+public interface GrpcObserverHandler {
+ /**
+ * The implementation of this method adds an
+ * observer on a stub generated on the specific channel.
+ * This method will be called by the gRPC controller.
+ *
+ * @param channel the channel from which to derive the stub.
+ */
+ void bindObserver(ManagedChannel channel);
+
+ /**
+ * The implementation of this method returns the request stream
+ * observer, if any, on a stub generated on the specific channel.
+ *
+ * @return the observer on the stub, empty if observer is server-side unidirectional.
+ */
+ Optional<StreamObserver> requestStreamObserver();
+
+ /**
+ * The implementation of this method removes an
+ * observer on a stub generated on the specific channel.
+ * This method will be called by the gRPC controller.
+ */
+ void removeObserver();
+}
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcServiceId.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcServiceId.java
new file mode 100644
index 0000000..203ade6
--- /dev/null
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcServiceId.java
@@ -0,0 +1,81 @@
+/*
+ * 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.grpc.api;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * gRPCService identifier suitable as an external key.
+ * <p>
+ * This class is immutable.</p>
+ */
+@Beta
+public final class GrpcServiceId extends Identifier<String> {
+
+ private final GrpcChannelId channelId;
+
+ private final String serviceName;
+
+ /**
+ * Instantiates a new gRPC Service id.
+ *
+ * @param channelId the channel id
+ * @param serviceName the name of the service on that channel
+ */
+ private GrpcServiceId(GrpcChannelId channelId, String serviceName) {
+ super(channelId.toString() + ":" + serviceName);
+ checkNotNull(channelId, "channel id must not be null");
+ checkNotNull(serviceName, "service name must not be null");
+ checkArgument(!serviceName.isEmpty(), "service name must not be empty");
+ this.channelId = channelId;
+ this.serviceName = serviceName;
+ }
+
+ /**
+ * Returns the id of the channel that this service uses.
+ *
+ * @return the channel Id
+ */
+ public GrpcChannelId channelId() {
+ return channelId;
+ }
+
+ /**
+ * Returns the name of this service.
+ *
+ * @return the service name
+ */
+ public String serviceName() {
+ return serviceName;
+ }
+
+ /**
+ * Creates a gRPC Service identifier from the specified device id and
+ * service name provided.
+ *
+ * @param id channel id
+ * @param serviceName name of the service
+ * @return service name
+ */
+ public static GrpcServiceId of(GrpcChannelId id, String serviceName) {
+ return new GrpcServiceId(id, serviceName);
+ }
+}
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcStreamObserverId.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcStreamObserverId.java
new file mode 100644
index 0000000..911705a
--- /dev/null
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/GrpcStreamObserverId.java
@@ -0,0 +1,80 @@
+/*
+ * 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.grpc.api;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * GrpcStreamObserver identifier suitable as an external key.
+ * <p>
+ * This class is immutable.</p>
+ */
+@Beta
+public final class GrpcStreamObserverId extends Identifier<String> {
+
+ private GrpcServiceId serviceId;
+ private String streamName;
+
+ /**
+ * Instantiates a new GrpcStreamObserver id.
+ *
+ * @param serviceId the service id
+ * @param streamName the name of the stream on that device
+ */
+ private GrpcStreamObserverId(GrpcServiceId serviceId, String streamName) {
+ super(serviceId.toString() + ":" + streamName);
+ checkNotNull(serviceId, "service id must not be null");
+ checkNotNull(streamName, "stream name must not be null");
+ checkArgument(!streamName.isEmpty(), "stream name must not be empty");
+ this.serviceId = serviceId;
+ this.streamName = streamName;
+ }
+
+ /**
+ * Returns the id of the service that this stream observer uses.
+ *
+ * @return the service Id
+ */
+ public GrpcServiceId serviceId() {
+ return serviceId;
+ }
+
+ /**
+ * Returns the name of this stream.
+ *
+ * @return the stream name
+ */
+ public String streamName() {
+ return streamName;
+ }
+
+ /**
+ * Creates a gRPC Stream Observer identifier from the specified service id and
+ * stream name provided.
+ *
+ * @param id service id
+ * @param streamName stream name
+ * @return stream name
+ */
+ public static GrpcStreamObserverId of(GrpcServiceId id, String streamName) {
+ return new GrpcStreamObserverId(id, streamName);
+ }
+}
diff --git a/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/package-info.java b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/package-info.java
new file mode 100644
index 0000000..c3251db
--- /dev/null
+++ b/protocols/grpc/api/src/main/java/org/onosproject/grpc/api/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-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.
+ */
+
+/**
+ * gRPC protocol API.
+ */
+package org.onosproject.grpc.api;
\ No newline at end of file