[GoldenEye] [ONOS-4163] Add provider service update API with status change

Change-Id: Id8774f5577f735566b1826ab4adfe5969c3aa168
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java
index d543437..2cda4a3 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelProviderService.java
@@ -60,6 +60,14 @@
     void tunnelUpdated(TunnelDescription tunnel);
 
     /**
+     * Signals that the tunnel was changed with tunnel status change.
+     *
+     * @param tunnel tunnel information
+     * @param state tunnel working status
+     */
+    void tunnelUpdated(TunnelDescription tunnel, State state);
+
+    /**
      * Signals that the a tunnel was queried.
      *
      * @param tunnelId tunnel identity
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java
index 6940ab2..519c9f7 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/tunnel/TunnelStore.java
@@ -19,6 +19,7 @@
 
 import com.google.common.annotations.Beta;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.tunnel.Tunnel.State;
 import org.onosproject.incubator.net.tunnel.Tunnel.Type;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.provider.ProviderId;
@@ -38,6 +39,15 @@
     TunnelId createOrUpdateTunnel(Tunnel tunnel);
 
     /**
+     * Creates a tunnel or updates a tunnel with the new state given in input.
+     *
+     * @param tunnel tunnel
+     * @param state tunnel state
+     * @return tunnel identity
+     */
+    TunnelId createOrUpdateTunnel(Tunnel tunnel, State state);
+
+    /**
      * Deletes a tunnel by a specific tunnel identifier.
      *
      * @param tunnelId tunnel unique identifier generated by ONOS
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 702667f..8a9225b 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
@@ -337,6 +337,20 @@
         }
 
         @Override
+        public void tunnelUpdated(TunnelDescription tunnel, State state) {
+            Tunnel storedTunnel = new DefaultTunnel(provider().id(),
+                                                    tunnel.src(), tunnel.dst(),
+                                                    tunnel.type(),
+                                                    state,
+                                                    tunnel.groupId(),
+                                                    tunnel.id(),
+                                                    tunnel.tunnelName(),
+                                                    tunnel.path(),
+                                                    tunnel.annotations());
+            store.createOrUpdateTunnel(storedTunnel, state);
+        }
+
+        @Override
         public void tunnelRemoved(TunnelDescription tunnel) {
             if (tunnel.id() != null) {
                 store.deleteTunnel(tunnel.id());
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 9a1871d..7f5074a 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
@@ -38,6 +38,7 @@
 import org.onosproject.core.IdGenerator;
 import org.onosproject.incubator.net.tunnel.DefaultTunnel;
 import org.onosproject.incubator.net.tunnel.Tunnel;
+import org.onosproject.incubator.net.tunnel.Tunnel.State;
 import org.onosproject.incubator.net.tunnel.Tunnel.Type;
 import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
 import org.onosproject.incubator.net.tunnel.TunnelEvent;
@@ -147,6 +148,15 @@
 
     @Override
     public TunnelId createOrUpdateTunnel(Tunnel tunnel) {
+        return handleCreateOrUpdateTunnel(tunnel, null);
+    }
+
+    @Override
+    public TunnelId createOrUpdateTunnel(Tunnel tunnel, State state) {
+        return handleCreateOrUpdateTunnel(tunnel, state);
+    }
+
+    private TunnelId handleCreateOrUpdateTunnel(Tunnel tunnel, State state) {
         // tunnelIdAsKeyStore.
         if (tunnel.tunnelId() != null && !"".equals(tunnel.tunnelId().toString())) {
             Tunnel old = tunnelIdAsKeyStore.get(tunnel.tunnelId());
@@ -156,24 +166,25 @@
             }
             DefaultAnnotations oldAnno = (DefaultAnnotations) old.annotations();
             SparseAnnotations newAnno = (SparseAnnotations) tunnel.annotations();
+            State newTunnelState = (state != null) ? state : old.state();
             Tunnel newT = new DefaultTunnel(old.providerId(), old.src(),
                                             old.dst(), old.type(),
-                                            old.state(), old.groupId(),
+                                            newTunnelState, old.groupId(),
                                             old.tunnelId(),
                                             old.tunnelName(),
                                             old.path(),
                                             DefaultAnnotations.merge(oldAnno, newAnno));
             tunnelIdAsKeyStore.put(tunnel.tunnelId(), newT);
-            TunnelEvent event = new TunnelEvent(
-                                                TunnelEvent.Type.TUNNEL_UPDATED,
+            TunnelEvent event = new TunnelEvent(TunnelEvent.Type.TUNNEL_UPDATED,
                                                 tunnel);
             notifyDelegate(event);
             return tunnel.tunnelId();
         } else {
             TunnelId tunnelId = TunnelId.valueOf(idGenerator.getNewId());
+            State tunnelState = (state != null) ? state : tunnel.state();
             Tunnel newT = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
                                             tunnel.dst(), tunnel.type(),
-                                            tunnel.state(), tunnel.groupId(),
+                                            tunnelState, tunnel.groupId(),
                                             tunnelId,
                                             tunnel.tunnelName(),
                                             tunnel.path(),
diff --git a/providers/ovsdb/tunnel/src/test/java/org/onosproject/ovsdb/provider/tunnel/OvsdbTunnelProviderTest.java b/providers/ovsdb/tunnel/src/test/java/org/onosproject/ovsdb/provider/tunnel/OvsdbTunnelProviderTest.java
index b8d4d14..566f535 100644
--- a/providers/ovsdb/tunnel/src/test/java/org/onosproject/ovsdb/provider/tunnel/OvsdbTunnelProviderTest.java
+++ b/providers/ovsdb/tunnel/src/test/java/org/onosproject/ovsdb/provider/tunnel/OvsdbTunnelProviderTest.java
@@ -182,6 +182,11 @@
         }
 
         @Override
+        public void tunnelUpdated(TunnelDescription tunnel, State state) {
+
+        }
+
+        @Override
         public Tunnel tunnelQueryById(TunnelId tunnelId) {
             return null;
         }
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/TunnelProviderRegistryAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/TunnelProviderRegistryAdapter.java
index d455e7f..d331407 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/TunnelProviderRegistryAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/TunnelProviderRegistryAdapter.java
@@ -70,6 +70,10 @@
         }
 
         @Override
+        public void tunnelUpdated(TunnelDescription tunnel, State state) {
+        }
+
+        @Override
         public Tunnel tunnelQueryById(TunnelId tunnelId) {
             return null;
         }