Tunnel Service  extenstion to support to create tunnel from APP and also to carry Label stack as network resource

Change-Id: Ie69fd2d824bd40a14012406be3eea5b1449b5cf2
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultLabelStack.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultLabelStack.java
new file mode 100644
index 0000000..71de4b7
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultLabelStack.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+package org.onosproject.incubator.net.tunnel;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Default implementation of label stack.
+ */
+public class DefaultLabelStack implements LabelStack {
+
+    private final List<LabelResourceId> labelResources;
+
+    /**
+     * Creates label stack.
+     *
+     * @param labelResources contiguous label ids that comprise the path
+     */
+    public DefaultLabelStack(List<LabelResourceId> labelResources) {
+        this.labelResources = ImmutableList.copyOf(labelResources);
+    }
+
+    @Override
+    public List<LabelResourceId> labelResources() {
+        return labelResources;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("labelResources", labelResources)
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return labelResources.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultLabelStack) {
+            final DefaultLabelStack other = (DefaultLabelStack) obj;
+            return Objects.equals(this.labelResources, other.labelResources);
+        }
+        return false;
+    }
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java
index 122474f..c533cf9 100755
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnel.java
@@ -45,6 +45,7 @@
                                      // ONOS as primary key
     private final TunnelName tunnelName; // name of a tunnel
     private final Path path;
+    private final NetworkResource networkRes; // network resource to carry label stack
 
     /**
      * Creates an active infrastructure tunnel using the supplied information.
@@ -94,6 +95,61 @@
         this.tunnelId = tunnelId;
         this.tunnelName = tunnelName;
         this.path = path;
+        this.networkRes = null;
+    }
+
+    /**
+     * Creates an active infrastructure tunnel using the supplied information.
+     *
+     * @param producerName provider identity
+     * @param src tunnel source
+     * @param dst tunnel destination
+     * @param type tunnel type
+     * @param groupId groupId
+     * @param tunnelId tunnelId
+     * @param tunnelName tunnel name
+     * @param path the path of tunnel
+     * @param networkRes network resource of tunnel
+     * @param annotations optional key/value annotations
+     */
+    public DefaultTunnel(ProviderId producerName, TunnelEndPoint src,
+                         TunnelEndPoint dst, Type type, DefaultGroupId groupId,
+                         TunnelId tunnelId, TunnelName tunnelName, Path path,
+                         NetworkResource networkRes, Annotations... annotations) {
+        this(producerName, src, dst, type, Tunnel.State.ACTIVE, groupId,
+                tunnelId, tunnelName, path, networkRes, annotations);
+    }
+
+    /**
+     * Creates an tunnel using the supplied information.
+     *
+     * @param producerName provider identity
+     * @param src tunnel source
+     * @param dst tunnel destination
+     * @param type tunnel type
+     * @param state tunnel state
+     * @param groupId groupId
+     * @param tunnelId tunnelId
+     * @param tunnelName tunnel name
+     * @param path the path of tunnel
+     * @param networkRes network resource of tunnel
+     * @param annotations optional key/value annotations
+     */
+    public DefaultTunnel(ProviderId producerName, TunnelEndPoint src,
+                         TunnelEndPoint dst, Type type, State state,
+                         DefaultGroupId groupId, TunnelId tunnelId,
+                         TunnelName tunnelName, Path path, NetworkResource networkRes,
+                         Annotations... annotations) {
+        super(producerName, annotations);
+        this.src = src;
+        this.dst = dst;
+        this.type = type;
+        this.state = state;
+        this.groupId = groupId;
+        this.tunnelId = tunnelId;
+        this.tunnelName = tunnelName;
+        this.path = path;
+        this.networkRes = networkRes;
     }
 
     @Override
@@ -118,7 +174,7 @@
 
     @Override
     public NetworkResource resource() {
-        return null;
+        return networkRes;
     }
 
     @Override
@@ -145,7 +201,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(src, dst, type, groupId, tunnelId, tunnelName,
-                            state, path);
+                            state, path, networkRes);
     }
 
     @Override
@@ -162,7 +218,8 @@
                     && Objects.equals(this.tunnelId, other.tunnelId)
                     && Objects.equals(this.tunnelName, other.tunnelName)
                     && Objects.equals(this.state, other.state)
-                    && Objects.equals(this.path, other.path);
+                    && Objects.equals(this.path, other.path)
+                    && Objects.equals(this.networkRes, other.networkRes);
         }
         return false;
     }
@@ -173,6 +230,7 @@
                 .add("type", type).add("state", state).add("groupId", groupId)
                 .add("producerTunnelId", tunnelId)
                 .add("tunnelName", tunnelName)
-                .add("path", path).toString();
+                .add("path", path)
+                .add("networkResource", networkRes).toString();
     }
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java
index 077c0d9..62f7646 100755
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/DefaultTunnelDescription.java
@@ -18,6 +18,7 @@
 import com.google.common.annotations.Beta;
 import org.onosproject.core.DefaultGroupId;
 import org.onosproject.net.AbstractDescription;
+import org.onosproject.net.NetworkResource;
 import org.onosproject.net.Path;
 import org.onosproject.net.SparseAnnotations;
 import org.onosproject.net.provider.ProviderId;
@@ -41,6 +42,7 @@
     private final ProviderId producerName; // tunnel producer name
     private final TunnelName tunnelName; // name of a tunnel
     private final Path path;
+    private final NetworkResource networkRes;
 
     /**
      * Creates a tunnel description using the supplied information.
@@ -71,6 +73,41 @@
         this.producerName = producerName;
         this.tunnelName = tunnelName;
         this.path = path;
+        this.networkRes = null;
+    }
+
+    /**
+     * Creates a tunnel description using the supplied information.
+     *
+     * @param id TunnelId
+     * @param src TunnelPoint source
+     * @param dst TunnelPoint destination
+     * @param type tunnel type
+     * @param groupId groupId
+     * @param producerName tunnel producer
+     * @param tunnelName tunnel name
+     * @param path the path of tunnel
+     * @param networkRes network resource of tunnel
+     * @param annotations optional key/value annotations
+     */
+    public DefaultTunnelDescription(TunnelId id, TunnelEndPoint src,
+                                    TunnelEndPoint dst, Tunnel.Type type,
+                                    DefaultGroupId groupId,
+                                    ProviderId producerName,
+                                    TunnelName tunnelName,
+                                    Path path,
+                                    NetworkResource networkRes,
+                                    SparseAnnotations... annotations) {
+        super(annotations);
+        this.tunnelId = id;
+        this.src = src;
+        this.dst = dst;
+        this.type = type;
+        this.groupId = groupId;
+        this.producerName = producerName;
+        this.tunnelName = tunnelName;
+        this.path = path;
+        this.networkRes = networkRes;
     }
 
     @Override
@@ -115,6 +152,11 @@
     }
 
     @Override
+    public NetworkResource resource() {
+        return networkRes;
+    }
+
+    @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
                 .add("tunnelId", id())
@@ -125,6 +167,7 @@
                 .add("producerName", producerName())
                 .add("groupId", groupId())
                 .add("path", path)
+                .add("resource", networkRes)
                 .toString();
     }
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/LabelStack.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/LabelStack.java
new file mode 100644
index 0000000..a529cce
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/LabelStack.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+package org.onosproject.incubator.net.tunnel;
+
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.net.NetworkResource;
+
+import java.util.List;
+
+/**
+ * Representation of a label stack in a network which represents the network path.
+ */
+public interface LabelStack extends NetworkResource {
+
+    /**
+     * Returns sequence of label resources comprising the path.
+     *
+     * @return list of links
+     */
+    List<LabelResourceId> labelResources();
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java
index 044533d..fd73846 100755
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelDescription.java
@@ -20,6 +20,7 @@
 import org.onosproject.incubator.net.tunnel.Tunnel.Type;
 import org.onosproject.net.Annotated;
 import org.onosproject.net.Description;
+import org.onosproject.net.NetworkResource;
 import org.onosproject.net.Path;
 import org.onosproject.net.provider.ProviderId;
 
@@ -84,4 +85,11 @@
      * @return the path of the tunnel
      */
     Path path();
+
+    /**
+     * Returns the network resource backing the tunnel, e.g. lambda, VLAN id, MPLS tag, label stack.
+     *
+     * @return backing resource
+     */
+    NetworkResource resource();
 }
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java
index f93fae9..3c846a6 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/tunnel/impl/TunnelManager.java
@@ -67,6 +67,7 @@
         implements TunnelService, TunnelAdminService, TunnelProviderRegistry {
 
     private static final String TUNNNEL_ID_NULL = "Tunnel ID cannot be null";
+    private static final String TUNNNEL_NULL = "Tunnel cannot be null";
 
     private final Logger log = getLogger(getClass());
 
@@ -235,13 +236,35 @@
 
     @Override
     public TunnelId setupTunnel(ApplicationId producerId, ElementId srcElementId, Tunnel tunnel, Path path) {
-        // TODO: Insert into store and trigger provider API.
-        return null;
+        // TODO: producerId to check if really required to consider while setup the tunnel.
+        checkNotNull(tunnel, TUNNNEL_NULL);
+        TunnelId tunnelId = store.createOrUpdateTunnel(tunnel, State.INIT);
+        if (tunnelId != null) {
+            Set<ProviderId> ids = getProviders();
+            for (ProviderId providerId : ids) {
+                TunnelProvider provider = getProvider(providerId);
+                provider.setupTunnel(srcElementId, tunnel, path);
+            }
+        }
+        return tunnelId;
     }
 
     @Override
     public boolean downTunnel(ApplicationId producerId, TunnelId tunnelId) {
-        // TODO: Change the tunnel status and trigger provider API.
+        // TODO: producerId to check if really required to consider while deleting the tunnel.
+        checkNotNull(tunnelId, TUNNNEL_ID_NULL);
+        Tunnel tunnel = store.queryTunnel(tunnelId);
+        if (tunnel != null) {
+            TunnelId updtTunnelId = store.createOrUpdateTunnel(tunnel, State.INACTIVE);
+            if (updtTunnelId != null) {
+                Set<ProviderId> ids = getProviders();
+                for (ProviderId providerId : ids) {
+                    TunnelProvider provider = getProvider(providerId);
+                    provider.releaseTunnel(tunnel);
+                }
+            }
+            return true;
+        }
         return false;
     }
 
@@ -324,6 +347,7 @@
                                                     tunnel.id(),
                                                     tunnel.tunnelName(),
                                                     tunnel.path(),
+                                                    tunnel.resource(),
                                                     tunnel.annotations());
             return store.createOrUpdateTunnel(storedTunnel);
         }
@@ -338,6 +362,7 @@
                                                     tunnel.id(),
                                                     tunnel.tunnelName(),
                                                     tunnel.path(),
+                                                    tunnel.resource(),
                                                     tunnel.annotations());
             return store.createOrUpdateTunnel(storedTunnel);
         }
@@ -351,6 +376,7 @@
                                                     tunnel.id(),
                                                     tunnel.tunnelName(),
                                                     tunnel.path(),
+                                                    tunnel.resource(),
                                                     tunnel.annotations());
             store.createOrUpdateTunnel(storedTunnel);
         }
@@ -365,6 +391,7 @@
                                                     tunnel.id(),
                                                     tunnel.tunnelName(),
                                                     tunnel.path(),
+                                                    tunnel.resource(),
                                                     tunnel.annotations());
             store.createOrUpdateTunnel(storedTunnel, state);
         }
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java
index bf61e0d..45e83b25 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/tunnel/impl/DistributedTunnelStore.java
@@ -174,6 +174,7 @@
                                             old.tunnelId(),
                                             old.tunnelName(),
                                             old.path(),
+                                            old.resource(),
                                             DefaultAnnotations.merge(oldAnno, newAnno));
             tunnelIdAsKeyStore.put(tunnel.tunnelId(), newT);
             TunnelEvent event = new TunnelEvent(TunnelEvent.Type.TUNNEL_UPDATED,
@@ -189,6 +190,7 @@
                                             tunnelId,
                                             tunnel.tunnelName(),
                                             tunnel.path(),
+                                            tunnel.resource(),
                                             tunnel.annotations());
             tunnelIdAsKeyStore.put(tunnelId, newT);