BUG-5414 introduce EOS inJeopardy flag 56/37956/2
authorVaclav Demcak <vdemcak@cisco.com>
Mon, 18 Apr 2016 16:05:46 +0000 (18:05 +0200)
committerRobert Varga <nite@hq.sk>
Mon, 2 May 2016 14:08:59 +0000 (14:08 +0000)
The inJeopardy flag is used to indicate that the leader has lost quorum,
e.g. if cannot reach majority of followers or the follower has lost connection
to the leader (and has initiated new elections).

While EOS is in jeopardy, any reported entity state may not reflect cluster-wide
consensus, but rather represents the latest intended state as seen by this node.

Depend on:
https://git.opendaylight.org/gerrit/#/c/36752/7

Change-Id: I8f17fb97dd6ec54222b783bb7b4b827ce9b4a0ad
Signed-off-by: Vaclav Demcak <vdemcak@cisco.com>
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/clustering/EntityOwnershipChange.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/clustering/DOMEntityOwnershipListenerAdapter.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/clustering/BindingDOMEntityOwnershipServiceAdapterTest.java
common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/clustering/GenericEntityOwnershipChange.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/clustering/DOMEntityOwnershipChange.java

index c5edfebdf04e71677d0da033ec58fc8ac1b11479..e15b4fe79b1eb1a97a806152ebda95faf7dd88f7 100644 (file)
@@ -25,6 +25,14 @@ public class EntityOwnershipChange extends GenericEntityOwnershipChange<Instance
      * {@inheritDoc}
      */
     public EntityOwnershipChange(@Nonnull final Entity entity, @Nonnull final EntityOwnershipChangeState state) {
-        super(entity, state);
+        super(entity, state, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public EntityOwnershipChange(@Nonnull final Entity entity, @Nonnull final EntityOwnershipChangeState state,
+            final boolean inJeopardy) {
+        super(entity, state, inJeopardy);
     }
 }
index c2ca39b36cd461c6d459cada24f6bd079bd20bb9..25f8b080fc8bf199bbe948b87da74b31c9284cd0 100644 (file)
@@ -24,19 +24,20 @@ class DOMEntityOwnershipListenerAdapter implements DOMEntityOwnershipListener {
     private final BindingToNormalizedNodeCodec conversionCodec;
     private final EntityOwnershipListener bindingListener;
 
-    DOMEntityOwnershipListenerAdapter(EntityOwnershipListener bindingListener,
-            BindingToNormalizedNodeCodec conversionCodec) {
+    DOMEntityOwnershipListenerAdapter(final EntityOwnershipListener bindingListener,
+            final BindingToNormalizedNodeCodec conversionCodec) {
         this.bindingListener = Preconditions.checkNotNull(bindingListener);
         this.conversionCodec = Preconditions.checkNotNull(conversionCodec);
     }
 
     @Override
-    public void ownershipChanged(DOMEntityOwnershipChange ownershipChange) {
+    public void ownershipChanged(final DOMEntityOwnershipChange ownershipChange) {
         try {
-            Entity entity = new Entity(ownershipChange.getEntity().getType(), conversionCodec.toBinding(
+            final Entity entity = new Entity(ownershipChange.getEntity().getType(), conversionCodec.toBinding(
                     ownershipChange.getEntity().getIdentifier()).get());
-            bindingListener.ownershipChanged(new EntityOwnershipChange(entity, ownershipChange.getState()));
-        } catch (Exception e) {
+            bindingListener.ownershipChanged(new EntityOwnershipChange(entity, ownershipChange.getState(),
+                    ownershipChange.inJeopardy()));
+        } catch (final Exception e) {
             BindingDOMEntityOwnershipServiceAdapter.LOG.error("Error converting DOM entity ID {} to binding InstanceIdentifier",
                     ownershipChange.getEntity().getIdentifier(), e);
         }
index a0b7a1e29648a2f44195185b9b67cc6be759255f..9c56fb98839c28f459320104617a036e3a8b8f56 100644 (file)
@@ -70,10 +70,10 @@ public class BindingDOMEntityOwnershipServiceAdapterTest {
 
     @Test
     public void testRegisterCandidate() throws CandidateAlreadyRegisteredException {
-        DOMEntityOwnershipCandidateRegistration mockDOMReg = mock(DOMEntityOwnershipCandidateRegistration.class);
+        final DOMEntityOwnershipCandidateRegistration mockDOMReg = mock(DOMEntityOwnershipCandidateRegistration.class);
         doReturn(mockDOMReg).when(mockDOMService).registerCandidate(DOM_ENTITY);
 
-        EntityOwnershipCandidateRegistration reg = adapter.registerCandidate(BINDING_ENTITY);
+        final EntityOwnershipCandidateRegistration reg = adapter.registerCandidate(BINDING_ENTITY);
 
         assertNotNull("registerCandidate returned null", reg);
         assertEquals("getInstance", BINDING_ENTITY, reg.getInstance());
@@ -84,28 +84,28 @@ public class BindingDOMEntityOwnershipServiceAdapterTest {
 
     @Test
     public void testRegisterListener() {
-        DOMEntityOwnershipListenerRegistration mockDOMReg = mock(DOMEntityOwnershipListenerRegistration.class);
+        final DOMEntityOwnershipListenerRegistration mockDOMReg = mock(DOMEntityOwnershipListenerRegistration.class);
         doReturn(mockDOMReg).when(mockDOMService).registerListener(eq(DOM_ENTITY.getType()),
                 any(DOMEntityOwnershipListener.class));
-        EntityOwnershipListener mockListener = mock(EntityOwnershipListener.class);
+        final EntityOwnershipListener mockListener = mock(EntityOwnershipListener.class);
 
-        EntityOwnershipListenerRegistration reg = adapter.registerListener(BINDING_ENTITY.getType(), mockListener);
+        final EntityOwnershipListenerRegistration reg = adapter.registerListener(BINDING_ENTITY.getType(), mockListener);
 
         assertNotNull("registerListener returned null", reg);
         assertEquals("getInstance", mockListener, reg.getInstance());
         assertEquals("getEntityType", BINDING_ENTITY.getType(), reg.getEntityType());
 
-        ArgumentCaptor<DOMEntityOwnershipListener> domListenerCaptor = ArgumentCaptor.forClass(DOMEntityOwnershipListener.class);
+        final ArgumentCaptor<DOMEntityOwnershipListener> domListenerCaptor = ArgumentCaptor.forClass(DOMEntityOwnershipListener.class);
         verify(mockDOMService).registerListener(eq(DOM_ENTITY.getType()),  domListenerCaptor.capture());
 
-        DOMEntityOwnershipChange domOwnershipChange = new DOMEntityOwnershipChange(DOM_ENTITY,
-                EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED);
+        final DOMEntityOwnershipChange domOwnershipChange = new DOMEntityOwnershipChange(DOM_ENTITY,
+                EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED, true);
         domListenerCaptor.getValue().ownershipChanged(domOwnershipChange );
 
-        ArgumentCaptor<EntityOwnershipChange> ownershipChangeCaptor = ArgumentCaptor.forClass(EntityOwnershipChange.class);
+        final ArgumentCaptor<EntityOwnershipChange> ownershipChangeCaptor = ArgumentCaptor.forClass(EntityOwnershipChange.class);
         verify(mockListener).ownershipChanged(ownershipChangeCaptor.capture());
 
-        EntityOwnershipChange change = ownershipChangeCaptor.getValue();
+        final EntityOwnershipChange change = ownershipChangeCaptor.getValue();
         assertEquals("getEntity", BINDING_ENTITY, change.getEntity());
         assertEquals("getState", EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED, change.getState());
 
@@ -115,10 +115,10 @@ public class BindingDOMEntityOwnershipServiceAdapterTest {
 
     @Test
     public void testGetOwnershipState() {
-        Optional<EntityOwnershipState>  expectedState = Optional.of(EntityOwnershipState.IS_OWNER);
+        final Optional<EntityOwnershipState>  expectedState = Optional.of(EntityOwnershipState.IS_OWNER);
         doReturn(expectedState).when(mockDOMService).getOwnershipState(DOM_ENTITY);
 
-        Optional<EntityOwnershipState> actualState = adapter.getOwnershipState(BINDING_ENTITY);
+        final Optional<EntityOwnershipState> actualState = adapter.getOwnershipState(BINDING_ENTITY);
 
         assertSame("getOwnershipState", expectedState, actualState);
     }
index e70aa5df8a476ed94266a80324ffae16de324e1b..338ecdd05e15dbad67587012c9c55ba06cbc4750 100644 (file)
@@ -22,10 +22,17 @@ import org.opendaylight.yangtools.concepts.Path;
 public class GenericEntityOwnershipChange<P extends Path<P>, E extends GenericEntity<P>> {
     private final E entity;
     private final EntityOwnershipChangeState state;
+    private final boolean inJeopardy;
 
-    public GenericEntityOwnershipChange(@Nonnull E entity, @Nonnull EntityOwnershipChangeState state) {
+    public GenericEntityOwnershipChange(@Nonnull final E entity, @Nonnull final EntityOwnershipChangeState state) {
+        this(entity, state, false);
+    }
+
+    public GenericEntityOwnershipChange(@Nonnull final E entity, @Nonnull final EntityOwnershipChangeState state,
+            final boolean inJeopardy) {
         this.entity = Preconditions.checkNotNull(entity, "entity can't be null");
         this.state = Preconditions.checkNotNull(state, "state can't be null");
+        this.inJeopardy = inJeopardy;
     }
 
     /**
@@ -44,8 +51,18 @@ public class GenericEntityOwnershipChange<P extends Path<P>, E extends GenericEn
         return state;
     }
 
+    /**
+     * Returns the current jeopardy state. When in a jeopardy state, the values from other methods may potentially
+     * be out of date.
+     *
+     * @return true if the local node is in a jeopardy state. If false, the reported information is accurate.
+     */
+    public boolean inJeopardy() {
+        return inJeopardy;
+    }
+
     @Override
     public String toString() {
-        return getClass().getSimpleName() + " [entity=" + entity + ", state=" + state + "]";
+        return getClass().getSimpleName() + " [entity=" + entity + ", state=" + state + ", inJeopardy=" + inJeopardy + "]";
     }
 }
index e25f6f2aa4cd12be22bd99de9a06a4f7e236568a..579a84595e70d08c1cf64a8af43f97bb264ffb30 100644 (file)
@@ -25,6 +25,14 @@ public class DOMEntityOwnershipChange extends GenericEntityOwnershipChange<YangI
      * {@inheritDoc}
      */
     public DOMEntityOwnershipChange(@Nonnull final DOMEntity entity, @Nonnull final EntityOwnershipChangeState state) {
-        super(entity, state);
+        super(entity, state, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public DOMEntityOwnershipChange(@Nonnull final DOMEntity entity, @Nonnull final EntityOwnershipChangeState state,
+            final boolean inJeopardy) {
+        super(entity, state, inJeopardy);
     }
 }