Michael Pasternak has uploaded a new change for review.

Change subject: cli: implement StateMachine.rollback()
......................................................................

cli: implement StateMachine.rollback()

StateMachine.rollback() is triggered when an error occurred during
logical state transition, such as connection failure in 'connect'
command,

calling rollback() will return StateMachine to the origin state
whatever it was before the failure.

Change-Id: Ideaf855e2475bd39cf15454b09aa8add0fc08726
Signed-off-by: Michael pasternak <[email protected]>
---
M src/ovirtcli/command/connect.py
M src/ovirtcli/command/disconnect.py
M src/ovirtcli/state/dfsaevent.py
M src/ovirtcli/state/finitestatemachine.py
M src/ovirtcli/state/statemachine.py
5 files changed, 51 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine-cli refs/changes/76/23076/1

diff --git a/src/ovirtcli/command/connect.py b/src/ovirtcli/command/connect.py
index 5063268..61723d8 100644
--- a/src/ovirtcli/command/connect.py
+++ b/src/ovirtcli/command/connect.py
@@ -144,16 +144,20 @@
             StateMachine.connected()  # @UndefinedVariable
 
         except RequestError, e:
+            StateMachine.rollback()
             self.__cleanContext()
             self.error("[" + str(e.status) + '] - ' + str(e.reason) + ', ' + 
str(e.detail))
         except NoCertificatesError:
+            StateMachine.rollback()
             self.__cleanContext()
             self.error(Messages.Error.NO_CERTIFICATES)
         except ConnectionError, e:
+            StateMachine.rollback()
             self.__cleanContext()
             self.context._clean_settings()
             self.error(str(e))
         except TypeError, e:
+            StateMachine.rollback()
             self.__cleanContext()
             option, value, expected = self.__normalize_typeerror(e)
             self.error(
@@ -163,6 +167,7 @@
                                expected)
             )
         except Exception, e:
+            StateMachine.rollback()
             self.__cleanContext()
             self.error(str(e))
         finally:
diff --git a/src/ovirtcli/command/disconnect.py 
b/src/ovirtcli/command/disconnect.py
index 1afae0c..8adc57d 100644
--- a/src/ovirtcli/command/disconnect.py
+++ b/src/ovirtcli/command/disconnect.py
@@ -49,6 +49,7 @@
             connection.disconnect()
             self.context.status = ExecutionContext.OK
         except Exception:
+            # TODO: consider rollback on disconnect failure 
(StateMachine.rollback())
             self.context.status = ExecutionContext.COMMAND_ERROR
         finally:
             self.context._clean_settings()
diff --git a/src/ovirtcli/state/dfsaevent.py b/src/ovirtcli/state/dfsaevent.py
index 589fda1..7ab3414 100644
--- a/src/ovirtcli/state/dfsaevent.py
+++ b/src/ovirtcli/state/dfsaevent.py
@@ -24,7 +24,7 @@
     Finite-State Automata event
     '''
 
-    def __init__(self, name, sources, destination, callbacks=[]):
+    def __init__(self, name, sources, destination, description=None, 
callbacks=[]):
         '''
         @param name: the state event name
         @param sources: the source states from which destination state is 
eligible
@@ -35,6 +35,7 @@
         self.__name = name
         self.__sources = sources
         self.__destination = destination
+        self.__description = description
         self.__callbacks = callbacks
 
     def get_name(self):
@@ -55,6 +56,12 @@
         """
         return self.__destination
 
+    def get_description(self):
+        """
+        @return: the description of DFSAEvent
+        """
+        return self.__description
+
     def get_callbacks(self):
         """
         @return: the destination of DFSAEvent
diff --git a/src/ovirtcli/state/finitestatemachine.py 
b/src/ovirtcli/state/finitestatemachine.py
index 3add699..a43cebb 100644
--- a/src/ovirtcli/state/finitestatemachine.py
+++ b/src/ovirtcli/state/finitestatemachine.py
@@ -150,9 +150,10 @@
 #   @Requires([DFSAEvent], DFSAEvent)
 #   TODO: support multi-parameters definition ^
     def __init__(self, events, inital_state=DFSAEvent(
-                                      name='init',
+                                      name='disconnected',
                                       sources=[],
-                                      destination=DFSAState.DISCONNECTED
+                                      destination=DFSAState.DISCONNECTED,
+                                      description='init'
                                )
         ):
         '''
@@ -166,6 +167,7 @@
         self.__current_state_obj = None
         self.__current_state = None
         self.__origin_state = None
+        self.__origin_state_object = None
         self.__events = {}  # future use
 
         self.onBeforeApplyState = Event()
@@ -178,7 +180,7 @@
         self.onCanMove = Event()
 
         self.__register_events(events)
-        self.__apply_state(inital_state)
+        self.__resolve_inital_state(inital_state)
 
 #     @Requires(DFSAEvent)
     def __apply_state(self, event):
@@ -202,6 +204,7 @@
 
             old_state = self.get_current_state()
 
+            self.__origin_state_object = self.__current_state_obj 
             self.__current_state_obj = event
             self.__origin_state = self.__current_state
             self.__current_state = event.get_destination()
@@ -325,6 +328,12 @@
         """
         return self.__origin_state
 
+    def get_origin_state_event(self):
+        """
+        @return: the origin State of DFSA
+        """
+        return self.__origin_state_object
+
     @Requires(DFSAEvent)
     def can_move(self, event):
         """
@@ -346,3 +355,26 @@
         )
 
         return result
+
+    def rollback(self):
+        """
+        performs a rollback to the origin state
+        """
+        self.__apply_state(self.get_origin_state_event())
+
+    def __resolve_inital_state(self, inital_state):
+        """
+        resolves initial state of DFSA
+        
+        if user has defined same state as default one and DFSA can move to it -
+        it will be used, otherwise default state will be set as a initial. 
+        """
+        if self.__events.has_key(inital_state.get_name()) and \
+           self.can_move(inital_state):
+            self.__apply_state(
+                   self.__events.get(
+                         inital_state.get_name()
+                   )
+            )
+        else:
+            self.__apply_state(inital_state)
diff --git a/src/ovirtcli/state/statemachine.py 
b/src/ovirtcli/state/statemachine.py
index eba0556..41eedf5 100644
--- a/src/ovirtcli/state/statemachine.py
+++ b/src/ovirtcli/state/statemachine.py
@@ -106,7 +106,8 @@
         DFSAEvent(
           name='disconnected',
           sources=[
-               DFSAState.DISCONNECTING
+               DFSAState.DISCONNECTING,
+               DFSAState.CONNECTING
           ],
           destination=DFSAState.DISCONNECTED,
           callbacks=[]),


-- 
To view, visit http://gerrit.ovirt.org/23076
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ideaf855e2475bd39cf15454b09aa8add0fc08726
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine-cli
Gerrit-Branch: master
Gerrit-Owner: Michael Pasternak <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to