Created LinkService and added unit tests.

Change-Id: I1f2104c873e5a9e2df34074d36cddc823e3b3ec5
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
new file mode 100644
index 0000000..c0177fe
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ConnectPointProtoTranslator.java
@@ -0,0 +1,94 @@
+/*
+ * 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.onosproject.grpc.net.models.ConnectPointProtoOuterClass;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.IpElementId;
+import org.onosproject.net.PortNumber;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+/**
+ * gRPC ConnectPoint message to org.onosproject.net.ConnectPoint conversion related utilities.
+ */
+public final class ConnectPointProtoTranslator {
+
+    private static final Logger log = LoggerFactory.getLogger(ConnectPointProtoTranslator.class);
+
+    /**
+     * Translates gRPC ConnectPoint message to Optional of {@link org.onosproject.net.ConnectPoint}.
+     *
+     * @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) {
+        switch (connectPoint.getElementIdCase()) {
+            case DEVICE_ID:
+                return Optional.of(new ConnectPoint(DeviceId.deviceId(connectPoint.getDeviceId()),
+                                                    PortNumber.portNumber(connectPoint.getPortNumber())));
+            case HOST_ID:
+                return Optional.of(new ConnectPoint(HostId.hostId(connectPoint.getHostId()),
+                                                    PortNumber.portNumber(connectPoint.getPortNumber())));
+            case IP_ELEMENT_ID:
+                return Optional.of(new ConnectPoint(IpElementId.ipElement(IpAddress
+                                                                                  .valueOf(connectPoint
+                                                                                                   .getIpElementId()
+                                                                                  )),
+                                                    PortNumber.portNumber(connectPoint.getPortNumber())));
+            default:
+                return Optional.empty();
+        }
+    }
+
+    /**
+     * Translates {@link org.onosproject.net.ConnectPoint} to gRPC ConnectPoint message.
+     *
+     * @param connectPoint {@link org.onosproject.net.ConnectPoint}
+     * @return gRPC ConnectPoint message
+     */
+    public static ConnectPointProtoOuterClass.ConnectPointProto translate(ConnectPoint connectPoint) {
+        if (connectPoint.elementId() instanceof DeviceId) {
+            return ConnectPointProtoOuterClass.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())
+                    .setPortNumber(connectPoint.port().toString())
+                    .build();
+        } else if (connectPoint.ipElementId() instanceof IpElementId) {
+            return ConnectPointProtoOuterClass.ConnectPointProto.newBuilder()
+                    .setIpElementId(connectPoint.ipElementId().toString())
+                    .setPortNumber(connectPoint.port().toString())
+                    .build();
+        } else {
+            log.warn("Unrecognized ElementId", connectPoint);
+            throw new IllegalArgumentException("Unrecognized ElementId");
+        }
+    }
+
+
+    // Utility class not intended for instantiation.
+    private ConnectPointProtoTranslator() {}
+}
+
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java
new file mode 100644
index 0000000..56804c7
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/LinkProtoTranslator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.LinkProtoOuterClass;
+import org.onosproject.incubator.protobuf.models.ProtobufUtils;
+import org.onosproject.incubator.protobuf.models.net.link.LinkEnumsProtoTranslator;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Link;
+import org.onosproject.net.provider.ProviderId;
+
+/**
+ * gRPC LinkProto message to equivalent ONOS Link conversion related utilities.
+ */
+public final class LinkProtoTranslator {
+
+    /**
+     * Translates gRPC LinkCore message to {@link org.onosproject.net.Link}.
+     *
+     * @param link gRPC message
+     * @return {@link org.onosproject.net.Link} null if link is a default instance
+     */
+    public static Link translate(LinkProtoOuterClass.LinkProto link) {
+        if (link.equals(LinkProtoOuterClass.LinkProto.getDefaultInstance())) {
+            return null;
+        }
+        ProviderId providerId = ProviderIdProtoTranslator.translate(link.getProviderId());
+        Link.State state = LinkEnumsProtoTranslator.translate(link.getState()).get();
+        ConnectPoint src = ConnectPointProtoTranslator.translate(link.getSrc()).get();
+        ConnectPoint dst = ConnectPointProtoTranslator.translate(link.getDst()).get();
+        Link.Type type = LinkEnumsProtoTranslator.translate(link.getType()).get();
+        Annotations annots = ProtobufUtils.asAnnotations(link.getAnnotations());
+        Boolean isExpected = link.getIsExpected();
+        return DefaultLink.builder().state(state)
+                .annotations(annots)
+                .providerId(providerId)
+                .src(src)
+                .dst(dst)
+                .type(type)
+                .isExpected(isExpected)
+                .build();
+    }
+
+
+    /**
+     * Translates {@link org.onosproject.net.Link} to gRPC LinkCore message.
+     *
+     * @param link {@link org.onosproject.net.Link}
+     * @return gRPC LinkCore message
+     */
+    public static LinkProtoOuterClass.LinkProto translate(Link link) {
+        if (link == null) {
+            return LinkProtoOuterClass.LinkProto.getDefaultInstance();
+        }
+        return LinkProtoOuterClass.LinkProto.newBuilder()
+                .setProviderId(ProviderIdProtoTranslator.translate(link.providerId()))
+                .setState(LinkEnumsProtoTranslator.translate(link.state()))
+                .setSrc(ConnectPointProtoTranslator.translate(link.src()))
+                .setDst(ConnectPointProtoTranslator.translate(link.dst()))
+                .setType(LinkEnumsProtoTranslator.translate(link.type()))
+                .setIsExpected(link.isExpected())
+                .build();
+    }
+
+    // Utility class not intended for instantiation.
+    private LinkProtoTranslator() {}
+
+}
+
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ProviderIdProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ProviderIdProtoTranslator.java
new file mode 100644
index 0000000..8ee4fe5
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/ProviderIdProtoTranslator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.ProviderIdProtoOuterClass;
+import org.onosproject.net.provider.ProviderId;
+
+/**
+ * gRPC ProviderId message to org.onosproject.net.provider.ProviderId conversion related utilities.
+ */
+public final class ProviderIdProtoTranslator {
+
+    /**
+     * Translates gRPC ProviderId message to {@link org.onosproject.net.provider.ProviderId}.
+     *
+     * @param providerId gRPC ProviderId message
+     * @return {@link org.onosproject.net.provider.ProviderId} or null if providerId is a default instance
+     */
+    public static ProviderId translate(ProviderIdProtoOuterClass.ProviderIdProto providerId) {
+        if (providerId.equals(ProviderIdProtoOuterClass.ProviderIdProto.getDefaultInstance())) {
+            return null;
+        }
+        return new ProviderId(providerId.getScheme(), providerId.getId(), providerId.getAncillary());
+    }
+
+    /**
+     * Translates {@link org.onosproject.net.provider.ProviderId} to gRPC ProviderId message.
+     *
+     * @param providerId {@link org.onosproject.net.provider.ProviderId}
+     * @return gRPC ProviderId message
+     */
+    public static ProviderIdProtoOuterClass.ProviderIdProto translate(ProviderId providerId) {
+        if (providerId == null) {
+            return ProviderIdProtoOuterClass.ProviderIdProto.getDefaultInstance();
+        }
+        return ProviderIdProtoOuterClass.ProviderIdProto.newBuilder()
+                .setScheme(providerId.scheme())
+                .setId(providerId.id())
+                .setAncillary(providerId.isAncillary())
+                .build();
+    }
+
+
+    // Utility class not intended for instantiation.
+    private ProviderIdProtoTranslator() {}
+
+}
+
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/link/LinkEnumsProtoTranslator.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/link/LinkEnumsProtoTranslator.java
new file mode 100644
index 0000000..bc87984
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/link/LinkEnumsProtoTranslator.java
@@ -0,0 +1,125 @@
+/*
+ * 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.link;
+
+import org.onosproject.grpc.net.link.models.LinkEnumsProto;
+import org.onosproject.net.Link;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+/**
+ * gRPC LinkType and LinkState message to equivalent ONOS enum conversion related utilities.
+ */
+public final class LinkEnumsProtoTranslator {
+
+    private static final Logger log = LoggerFactory.getLogger(LinkEnumsProtoTranslator.class);
+
+    /**
+     * Translates gRPC enum LinkType to Optional of ONOS enum.
+     *
+     * @param type linktype type in gRPC enum
+     * @return Optional of equivalent ONOS enum or empty if not recognized
+     */
+    public static Optional<Link.Type> translate(LinkEnumsProto.LinkTypeProto type) {
+        switch (type) {
+            case DIRECT:
+                return Optional.of(Link.Type.DIRECT);
+            case INDIRECT:
+                return Optional.of(Link.Type.INDIRECT);
+            case EDGE:
+                return Optional.of(Link.Type.EDGE);
+            case TUNNEL:
+                return Optional.of(Link.Type.TUNNEL);
+            case OPTICAL:
+                return Optional.of(Link.Type.OPTICAL);
+            case VIRTUAL:
+                return Optional.of(Link.Type.VIRTUAL);
+            default:
+                log.warn("Unrecognized Type gRPC message: {}", type);
+                return Optional.empty();
+        }
+    }
+
+    /**
+     * Translates ONOS enum Type to gRPC enum.
+     *
+     * @param type ONOS' Type type
+     * @return equivalent gRPC message enum
+     */
+    public static LinkEnumsProto.LinkTypeProto translate(Link.Type type) {
+        switch (type) {
+            case DIRECT:
+                return LinkEnumsProto.LinkTypeProto.DIRECT;
+            case INDIRECT:
+                return LinkEnumsProto.LinkTypeProto.INDIRECT;
+            case EDGE:
+                return LinkEnumsProto.LinkTypeProto.EDGE;
+            case TUNNEL:
+                return LinkEnumsProto.LinkTypeProto.TUNNEL;
+            case OPTICAL:
+                return LinkEnumsProto.LinkTypeProto.OPTICAL;
+            case VIRTUAL:
+                return LinkEnumsProto.LinkTypeProto.VIRTUAL;
+            default:
+                log.warn("Unrecognized type", type);
+                throw new IllegalArgumentException("Unrecognized Type");
+        }
+    }
+
+    /**
+     * Translates gRPC enum LinkState to Optional of ONOS enum.
+     *
+     * @param state linkstate state in gRPC enum
+     * @return Optional of equivalent ONOS enum or empty if not recognized
+     */
+    public static Optional<Link.State> translate(LinkEnumsProto.LinkStateProto state) {
+        switch (state) {
+            case ACTIVE:
+                return Optional.of(Link.State.ACTIVE);
+            case INACTIVE:
+                return Optional.of(Link.State.INACTIVE);
+            default:
+                log.warn("Unrecognized State gRPC message: {}", state);
+                return Optional.empty();
+        }
+    }
+
+    /**
+     * Translates ONOS enum State to gRPC enum.
+     *
+     * @param state ONOS' state state
+     * @return equivalent gRPC message enum
+     */
+    public static LinkEnumsProto.LinkStateProto translate(Link.State state) {
+        switch (state) {
+            case ACTIVE:
+                return LinkEnumsProto.LinkStateProto.ACTIVE;
+            case INACTIVE:
+                return LinkEnumsProto.LinkStateProto.INACTIVE;
+            default:
+                log.warn("Unrecognized State", state);
+                throw new IllegalArgumentException("Unrecognized State");
+        }
+    }
+
+
+    // Utility class not intended for instantiation.
+    private LinkEnumsProtoTranslator() {}
+
+}
+
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/link/package-info.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/link/package-info.java
new file mode 100644
index 0000000..1392669
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/link/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * Utilities to handle ProtoBuf version of ONOS link models.
+ */
+package org.onosproject.incubator.protobuf.models.net.link;
diff --git a/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/package-info.java b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/package-info.java
new file mode 100644
index 0000000..e393681
--- /dev/null
+++ b/incubator/protobuf/models/src/main/java/org/onosproject/incubator/protobuf/models/net/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+/**
+ * Utilities to handle ProtoBuf version of ONOS network models.
+ */
+package org.onosproject.incubator.protobuf.models.net;