ONOS-5549 TE Tunnel LSP attributes management

Change-Id: I1f8f7fdd23f26ed0600c27dc7d958dff872e6d35
diff --git a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelProviderService.java b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelProviderService.java
index 4b510b1..416d11b 100755
--- a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelProviderService.java
+++ b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelProviderService.java
@@ -18,6 +18,8 @@
 
 import org.onosproject.incubator.net.tunnel.Tunnel;
 import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.tetunnel.api.lsp.TeLsp;
+import org.onosproject.tetunnel.api.lsp.TeLspKey;
 import org.onosproject.tetunnel.api.tunnel.TeTunnel;
 import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
 
@@ -62,5 +64,27 @@
      */
     void updateTunnelState(TeTunnelKey key, Tunnel.State state);
 
+    /**
+     * Signifies that a TE LSP is created.
+     *
+     * @param lsp new created TE LSP attributes
+     * @return key of the TE LSP or null if failed
+     */
+    TeLspKey teLspAdded(TeLsp lsp);
+
+    /**
+     * Signifies that a TE LSP is removed.
+     *
+     * @param lsp removed TE LSP
+     */
+    void teLspRemoved(TeLsp lsp);
+
+    /**
+     * Updates TE LSP attributes.
+     *
+     * @param lsp new TE LSP attributes
+     */
+    void updateTeLsp(TeLsp lsp);
+
     //TODO: add interfaces for teGlobal and teLspState
 }
diff --git a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelService.java b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelService.java
index d4dd4b3..f6fef66 100755
--- a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelService.java
+++ b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelService.java
@@ -18,6 +18,8 @@
 
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetunnel.api.lsp.TeLsp;
+import org.onosproject.tetunnel.api.lsp.TeLspKey;
 import org.onosproject.tetunnel.api.tunnel.TeTunnel;
 import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
 
@@ -83,5 +85,20 @@
      */
     Collection<TeTunnel> getTeTunnels(TeTopologyKey teTopologyKey);
 
+    /**
+     * Returns the TE LSP with the specified key.
+     *
+     * @param key TE LSP key
+     * @return TeLsp or null if one with the given key is not known
+     */
+    TeLsp getTeLsp(TeLspKey key);
+
+    /**
+     * Returns a collection of currently known TE LSPs.
+     *
+     * @return collection of TeLsp
+     */
+    Collection<TeLsp> getTeLsps();
+
     //TODO: add interfaces for teGlobal and teLspState
 }
diff --git a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelStore.java b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelStore.java
index 84b795d..192dca2 100755
--- a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelStore.java
+++ b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/TeTunnelStore.java
@@ -18,6 +18,8 @@
 
 import org.onosproject.incubator.net.tunnel.TunnelId;
 import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetunnel.api.lsp.TeLsp;
+import org.onosproject.tetunnel.api.lsp.TeLspKey;
 import org.onosproject.tetunnel.api.tunnel.TeTunnel;
 import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
 
@@ -114,4 +116,41 @@
      * @return filtered collection of TE tunnels
      */
     Collection<TeTunnel> getTeTunnels(TeTopologyKey teTopologyKey);
+
+    /**
+     * Adds a TE LSP.
+     *
+     * @param lsp TE LSP attributes
+     * @return true when success
+     */
+    boolean addTeLsp(TeLsp lsp);
+
+    /**
+     * Updates TE LSP attributes.
+     *
+     * @param lsp new TE LSP attributes
+     */
+    void updateTeLsp(TeLsp lsp);
+
+    /**
+     * Removes a TE LSP.
+     *
+     * @param key TE LSP key
+     */
+    void removeTeLsp(TeLspKey key);
+
+    /**
+     * Returns the TE LSP with the specified key.
+     *
+     * @param key TE LSP key
+     * @return TeLsp or null if one with the given key is not known
+     */
+    TeLsp getTeLsp(TeLspKey key);
+
+    /**
+     * Returns a collection of currently known TE LSP.
+     *
+     * @return collection of TeLsp
+     */
+    Collection<TeLsp> getTeLsps();
 }
diff --git a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/lsp/DefaultTeLsp.java b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/lsp/DefaultTeLsp.java
new file mode 100755
index 0000000..56d56a1
--- /dev/null
+++ b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/lsp/DefaultTeLsp.java
@@ -0,0 +1,297 @@
+/*
+ * 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.tetunnel.api.lsp;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TtpKey;
+import org.onosproject.tetunnel.api.tunnel.TeTunnel;
+import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
+import org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject;
+
+import java.util.List;
+
+/**
+ * Default implementation of TE LSP.
+ */
+public class DefaultTeLsp implements TeLsp {
+
+    private final TeLspKey teLspKey;
+    private final TeNodeKey srcNode;
+    private final TeNodeKey dstNode;
+    private final TtpKey srcTp;
+    private final TtpKey dstTp;
+    private final TeTunnelKey teTunnelKey;
+    private final TeTunnel.Type tunnelType;
+    private final TeTunnel.State operStatus;
+    private final LspProtectionRole lspProtectionRole;
+    private final OriginType originType;
+    private final List<TeRouteSubobject> lspRecordRoutes;
+
+    /**
+     * Creates an instance of default TE LSP with supplied information.
+     *
+     * @param teLspKey TE LSP key
+     * @param srcNode source TE node key
+     * @param dstNode destination TE node key
+     * @param srcTp source TE termination point key
+     * @param dstTp destination TE termination point key
+     * @param teTunnelKey TE tunnel key
+     * @param tunnelType TE tunnel type
+     * @param operStatus operational status
+     * @param lspProtectionRole protection type
+     * @param originType origin type
+     * @param lspRecordRoutes route of the LSP
+     */
+    protected DefaultTeLsp(TeLspKey teLspKey, TeNodeKey srcNode, TeNodeKey dstNode,
+                        TtpKey srcTp, TtpKey dstTp, TeTunnelKey teTunnelKey,
+                        TeTunnel.Type tunnelType, TeTunnel.State operStatus,
+                        LspProtectionRole lspProtectionRole,
+                        OriginType originType,
+                        List<TeRouteSubobject> lspRecordRoutes) {
+        this.srcNode = srcNode;
+        this.dstNode = dstNode;
+        this.srcTp = srcTp;
+        this.dstTp = dstTp;
+        this.teTunnelKey = teTunnelKey;
+        this.tunnelType = tunnelType;
+        this.operStatus = operStatus;
+        this.lspProtectionRole = lspProtectionRole;
+        this.originType = originType;
+        this.lspRecordRoutes = Lists.newArrayList(lspRecordRoutes);
+        this.teLspKey = teLspKey;
+    }
+
+    @Override
+    public TeLspKey teLspKey() {
+        return teLspKey;
+    }
+
+    @Override
+    public TeNodeKey srcNode() {
+        return srcNode;
+    }
+
+    @Override
+    public TeNodeKey dstNode() {
+        return dstNode;
+    }
+
+    @Override
+    public TtpKey srcTp() {
+        return srcTp;
+    }
+
+    @Override
+    public TtpKey dstTp() {
+        return dstTp;
+    }
+
+    @Override
+    public TeTunnelKey teTunnelKey() {
+        return teTunnelKey;
+    }
+
+    @Override
+    public TeTunnel.Type tunnelType() {
+        return tunnelType;
+    }
+
+    @Override
+    public TeTunnel.State operStatus() {
+        return operStatus;
+    }
+
+    @Override
+    public LspProtectionRole lspProtectionRole() {
+        return lspProtectionRole;
+    }
+
+    @Override
+    public OriginType originType() {
+        return originType;
+    }
+
+    @Override
+    public List<TeRouteSubobject> lspRecordRoutes() {
+        return ImmutableList.copyOf(lspRecordRoutes);
+    }
+
+
+    /**
+     * Creates a new default TE LSP builder.
+     *
+     * @return default builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for default TE LSP objects.
+     */
+    public static class Builder {
+
+        private TeLspKey teLspKey = null;
+        private TeNodeKey srcNode = null;
+        private TeNodeKey dstNode = null;
+        private TtpKey srcTp = null;
+        private TtpKey dstTp = null;
+        private TeTunnelKey teTunnelKey = null;
+        private TeTunnel.Type tunnelType = null;
+        private TeTunnel.State operStatus = null;
+        private LspProtectionRole lspProtectionRole = null;
+        private OriginType originType = null;
+        private List<TeRouteSubobject> lspRecordRoutes = Lists.newArrayList();
+
+        /**
+         * Builds a default TE LSP object from the accumulated parameters.
+         *
+         * @return default TE LSP object
+         */
+        public DefaultTeLsp build() {
+            return new DefaultTeLsp(teLspKey, srcNode, dstNode, srcTp, dstTp,
+                                    teTunnelKey, tunnelType, operStatus,
+                                    lspProtectionRole, originType,
+                                    lspRecordRoutes);
+        }
+
+        /**
+         * Sets TE LSP key to be used by this builder.
+         *
+         * @param teLspKey TE LSP key
+         * @return self
+         */
+        public Builder teLspKey(TeLspKey teLspKey) {
+            this.teLspKey = teLspKey;
+            return this;
+        }
+
+        /**
+         * Sets source node key to be used by this builder.
+         *
+         * @param srcNode source node key
+         * @return self
+         */
+        public Builder srcNode(TeNodeKey srcNode) {
+            this.srcNode = srcNode;
+            return this;
+        }
+
+        /**
+         * Sets destination node key to be used by this builder.
+         *
+         * @param dstNode destination node key
+         * @return self
+         */
+        public Builder dstNode(TeNodeKey dstNode) {
+            this.dstNode = dstNode;
+            return this;
+        }
+
+        /**
+         * Sets source termination point key to be used by this builder.
+         *
+         * @param srcTp source termination point key
+         * @return self
+         */
+        public Builder srcTp(TtpKey srcTp) {
+            this.srcTp = srcTp;
+            return this;
+        }
+
+        /**
+         * Sets destination termination point key to be used by this builder.
+         *
+         * @param dstTp destination termination point key
+         * @return self
+         */
+        public Builder dstTp(TtpKey dstTp) {
+            this.dstTp = dstTp;
+            return this;
+        }
+
+        /**
+         * Sets TE tunnel key to be used by this builder.
+         *
+         * @param teTunnelKey TE tunnel key
+         * @return self
+         */
+        public Builder teTunnelKey(TeTunnelKey teTunnelKey) {
+            this.teTunnelKey = teTunnelKey;
+            return this;
+        }
+
+        /**
+         * Sets TE tunnel type to be used by this builder.
+         *
+         * @param tunnelType TE tunnel type
+         * @return self
+         */
+        public Builder tunnelType(TeTunnel.Type tunnelType) {
+            this.tunnelType = tunnelType;
+            return this;
+        }
+
+        /**
+         * Sets LSP operational status to be used by this builder.
+         *
+         * @param operStatus LSP operational status
+         * @return self
+         */
+        public Builder operStatus(TeTunnel.State operStatus) {
+            this.operStatus = operStatus;
+            return this;
+        }
+
+        /**
+         * Sets LSP protection role to be used by this builder.
+         *
+         * @param lspProtectionRole LSP protection role
+         * @return self
+         */
+        public Builder lspProtectionRole(LspProtectionRole lspProtectionRole) {
+            this.lspProtectionRole = lspProtectionRole;
+            return this;
+        }
+
+        /**
+         * Sets LSP origin type to be used by this builder.
+         *
+         * @param originType LSP origin type
+         * @return self
+         */
+        public Builder originType(OriginType originType) {
+            this.originType = originType;
+            return this;
+        }
+
+        /**
+         * Sets LSP record routes to be used by this builder.
+         *
+         * @param lspRecordRoutes LSP record routes
+         * @return self
+         */
+        public Builder lspRecordRoutes(List<TeRouteSubobject> lspRecordRoutes) {
+            if (lspRecordRoutes != null) {
+                this.lspRecordRoutes = lspRecordRoutes;
+            }
+            return this;
+        }
+    }
+}
diff --git a/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/lsp/TeLsp.java b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/lsp/TeLsp.java
new file mode 100755
index 0000000..95b55cc
--- /dev/null
+++ b/apps/tetunnel/api/src/main/java/org/onosproject/tetunnel/api/lsp/TeLsp.java
@@ -0,0 +1,135 @@
+/*
+ * 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.tetunnel.api.lsp;
+
+import org.onosproject.tetopology.management.api.node.TeNodeKey;
+import org.onosproject.tetopology.management.api.node.TtpKey;
+import org.onosproject.tetunnel.api.tunnel.TeTunnel;
+import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
+import org.onosproject.tetunnel.api.tunnel.path.TeRouteSubobject;
+
+import java.util.List;
+
+/**
+ * Representation of a TE LSP.
+ */
+public interface TeLsp {
+
+    /**
+     * Protection roles of TE LSP.
+     */
+    enum LspProtectionRole {
+        /**
+         * Designates a working LSP.
+         */
+        WORKING,
+        /**
+         * Designates a protection LSP.
+         */
+        PROTECTION
+    }
+
+    /**
+     * Origin type of LSP relative to the location of the local switch in the
+     * path.
+     */
+    enum OriginType {
+        INGRESS,
+        EGRESS,
+        TRANSIT
+    }
+
+    /**
+     * Returns key of this TE LSP.
+     *
+     * @return key of this TE LSP
+     */
+    TeLspKey teLspKey();
+
+    /**
+     * Returns source TE node of this tunnel.
+     *
+     * @return source TE node key
+     */
+    TeNodeKey srcNode();
+
+    /**
+     * Returns source TE termination point of this tunnel.
+     *
+     * @return source TE termination point key
+     */
+    TtpKey srcTp();
+
+    /**
+     * Returns destination TE node of this tunnel.
+     *
+     * @return destination TE node key
+     */
+    TeNodeKey dstNode();
+
+    /**
+     * Returns destination TE termination point of this tunnel.
+     *
+     * @return destination TE termination point key
+     */
+    TtpKey dstTp();
+
+    /**
+     * Returns the TE tunnel used in the SESSION that remains constant over
+     * the life of the tunnel.
+     *
+     * @return TE tunnel key
+     */
+    TeTunnelKey teTunnelKey();
+
+    /**
+     * Returns corresponding tunnel type.
+     *
+     * @return TE tunnel type
+     */
+    TeTunnel.Type tunnelType();
+
+    /**
+     * Returns operational status of the LSP.
+     *
+     * @return operational status
+     */
+    TeTunnel.State operStatus();
+
+    /**
+     * Returns protection role of the LSP.
+     *
+     * @return protection role
+     */
+    LspProtectionRole lspProtectionRole();
+
+    /**
+     * Return origin type of the LSP.
+     *
+     * @return origin type
+     */
+    OriginType originType();
+
+    /**
+     * Returns route of this LSP.
+     *
+     * @return list of TeRouteSubobject
+     */
+    List<TeRouteSubobject> lspRecordRoutes();
+
+    //TODO add more attributes here.
+}
diff --git a/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/DistributedTeTunnelStore.java b/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/DistributedTeTunnelStore.java
index 2824007..ddca1e1 100755
--- a/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/DistributedTeTunnelStore.java
+++ b/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/DistributedTeTunnelStore.java
@@ -30,6 +30,8 @@
 import org.onosproject.store.service.LogicalClockService;
 import org.onosproject.store.service.StorageService;
 import org.onosproject.tetopology.management.api.TeTopologyKey;
+import org.onosproject.tetunnel.api.lsp.TeLsp;
+import org.onosproject.tetunnel.api.lsp.TeLspKey;
 import org.onosproject.tetunnel.api.tunnel.TeTunnel;
 import org.onosproject.tetunnel.api.TeTunnelStore;
 import org.onosproject.tetunnel.api.tunnel.TeTunnelKey;
@@ -57,6 +59,7 @@
 
     private EventuallyConsistentMap<TeTunnelKey, TeTunnel> teTunnels;
     private EventuallyConsistentMap<TeTunnelKey, TunnelId> tunnelIds;
+    private EventuallyConsistentMap<TeLspKey, TeLsp> lsps;
 
     @Activate
     public void activate() {
@@ -77,6 +80,12 @@
                 .withTimestampProvider((k, v) -> clockService.getTimestamp())
                 .build();
 
+        lsps = storageService.<TeLspKey, TeLsp>eventuallyConsistentMapBuilder()
+                .withName("TeLspStore")
+                .withSerializer(serializer)
+                .withTimestampProvider((k, v) -> clockService.getTimestamp())
+                .build();
+
         log.info("Started");
     }
 
@@ -84,6 +93,7 @@
     public void deactivate() {
         teTunnels.destroy();
         tunnelIds.destroy();
+        lsps.destroy();
 
         log.info("Stopped");
     }
@@ -166,4 +176,42 @@
                         .equals(teTopologyKey))
                 .collect(Collectors.toList()));
     }
+
+    @Override
+    public boolean addTeLsp(TeLsp lsp) {
+        if (lsp == null) {
+            log.warn("TeLsp is null");
+            return false;
+        }
+        if (lsps.containsKey(lsp.teLspKey())) {
+            log.error("TeLsp exist {}", lsp.teLspKey());
+            return false;
+        }
+        lsps.put(lsp.teLspKey(), lsp);
+        return true;
+    }
+
+    @Override
+    public void updateTeLsp(TeLsp lsp) {
+        if (lsp == null) {
+            log.warn("TeLsp is null");
+            return;
+        }
+        lsps.put(lsp.teLspKey(), lsp);
+    }
+
+    @Override
+    public void removeTeLsp(TeLspKey key) {
+        lsps.remove(key);
+    }
+
+    @Override
+    public TeLsp getTeLsp(TeLspKey key) {
+        return lsps.get(key);
+    }
+
+    @Override
+    public Collection<TeLsp> getTeLsps() {
+        return ImmutableList.copyOf(lsps.values());
+    }
 }
diff --git a/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/TeTunnelManager.java b/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/TeTunnelManager.java
index 82ce04f..3fc28fb 100755
--- a/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/TeTunnelManager.java
+++ b/apps/tetunnel/app/src/main/java/org/onosproject/tetunnel/impl/TeTunnelManager.java
@@ -37,6 +37,8 @@
 import org.onosproject.tetopology.management.api.TeTopology;
 import org.onosproject.tetopology.management.api.TeTopologyKey;
 import org.onosproject.tetopology.management.api.TeTopologyService;
+import org.onosproject.tetunnel.api.lsp.TeLsp;
+import org.onosproject.tetunnel.api.lsp.TeLspKey;
 import org.onosproject.tetunnel.api.tunnel.TeTunnel;
 import org.onosproject.tetunnel.api.TeTunnelAdminService;
 import org.onosproject.tetunnel.api.TeTunnelProviderService;
@@ -151,6 +153,25 @@
     }
 
     @Override
+    public TeLspKey teLspAdded(TeLsp lsp) {
+        if (store.addTeLsp(lsp)) {
+            return lsp.teLspKey();
+        }
+
+        return null;
+    }
+
+    @Override
+    public void teLspRemoved(TeLsp lsp) {
+        store.removeTeLsp(lsp.teLspKey());
+    }
+
+    @Override
+    public void updateTeLsp(TeLsp lsp) {
+        store.updateTeLsp(lsp);
+    }
+
+    @Override
     public void removeTeTunnel(TeTunnelKey teTunnelKey) {
         tunnelAdminService.updateTunnelState(
                 tunnelService.queryTunnel(getTunnelId(teTunnelKey)),
@@ -214,6 +235,16 @@
     }
 
     @Override
+    public TeLsp getTeLsp(TeLspKey key) {
+        return store.getTeLsp(key);
+    }
+
+    @Override
+    public Collection<TeLsp> getTeLsps() {
+        return store.getTeLsps();
+    }
+
+    @Override
     public TunnelId teTunnelAdded(TeTunnel teTunnel) {
         //TODO teTunnelAdded
         return null;