[ONOS-6316]create gRPC northbound Host Service and add unit tests
Change-Id: I385f52576000affd2523579c6a6f4c6d57e69938
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ConnectPointProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ConnectPointProtoTranslator.java
index c0177fe..6620096 100644
--- a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ConnectPointProtoTranslator.java
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ConnectPointProtoTranslator.java
@@ -16,7 +16,7 @@
package org.onosproject.incubator.protobuf.models.net;
import org.onlab.packet.IpAddress;
-import org.onosproject.grpc.net.models.ConnectPointProtoOuterClass;
+import org.onosproject.grpc.net.models.ConnectPointProtoOuterClass.ConnectPointProto;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
@@ -40,7 +40,7 @@
* @param connectPoint gRPC message
* @return Optional of equivalent {@link org.onosproject.net.ConnectPoint} or empty if ElementId is not recognized
*/
- public static Optional<ConnectPoint> translate(ConnectPointProtoOuterClass.ConnectPointProto connectPoint) {
+ public static Optional<ConnectPoint> translate(ConnectPointProto connectPoint) {
switch (connectPoint.getElementIdCase()) {
case DEVICE_ID:
return Optional.of(new ConnectPoint(DeviceId.deviceId(connectPoint.getDeviceId()),
@@ -65,20 +65,18 @@
* @param connectPoint {@link org.onosproject.net.ConnectPoint}
* @return gRPC ConnectPoint message
*/
- public static ConnectPointProtoOuterClass.ConnectPointProto translate(ConnectPoint connectPoint) {
+ public static ConnectPointProto translate(ConnectPoint connectPoint) {
+
if (connectPoint.elementId() instanceof DeviceId) {
- return ConnectPointProtoOuterClass.ConnectPointProto.newBuilder()
- .setDeviceId(connectPoint.deviceId().toString())
+ return ConnectPointProto.newBuilder().setDeviceId(connectPoint.deviceId().toString())
.setPortNumber(connectPoint.port().toString())
.build();
} else if (connectPoint.elementId() instanceof HostId) {
- return ConnectPointProtoOuterClass.ConnectPointProto.newBuilder()
- .setHostId(connectPoint.hostId().toString())
+ return ConnectPointProto.newBuilder().setHostId(connectPoint.hostId().toString())
.setPortNumber(connectPoint.port().toString())
.build();
} else if (connectPoint.ipElementId() instanceof IpElementId) {
- return ConnectPointProtoOuterClass.ConnectPointProto.newBuilder()
- .setIpElementId(connectPoint.ipElementId().toString())
+ return ConnectPointProto.newBuilder().setIpElementId(connectPoint.ipElementId().toString())
.setPortNumber(connectPoint.port().toString())
.build();
} else {
@@ -87,8 +85,6 @@
}
}
-
// Utility class not intended for instantiation.
private ConnectPointProtoTranslator() {}
-}
-
+}
\ No newline at end of file
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostIdProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostIdProtoTranslator.java
new file mode 100644
index 0000000..859cca4
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostIdProtoTranslator.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.incubator.protobuf.models.net;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.grpc.net.models.HostIdProtoOuterClass.HostIdProto;
+import org.onosproject.net.HostId;
+
+/**
+ * gRPC HostIdProto message to equivalent ONOS HostId conversion related utilities.
+ */
+public final class HostIdProtoTranslator {
+
+ /**
+ * Translates gRPC HostId to {@link HostId}.
+ *
+ * @param hostId gRPC message
+ * @return {@link HostId}
+ */
+ public static HostId translate(HostIdProto hostId) {
+
+ if (hostId.equals(HostIdProto.getDefaultInstance())) {
+ return null;
+ }
+
+ return HostId.hostId(MacAddress.valueOf(hostId.getMac()), VlanId.vlanId((short) hostId.getVlanId()));
+ }
+
+ /**
+ * Translates {@link HostId} to gRPC HostId message.
+ *
+ * @param hostId {@link HostId}
+ * @return gRPC HostId message
+ */
+ public static HostIdProto translate(HostId hostId) {
+
+ if (hostId != null) {
+ return HostIdProto.newBuilder()
+ .setMac(hostId.mac().toString())
+ .setVlanId(hostId.vlanId().toShort())
+ .build();
+ }
+
+ return HostIdProto.getDefaultInstance();
+ }
+
+ // Utility class not intended for instantiation.
+ private HostIdProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostLocationProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostLocationProtoTranslator.java
new file mode 100644
index 0000000..098a276
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostLocationProtoTranslator.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.incubator.protobuf.models.net;
+
+import org.onosproject.grpc.net.models.ConnectPointProtoOuterClass.ConnectPointProto;
+import org.onosproject.grpc.net.models.HostLocationProtoOuterClass.HostLocationProto;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+
+/**
+ * gRPC HostLocationProto message to equivalent ONOS Host location conversion related utilities.
+ */
+public final class HostLocationProtoTranslator {
+
+ /**
+ * Translates gRPC HostLocation to {@link HostLocation}.
+ *
+ * @param hostLocation gRPC message
+ * @return {@link HostLocation}
+ */
+ public static HostLocation translate(HostLocationProto hostLocation) {
+
+ if (hostLocation.equals(HostLocationProto.getDefaultInstance())) {
+ return null;
+ }
+
+ return new HostLocation(DeviceId.deviceId(hostLocation.getConnectPoint().getDeviceId()),
+ PortNumber.portNumber(hostLocation.getConnectPoint().getPortNumber()), 0L);
+ }
+
+ /**
+ * Translates {@link HostLocation} to gRPC HostLocation message.
+ *
+ * @param hostLocation {@link HostLocation}
+ * @return gRPC HostLocation message
+ */
+ public static HostLocationProto translate(HostLocation hostLocation) {
+
+ if (hostLocation != null) {
+ return HostLocationProto.newBuilder()
+ .setConnectPoint(ConnectPointProto.newBuilder()
+ .setDeviceId(hostLocation.deviceId().toString())
+ .setPortNumber(hostLocation.port().toString()))
+ .setTime(hostLocation.time())
+ .build();
+ }
+
+ return HostLocationProto.getDefaultInstance();
+ }
+
+ // Utility class not intended for instantiation.
+ private HostLocationProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostProtoTranslator.java
new file mode 100644
index 0000000..c12fd7f
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/HostProtoTranslator.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.incubator.protobuf.models.net;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.grpc.net.models.HostProtoOuterClass.HostProto;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.Host;
+
+import java.util.stream.Collectors;
+
+/**
+ * gRPC HostProto message to equivalent ONOS Host conversion related utilities.
+ */
+public final class HostProtoTranslator {
+
+
+ /**
+ * Translates {@link Host} to gRPC Host message.
+ *
+ * @param host {@link Host}
+ * @return gRPC HostProto message
+ */
+ public static HostProto translate(Host host) {
+
+ if (host != null) {
+ return HostProto.newBuilder()
+ .setHostId(HostIdProtoTranslator.translate(host.id()))
+ .setConfigured(host.configured())
+ .setVlan(host.vlan().toShort())
+ .addAllIpAddresses(host.ipAddresses().stream()
+ .map(IpAddress::toString)
+ .collect(Collectors.toList()))
+ .setLocation(HostLocationProtoTranslator.translate(host.location()))
+ .build();
+ }
+
+ return HostProto.getDefaultInstance();
+ }
+
+ /**
+ * Translates gRPC Host message to {@link Host}.
+ *
+ * @param host gRPC message
+ * @return {@link Host}
+ */
+ public static Host translate(HostProto host) {
+ if (host.equals(HostProto.getDefaultInstance())) {
+ return null;
+ }
+
+ return new DefaultHost(ProviderIdProtoTranslator.translate(host.getProviderId()),
+ HostIdProtoTranslator.translate(host.getHostId()),
+ MacAddress.valueOf(host.getHostId().getMac()),
+ VlanId.vlanId((short) host.getVlan()),
+ HostLocationProtoTranslator.translate(host.getLocation()),
+ host.getIpAddressesList().stream().map(x -> IpAddress.valueOf(x))
+ .collect(Collectors.toSet()),
+ DefaultAnnotations.builder().putAll(host.getAnnotationsMap()).build());
+ }
+
+ // Utility class not intended for instantiation.
+ private HostProtoTranslator() {}
+}
diff --git a/incubator/protobuf/models/src/main/proto/net/HostProto.proto b/incubator/protobuf/models/src/main/proto/net/HostProto.proto
index 110e1ab..e5e7b5f 100644
--- a/incubator/protobuf/models/src/main/proto/net/HostProto.proto
+++ b/incubator/protobuf/models/src/main/proto/net/HostProto.proto
@@ -3,6 +3,7 @@
import "net/HostIdProto.proto";
import "net/HostLocationProto.proto";
+import "net/ProviderIdProto.proto";
package net;
@@ -13,5 +14,6 @@
net.HostLocationProto location = 3;
repeated string ip_addresses = 4;
bool configured = 5;
- map<string, string> annotations = 6;
+ net.ProviderIdProto provider_id = 6;
+ map<string, string> annotations = 7;
}
\ No newline at end of file
diff --git a/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbHostService.java b/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbHostService.java
new file mode 100644
index 0000000..d5e3660
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbHostService.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.incubator.protobuf.services.nb;
+
+import com.google.common.annotations.Beta;
+import io.grpc.BindableService;
+import io.grpc.stub.StreamObserver;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.onosproject.protobuf.api.GrpcServiceRegistry;
+import org.slf4j.Logger;
+import org.onosproject.grpc.nb.net.host.HostServiceGrpc.HostServiceImplBase;
+import org.onosproject.incubator.protobuf.models.net.ConnectPointProtoTranslator;
+import org.onosproject.incubator.protobuf.models.net.HostProtoTranslator;
+
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostCountRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostCountReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsByVlanRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsByVlanReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsByMacRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsByMacReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsByIpRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getHostsByIpReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getConnectedHostsRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.getConnectedHostsReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.startMonitoringIpRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.startMonitoringIpReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.stopMonitoringIpRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.stopMonitoringIpReply;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.requestMacRequest;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.requestMacReply;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * A server that provides access to the methods exposed by {@link HostService}.
+ */
+@Beta
+@Component(immediate = true)
+public class GrpcNbHostService {
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected GrpcServiceRegistry registry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostService hostService;
+
+ private static HostServiceNBServerInternal instance = null;
+
+ @Activate
+ public void activate() {
+
+ registry.register(getInnerInstance());
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+
+ registry.unregister(getInnerInstance());
+ log.info("Stoped");
+ }
+
+ /**
+ * Register Host Service, Used for unit testing purposes.
+ *
+ * @return An instance of binding Host service
+ */
+ public InProcessServer<BindableService> registerInProcessServer() {
+ InProcessServer<BindableService> inprocessServer =
+ new InProcessServer(HostServiceNBServerInternal.class);
+ inprocessServer.addServiceToBind(getInnerInstance());
+
+ return inprocessServer;
+ }
+
+ /**
+ * Host Service NorthBound implementation.
+ */
+ private final class HostServiceNBServerInternal extends HostServiceImplBase {
+
+ private HostServiceNBServerInternal() {
+ super();
+ }
+
+ @Override
+ public void getHostCount(getHostCountRequest request,
+ StreamObserver<getHostCountReply> responseObserver) {
+
+ responseObserver.onNext(getHostCountReply.newBuilder()
+ .setHostCount(hostService.getHostCount())
+ .build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void getHosts(getHostsRequest request,
+ StreamObserver<getHostsReply> responseObserver) {
+
+ getHostsReply.Builder replyBuilder = getHostsReply.newBuilder();
+
+ hostService.getHosts().forEach(d -> replyBuilder.addHost(HostProtoTranslator.translate(d)));
+ responseObserver.onNext(replyBuilder.build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void getHost(getHostRequest request,
+ StreamObserver<getHostReply> responseObserver) {
+
+ Host host = hostService.getHost(HostId.hostId(request.getHostId().toString()));
+
+ responseObserver.onNext(getHostReply.newBuilder().setHost(HostProtoTranslator.translate(host)).build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void getHostsByVlan(getHostsByVlanRequest request,
+ StreamObserver<getHostsByVlanReply> responseObserver) {
+
+ getHostsByVlanReply.Builder replyBuilder = getHostsByVlanReply.newBuilder();
+
+ hostService.getHostsByVlan(VlanId.vlanId(request.getVlanId())).forEach(
+ d -> replyBuilder.addHost(HostProtoTranslator.translate(d)));
+ responseObserver.onNext(replyBuilder.build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void getHostsByMac(getHostsByMacRequest request,
+ StreamObserver<getHostsByMacReply> responseObserver) {
+
+ getHostsByMacReply.Builder replyBuilder = getHostsByMacReply.newBuilder();
+
+ hostService.getHostsByMac(MacAddress.valueOf(request.getMac())).forEach(
+ d -> replyBuilder.addHost(HostProtoTranslator.translate(d)));
+ responseObserver.onNext(replyBuilder.build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void getHostsByIp(getHostsByIpRequest request,
+ StreamObserver<getHostsByIpReply> responseObserver) {
+
+ getHostsByIpReply.Builder replyBuilder = getHostsByIpReply.newBuilder();
+
+ hostService.getHostsByIp(IpAddress.valueOf(request.getIpAddress())).forEach(
+ d -> replyBuilder.addHost(HostProtoTranslator.translate(d)));
+ responseObserver.onNext(replyBuilder.build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void getConnectedHosts(getConnectedHostsRequest request,
+ StreamObserver<getConnectedHostsReply> responseObserver) {
+
+ getConnectedHostsReply.Builder replyBuilder = getConnectedHostsReply.newBuilder();
+
+ if (getConnectedHostsRequest.ConnectedHostCase.DEVICEID == request.getConnectedHostCase()) {
+ hostService.getConnectedHosts(DeviceId.deviceId(request.getDeviceId()))
+ .forEach(d -> replyBuilder.addHost(HostProtoTranslator.translate(d)));
+ } else if (getConnectedHostsRequest.ConnectedHostCase.CONNECT_POINT == request.getConnectedHostCase()) {
+ hostService.getConnectedHosts(ConnectPointProtoTranslator.translate(request.getConnectPoint()).get())
+ .forEach(d -> replyBuilder.addHost(HostProtoTranslator.translate(d)));
+ } else {
+ log.warn("Both DeviceId and ConnectPoint are not set.");
+ }
+
+ responseObserver.onNext(replyBuilder.build());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void startMonitoringIp(startMonitoringIpRequest request,
+ StreamObserver<startMonitoringIpReply> responseObserver) {
+
+ hostService.startMonitoringIp(IpAddress.valueOf(request.getIpAddress()));
+ responseObserver.onNext(startMonitoringIpReply.getDefaultInstance());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void stopMonitoringIp(stopMonitoringIpRequest request,
+ StreamObserver<stopMonitoringIpReply> responseObserver) {
+
+ hostService.stopMonitoringIp(IpAddress.valueOf(request.getIpAddress()));
+ responseObserver.onNext(stopMonitoringIpReply.getDefaultInstance());
+ responseObserver.onCompleted();
+ }
+
+ @Override
+ public void requestMac(requestMacRequest request,
+ StreamObserver<requestMacReply> responseObserver) {
+
+ hostService.requestMac(IpAddress.valueOf(request.getIpAddress()));
+ responseObserver.onNext(requestMacReply.getDefaultInstance());
+ responseObserver.onCompleted();
+ }
+ }
+
+ private HostServiceNBServerInternal getInnerInstance() {
+ if (instance == null) {
+ instance = new HostServiceNBServerInternal();
+ }
+ return instance;
+ }
+}
diff --git a/incubator/protobuf/services/nb/src/main/proto/net/host/HostServiceNb.proto b/incubator/protobuf/services/nb/src/main/proto/net/host/HostServiceNb.proto
new file mode 100644
index 0000000..81debba
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/main/proto/net/host/HostServiceNb.proto
@@ -0,0 +1,119 @@
+syntax="proto3";
+option java_package = "org.onosproject.grpc.nb.net.host";
+
+package nb.net.host;
+
+import "net/HostProto.proto";
+import "net/HostIdProto.proto";
+import "net/ConnectPointProto.proto";
+
+message getHostCountRequest {
+}
+
+message getHostCountReply {
+ int32 host_count = 1;
+}
+
+message getHostsRequest {
+}
+
+message getHostsReply {
+ repeated .net.HostProto host = 1;
+}
+
+message getHostRequest {
+ .net.HostIdProto host_id = 1;
+}
+
+message getHostReply {
+ .net.HostProto host = 1;
+}
+
+message getHostsByVlanRequest {
+ string vlan_id = 1;
+}
+
+message getHostsByVlanReply {
+ repeated .net.HostProto host = 1;
+}
+
+message getHostsByMacRequest {
+ string mac = 1;
+}
+
+message getHostsByMacReply {
+ repeated .net.HostProto host = 1;
+}
+
+message getHostsByIpRequest {
+ string ip_address = 1;
+}
+
+message getHostsByIpReply {
+ repeated .net.HostProto host = 1;
+}
+
+message getConnectedHostsRequest {
+ oneof connected_host {
+ .net.ConnectPointProto connect_point = 1;
+ string deviceId = 2;
+ }
+}
+
+message getConnectedHostsReply {
+ repeated .net.HostProto host = 1;
+}
+
+message startMonitoringIpRequest {
+ string ip_address = 1;
+}
+
+message startMonitoringIpReply {
+}
+
+message stopMonitoringIpRequest {
+ string ip_address = 1;
+}
+
+message stopMonitoringIpReply {
+}
+
+message requestMacRequest {
+ string ip_address = 1;
+}
+
+message requestMacReply {
+}
+
+// Host Interface exported by the server.
+service HostService {
+ // GRPC Obtains the host count.
+ rpc getHostCount(getHostCountRequest) returns (getHostCountReply) {}
+
+ // GRPC Obtains the hosts.
+ rpc getHosts(getHostsRequest) returns (getHostsReply) {}
+
+ // GRPC Obtains the host at a given HostId.
+ rpc getHost(getHostRequest) returns (getHostReply) {}
+
+ // GRPC Obtains the hosts at a given VlanId.
+ rpc getHostsByVlan(getHostsByVlanRequest) returns (getHostsByVlanReply) {}
+
+ // GRPC Obtains the hosts at a given MacAddress.
+ rpc getHostsByMac(getHostsByMacRequest) returns (getHostsByMacReply) {}
+
+ // GRPC Obtains the hosts at a given IpAddress.
+ rpc getHostsByIp(getHostsByIpRequest) returns (getHostsByIpReply) {}
+
+ // GRPC Obtains the hosts at a given connectPoint or DeviceId.
+ rpc getConnectedHosts(getConnectedHostsRequest) returns (getConnectedHostsReply) {}
+
+ // GRPC Requests the host service to monitor hosts with the given IP address.
+ rpc startMonitoringIp(startMonitoringIpRequest) returns (startMonitoringIpReply) {}
+
+ // GRPC Stops the host service from monitoring an IP address.
+ rpc stopMonitoringIp(stopMonitoringIpRequest) returns (stopMonitoringIpReply) {}
+
+ // GRPC Requests the host service to resolve the MAC address for the given IP address.
+ rpc requestMac(requestMacRequest) returns (requestMacReply) {}
+}
\ No newline at end of file
diff --git a/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbHostServiceTest.java b/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbHostServiceTest.java
new file mode 100644
index 0000000..62e5cfa
--- /dev/null
+++ b/incubator/protobuf/services/nb/src/test/java/org/onosproject/incubator/protobuf/services/nb/GrpcNbHostServiceTest.java
@@ -0,0 +1,435 @@
+/*
+* Copyright 2017-present Open Networking Foundation
+*
+* 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.incubator.protobuf.services.nb;
+
+import com.google.common.collect.ImmutableSet;
+import io.grpc.BindableService;
+import io.grpc.inprocess.InProcessChannelBuilder;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import io.grpc.ManagedChannel;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.grpc.net.models.HostProtoOuterClass;
+import org.onosproject.incubator.protobuf.models.net.HostProtoTranslator;
+import org.onosproject.incubator.protobuf.models.net.HostIdProtoTranslator;
+import org.onosproject.incubator.protobuf.models.net.ConnectPointProtoTranslator;
+import org.onosproject.grpc.nb.net.host.HostServiceGrpc.HostServiceBlockingStub;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+
+import org.onosproject.grpc.nb.net.host.HostServiceGrpc;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.grpc.nb.net.host.HostServiceNb.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Unit tests of gRPC northbound host service.
+ */
+public class GrpcNbHostServiceTest {
+ private final Logger log = getLogger(getClass());
+
+ private static InProcessServer<BindableService> inprocessServer;
+ private static HostServiceBlockingStub blockingStub;
+ private static ManagedChannel channel;
+ private static final HostService MOCK_HOST = new MockHostService();
+ private static List<Host> allHosts = new ArrayList<>();
+ private static Host h1;
+ private static HostId id1;
+ private static IpAddress ip1;
+ private static MacAddress mac1;
+ private static DeviceId deviceId;
+ private static ConnectPoint c1;
+ private static boolean started = false;
+ private static boolean stopped = false;
+ private static boolean requestMac = false;
+
+ public GrpcNbHostServiceTest() {}
+
+ private static void populateHosts() {
+ ip1 = IpAddress.valueOf("10.1.1.1");
+ IpAddress ip2 = IpAddress.valueOf("10.1.1.2");
+ IpAddress ip3 = IpAddress.valueOf("10.1.1.3");
+ mac1 = MacAddress.valueOf("67:11:23:45:87:11");
+ MacAddress mac2 = MacAddress.valueOf("67:11:23:45:87:12");
+ MacAddress mac3 = MacAddress.valueOf("67:11:23:45:87:13");
+ id1 = HostId.hostId(mac1);
+ HostId id2 = HostId.hostId(mac2);
+ HostId id3 = HostId.hostId(mac3);
+ deviceId = DeviceId.deviceId("test");
+
+ c1 = new ConnectPoint(deviceId, PortNumber.portNumber(101));
+ HostLocation hostLocation1 = new HostLocation(deviceId, PortNumber.portNumber(101), 0);
+ HostLocation hostLocation2 = new HostLocation(deviceId, PortNumber.portNumber(102), 0);
+ HostLocation hostLocation3 = new HostLocation(deviceId, PortNumber.portNumber(103), 0);
+
+ h1 = new DefaultHost(ProviderId.NONE, id1, mac1, VlanId.NONE,
+ hostLocation1, ImmutableSet.of(ip1));
+ allHosts.add(h1);
+ allHosts.add(new DefaultHost(ProviderId.NONE, id2, mac2, VlanId.NONE,
+ hostLocation2, ImmutableSet.of(ip2)));
+ allHosts.add(new DefaultHost(ProviderId.NONE, id3, mac3, VlanId.NONE,
+ hostLocation3, ImmutableSet.of(ip3)));
+ }
+
+ /**
+ * Tests gRPC getComponentNames interface.
+ */
+ @Test
+ public void testGetHostCount() throws InterruptedException {
+ getHostCountRequest request = getHostCountRequest.getDefaultInstance();
+ getHostCountReply reply;
+
+ try {
+ reply = blockingStub.getHostCount(request);
+ assertTrue(allHosts.size() == reply.getHostCount());
+ } catch (Exception e) {
+ log.error("Get host count error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getComponentNames interface.
+ */
+ @Test
+ public void testGetHosts() throws InterruptedException {
+ getHostsRequest request = getHostsRequest.getDefaultInstance();
+ getHostsReply reply;
+
+ try {
+ reply = blockingStub.getHosts(request);
+ Set<Host> actualHosts = new HashSet<>();
+ for (HostProtoOuterClass.HostProto host : reply.getHostList()) {
+ actualHosts.add(HostProtoTranslator.translate(host));
+ }
+
+ Set<Host> expectedHosts = new HashSet<>();
+ for (Host h : allHosts) {
+ expectedHosts.add(h);
+ }
+ assertTrue(actualHosts.equals(expectedHosts));
+ } catch (Exception e) {
+ log.error("Get all hosts error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getHost interface.
+ */
+ @Test
+ public void testGetHost() throws InterruptedException {
+ getHostRequest request = getHostRequest.newBuilder().setHostId(HostIdProtoTranslator.translate(id1)).build();
+ getHostReply reply;
+
+ try {
+ reply = blockingStub.getHost(request);
+ assertTrue(HostProtoTranslator.translate(reply.getHost()).equals(h1));
+ } catch (Exception e) {
+ log.error("Get host with hostId error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getHostsByVlan interface.
+ */
+ @Test
+ public void testGetHostsByVlan() throws InterruptedException {
+ getHostsByVlanRequest request = getHostsByVlanRequest.newBuilder().setVlanId(VlanId.NONE.toString()).build();
+ getHostsByVlanReply reply;
+
+ try {
+ reply = blockingStub.getHostsByVlan(request);
+
+ Set<Host> actualHosts = new HashSet<>();
+ for (HostProtoOuterClass.HostProto host : reply.getHostList()) {
+ actualHosts.add(HostProtoTranslator.translate(host));
+ }
+
+ Set<Host> expectedHosts = new HashSet<>();
+ for (Host h : allHosts) {
+ expectedHosts.add(h);
+ }
+ assertTrue(actualHosts.equals(expectedHosts));
+ } catch (Exception e) {
+ log.error("Get hosts that belong to the specified VLAN error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getHostsByMac interface.
+ */
+ @Test
+ public void testGetHostsByMac() throws InterruptedException {
+ getHostsByMacRequest request = getHostsByMacRequest.newBuilder().setMac(mac1.toString()).build();
+ getHostsByMacReply reply;
+
+ try {
+ reply = blockingStub.getHostsByMac(request);
+
+ Set<Host> actualHosts = new HashSet<>();
+ for (HostProtoOuterClass.HostProto host : reply.getHostList()) {
+ actualHosts.add(HostProtoTranslator.translate(host));
+ }
+ Set<Host> expectedHosts = new HashSet<>();
+ expectedHosts.add(allHosts.get(0));
+ assertTrue(actualHosts.equals(expectedHosts));
+ } catch (Exception e) {
+ log.error("Get hosts that have the specified MAC address error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getHostsByIp interface.
+ */
+ @Test
+ public void testGetHostsByIp() throws InterruptedException {
+ getHostsByIpRequest request = getHostsByIpRequest.newBuilder().setIpAddress(ip1.toString()).build();
+ getHostsByIpReply reply;
+
+ try {
+ reply = blockingStub.getHostsByIp(request);
+
+ Set<Host> actualHosts = new HashSet<>();
+ for (HostProtoOuterClass.HostProto host : reply.getHostList()) {
+ actualHosts.add(HostProtoTranslator.translate(host));
+ }
+
+ Set<Host> expectedHosts = new HashSet<>();
+ expectedHosts.add(allHosts.get(0));
+ assertTrue(actualHosts.equals(expectedHosts));
+ } catch (Exception e) {
+ log.error("Get hosts that have the specified IP address error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getConnectedHosts interface.
+ */
+ @Test
+ public void testGetConnectedHosts() throws InterruptedException {
+ getConnectedHostsRequest request = getConnectedHostsRequest.newBuilder()
+ .setConnectPoint(ConnectPointProtoTranslator.translate(c1))
+ .build();
+ getConnectedHostsReply reply;
+
+ try {
+ reply = blockingStub.getConnectedHosts(request);
+
+ Set<Host> actualHosts = new HashSet<>();
+ for (HostProtoOuterClass.HostProto host : reply.getHostList()) {
+ actualHosts.add(HostProtoTranslator.translate(host));
+ }
+
+ Set<Host> expectedHosts = new HashSet<>();
+ expectedHosts.add(allHosts.get(0));
+ assertTrue(actualHosts.equals(expectedHosts));
+ } catch (Exception e) {
+ log.error("Get connected hosts with connect point error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC getConnectedHostsByDeviceId interface.
+ */
+ @Test
+ public void testGetConnectedHostsByDeviceId() throws InterruptedException {
+ getConnectedHostsRequest request = getConnectedHostsRequest.newBuilder()
+ .setDeviceId(deviceId.toString())
+ .build();
+ getConnectedHostsReply reply;
+
+ try {
+ reply = blockingStub.getConnectedHosts(request);
+
+ Set<Host> actualHosts = new HashSet<>();
+ for (HostProtoOuterClass.HostProto host : reply.getHostList()) {
+ actualHosts.add(HostProtoTranslator.translate(host));
+ }
+
+ Set<Host> expectedHosts = new HashSet<>();
+ for (Host h : allHosts) {
+ expectedHosts.add(h);
+ }
+ assertTrue(actualHosts.equals(expectedHosts));
+ } catch (Exception e) {
+ log.error("Get connected hosts with deviceId error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC startMonitoringIp interface.
+ */
+ @Test
+ public void testStartMonitoringIp() throws InterruptedException {
+ startMonitoringIpRequest request = startMonitoringIpRequest.newBuilder().setIpAddress(ip1.toString()).build();
+
+ try {
+ blockingStub.startMonitoringIp(request);
+ assertTrue(started);
+ } catch (Exception e) {
+ log.error("Start monitoring hosts with the given IP address error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC stopMonitoringIp interface.
+ */
+ @Test
+ public void testStopMonitoringIp() throws InterruptedException {
+ stopMonitoringIpRequest request = stopMonitoringIpRequest.newBuilder().setIpAddress(ip1.toString()).build();
+
+ try {
+ blockingStub.stopMonitoringIp(request);
+ assertTrue(stopped);
+ } catch (Exception e) {
+ log.error("Stop monitoring hosts with the given IP address error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Tests gRPC requestMac interface.
+ */
+ @Test
+ public void testRequestMac() throws InterruptedException {
+ requestMacRequest request = requestMacRequest.newBuilder().setIpAddress(ip1.toString()).build();
+
+ try {
+ blockingStub.requestMac(request);
+ assertTrue(requestMac);
+ } catch (Exception e) {
+ log.error("Resolve the MAC address for the given IP address error! Exception={}", e.toString());
+ }
+ }
+
+ /**
+ * Initialization before start testing gRPC northbound host service.
+ */
+ @BeforeClass
+ public static void beforeClass() throws InstantiationException, IllegalAccessException, IOException {
+ GrpcNbHostService hostService = new GrpcNbHostService();
+ hostService.hostService = MOCK_HOST;
+ inprocessServer = hostService.registerInProcessServer();
+
+ inprocessServer.start();
+ channel = InProcessChannelBuilder.forName("test").directExecutor()
+ // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
+ // needing certificates.
+ .usePlaintext(true).build();
+ blockingStub = HostServiceGrpc.newBlockingStub(channel);
+ populateHosts();
+ }
+
+ /**
+ * Finalization after test gRPC northbound host service.
+ */
+ @AfterClass
+ public static void afterClass() {
+
+ channel.shutdownNow();
+ inprocessServer.stop();
+ }
+
+ private static class MockHostService implements HostService {
+
+ MockHostService() {
+ }
+
+ @Override
+ public int getHostCount() {
+ return allHosts.size();
+ }
+
+ @Override
+ public Iterable<Host> getHosts() {
+ return allHosts;
+ }
+
+ @Override
+ public Host getHost(HostId hostId) {
+ return allHosts.stream().filter(h -> h.id().equals(hostId)).findFirst().get();
+ }
+
+ @Override
+ public Set<Host> getHostsByVlan(VlanId vlanId) {
+ return allHosts.stream().filter(h -> h.vlan().equals(vlanId)).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<Host> getHostsByMac(MacAddress mac) {
+ return allHosts.stream().filter(h -> h.mac().equals(mac)).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<Host> getHostsByIp(IpAddress ip) {
+ return allHosts.stream().filter(h -> h.ipAddresses().contains(ip)).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+ return allHosts.stream().filter(h -> h.location().deviceId().equals(connectPoint.deviceId())
+ && h.location().port().equals(connectPoint.port()))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<Host> getConnectedHosts(DeviceId deviceId) {
+ return allHosts.stream().filter(h -> h.location().deviceId().equals(deviceId)).collect(Collectors.toSet());
+ }
+
+ @Override
+ public void startMonitoringIp(IpAddress ip) {
+ started = true;
+ }
+
+ @Override
+ public void stopMonitoringIp(IpAddress ip) {
+ stopped = true;
+ }
+
+ @Override
+ public void requestMac(IpAddress ip) {
+ requestMac = true;
+ }
+
+ @Override
+ public void addListener(HostListener listener) {
+ }
+
+ @Override
+ public void removeListener(HostListener listener) {
+ }
+ }
+}