You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2012/09/17 05:11:15 UTC

[5/5] git commit: adds a state machine and state listener to Network objects

adds a state machine and state listener to Network objects


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/b89f7c61
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/b89f7c61
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/b89f7c61

Branch: refs/heads/events-framework
Commit: b89f7c61b3fc67f3841d352d672dd4fb1823642f
Parents: bfd6c67
Author: Murali Reddy <Mu...@citrix.com>
Authored: Sun Sep 16 21:03:59 2012 +0530
Committer: Murali Reddy <Mu...@citrix.com>
Committed: Sun Sep 16 21:03:59 2012 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java             |   51 ++++---------
 .../src/com/cloud/network/NetworkManagerImpl.java  |   59 +++++++++++---
 .../com/cloud/network/NetworkStateListener.java    |   31 ++++++++
 server/src/com/cloud/network/NetworkVO.java        |    1 +
 server/src/com/cloud/network/dao/NetworkDao.java   |    4 +-
 .../src/com/cloud/network/dao/NetworkDaoImpl.java  |   16 ++++
 6 files changed, 111 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b89f7c61/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 75d94ee..d220032 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -25,13 +25,13 @@ import com.cloud.acl.ControlledEntity;
 import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.Networks.Mode;
 import com.cloud.network.Networks.TrafficType;
-import com.cloud.utils.fsm.FiniteState;
-import com.cloud.utils.fsm.StateMachine;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.fsm.StateObject;
 
 /**
  * owned by an account. 
  */
-public interface Network extends ControlledEntity {
+public interface Network extends ControlledEntity, StateObject<Network.State> 	 {
     
     public enum GuestType {
         Shared,
@@ -197,7 +197,7 @@ public interface Network extends ControlledEntity {
         OperationFailed;
     }
 
-    enum State implements FiniteState<State, Event> {
+    public enum State {
         Allocated("Indicates the network configuration is in allocated but not setup"),
         Setup("Indicates the network configuration is setup"),
         Implementing("Indicates the network configuration is being implemented"),
@@ -205,39 +205,7 @@ public interface Network extends ControlledEntity {
         Shutdown("Indicates the network configuration is being destroyed"),
         Destroy("Indicates that the network is destroyed");
 
-
-        @Override
-        public StateMachine<State, Event> getStateMachine() {
-            return s_fsm;
-        }
-
-        @Override
-        public State getNextState(Event event) {
-            return s_fsm.getNextState(this, event);
-        }
-
-        @Override
-        public List<State> getFromStates(Event event) {
-            return s_fsm.getFromStates(this, event);
-        }
-
-        @Override
-        public Set<Event> getPossibleEvents() {
-            return s_fsm.getPossibleEvents(this);
-        }
-
-        String _description;
-
-        @Override
-        public String getDescription() {
-            return _description;
-        }
-
-        private State(String description) {
-            _description = description;
-        }
-
-        private static StateMachine<State, Event> s_fsm = new StateMachine<State, Event>();
+        protected static final StateMachine2<State, Network.Event, Network> s_fsm = new StateMachine2<State, Network.Event, Network>();
         static {
             s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implementing);
             s_fsm.addTransition(State.Implementing, Event.OperationSucceeded, State.Implemented);
@@ -246,6 +214,15 @@ public interface Network extends ControlledEntity {
             s_fsm.addTransition(State.Shutdown, Event.OperationSucceeded, State.Allocated);
             s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented);
         }
+
+        public static StateMachine2<State, Network.Event, Network> getStateMachine() {
+            return s_fsm;
+        }
+
+        String _description;
+        private State(String description) {
+            _description = description;
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b89f7c61/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index 292a259..08b0893 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -142,6 +142,7 @@ import com.cloud.network.element.StaticNatServiceProvider;
 import com.cloud.network.element.UserDataServiceProvider;
 import com.cloud.network.element.VirtualRouterElement;
 import com.cloud.network.element.VpcVirtualRouterElement;
+import com.cloud.network.Network.Event;
 import com.cloud.network.guru.NetworkGuru;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.lb.LoadBalancingRule.LbDestination;
@@ -200,6 +201,8 @@ import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.fsm.NoTransitionException;
+import com.cloud.utils.fsm.StateMachine2;
 import com.cloud.utils.net.Ip;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.Nic;
@@ -322,6 +325,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
     @Inject
     ResourceTagDao _resourceTagDao;
 
+    protected StateMachine2<Network.State, Network.Event, Network> _stateMachine;
     private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5);
     private static Long _privateOfferingId = null;
 
@@ -1503,6 +1507,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
 
         _agentMgr.registerForHostEvents(this, true, false, true);
 
+        Network.State.getStateMachine().registerListener(new NetworkStateListener(_usageEventDao, _networksDao));
+
         s_logger.info("Network Manager is configured.");
 
         return true;
@@ -1553,6 +1559,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
     }
 
     protected NetworkManagerImpl() {
+        setStateMachine();
     }
 
     @Override
@@ -1949,9 +1956,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
             NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId());
 
             network.setReservationId(context.getReservationId());
-            network.setState(Network.State.Implementing);
-
-            _networksDao.update(networkId, network);
+            stateTransitTo(network, Event.ImplementNetwork);
 
             Network result = guru.implement(network, offering, dest, context);
             network.setCidr(result.getCidr());
@@ -1964,16 +1969,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
             // implement network elements and re-apply all the network rules
             implementNetworkElementsAndResources(dest, context, network, offering);
 
-            network.setState(Network.State.Implemented);
+            stateTransitTo(network,Event.OperationSucceeded);
+
             network.setRestartRequired(false);
             _networksDao.update(network.getId(), network);
             implemented.set(guru, network);
             return implemented;
+        } catch (NoTransitionException e) {
+            s_logger.error(e.getMessage());
+            return null;
         } finally {
             if (implemented.first() == null) {
                 s_logger.debug("Cleaning up because we're unable to implement the network " + network);
-                network.setState(Network.State.Shutdown);
-                _networksDao.update(networkId, network);
+                try {
+                    stateTransitTo(network,Event.OperationFailed);
+                } catch (NoTransitionException e) {
+                    s_logger.error(e.getMessage());
+                }
 
                 shutdownNetwork(networkId, context, false);
             }
@@ -3401,8 +3413,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
             return false;
         }
 
-        network.setState(Network.State.Shutdown);
-        _networksDao.update(network.getId(), network);
+        try {
+            stateTransitTo(network, Event.DestroyNetwork);
+         } catch (NoTransitionException e) {
+             s_logger.debug(e.getMessage());
+         }
 
         boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network);
 
@@ -3418,14 +3433,22 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
 
             applyProfileToNetwork(network, profile);
 
-            network.setState(Network.State.Allocated);
+            try {
+                stateTransitTo(network, Event.OperationSucceeded);
+             } catch (NoTransitionException e) {
+                 s_logger.debug(e.getMessage());
+             }
+
             network.setRestartRequired(false);
             _networksDao.update(network.getId(), network);
             _networksDao.clearCheckForGc(networkId);
             result = true;
         } else {
-            network.setState(Network.State.Implemented);
-            _networksDao.update(network.getId(), network);
+            try {
+                stateTransitTo(network, Event.OperationFailed);
+             } catch (NoTransitionException e) {
+                 s_logger.debug(e.getMessage());
+             }
             result = false;
         }
         txn.commit();
@@ -3584,8 +3607,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
                 s_logger.warn("Failed to delete network " + network + "; was unable to cleanup corresponding ip ranges");
             } else {
                 // commit transaction only when ips and vlans for the network are released successfully
-                network.setState(Network.State.Destroy);
-                _networksDao.update(network.getId(), network);
+                try {
+                    stateTransitTo(network, Event.DestroyNetwork);
+                 } catch (NoTransitionException e) {
+                     s_logger.debug(e.getMessage());
+                 }
                 _networksDao.remove(network.getId());
                 txn.commit();
             }
@@ -7331,4 +7357,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
         return _networkLockTimeout;
     }
 
+    protected boolean stateTransitTo(NetworkVO network, Network.Event e) throws NoTransitionException {
+        return _stateMachine.transitTo(network, e, null, _networksDao);
+    }
+
+    private void setStateMachine() {
+        _stateMachine = Network.State.getStateMachine();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b89f7c61/server/src/com/cloud/network/NetworkStateListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkStateListener.java b/server/src/com/cloud/network/NetworkStateListener.java
new file mode 100644
index 0000000..fdabeb0
--- /dev/null
+++ b/server/src/com/cloud/network/NetworkStateListener.java
@@ -0,0 +1,31 @@
+package com.cloud.network;
+
+import com.cloud.event.dao.UsageEventDao;
+import com.cloud.network.Network.Event;
+import com.cloud.network.Network.State;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.utils.fsm.StateListener;
+
+public class NetworkStateListener implements StateListener<State, Event, Network> {
+
+    protected UsageEventDao _usageEventDao;
+    protected NetworkDao _networkDao;
+
+    public NetworkStateListener(UsageEventDao usageEventDao, NetworkDao networkDao) {
+        this._usageEventDao = usageEventDao;
+        this._networkDao = networkDao;
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b89f7c61/server/src/com/cloud/network/NetworkVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java
index 39dd66e..7108701 100644
--- a/server/src/com/cloud/network/NetworkVO.java
+++ b/server/src/com/cloud/network/NetworkVO.java
@@ -247,6 +247,7 @@ public class NetworkVO implements Network, Identity {
         return state;
     }
 
+    // don't use this directly when possible, use Network state machine instead
     public void setState(State state) {
         this.state = state;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b89f7c61/server/src/com/cloud/network/dao/NetworkDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java
index a2e37b7..396650b 100644
--- a/server/src/com/cloud/network/dao/NetworkDao.java
+++ b/server/src/com/cloud/network/dao/NetworkDao.java
@@ -24,10 +24,12 @@ import com.cloud.network.Network.GuestType;
 import com.cloud.network.NetworkAccountVO;
 import com.cloud.network.NetworkVO;
 import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.Network.State;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.fsm.StateDao;
 
-public interface NetworkDao extends GenericDao<NetworkVO, Long> {
+public interface NetworkDao extends GenericDao<NetworkVO, Long> , StateDao<State, Network.Event, Network> {
 
     List<NetworkVO> listByOwner(long ownerId);
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b89f7c61/server/src/com/cloud/network/dao/NetworkDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java
index cbfec89..b3d3f71 100644
--- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java
@@ -25,9 +25,11 @@ import javax.persistence.TableGenerator;
 
 import com.cloud.acl.ControlledEntity.ACLType;
 import com.cloud.network.Network;
+import com.cloud.network.Network.Event;
 import com.cloud.network.Network.GuestType;
 import com.cloud.network.Network.Provider;
 import com.cloud.network.Network.Service;
+import com.cloud.network.Network.State;
 import com.cloud.network.NetworkAccountDaoImpl;
 import com.cloud.network.NetworkAccountVO;
 import com.cloud.network.NetworkDomainVO;
@@ -551,4 +553,18 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
         sc.setParameters("vpcId", vpcId);
         return customSearch(sc, null).get(0);
     }
+
+	@Override
+	public boolean updateState(State currentState, Event event, State nextState, Network vo, Object data) {
+	   // TODO: ensure this update is correct
+       Transaction txn = Transaction.currentTxn();
+        txn.start();
+
+        NetworkVO networkVo = (NetworkVO) vo;
+        networkVo.setState(nextState);
+        super.update(networkVo.getId(), networkVo);
+
+        txn.commit();
+        return true;
+    }
 }