Martin Peřina has uploaded a new change for review.

Change subject: core: Introduce HostFenceActionExecutor
......................................................................

core: Introduce HostFenceActionExecutor

Introduces HostFenceActionExecutor which is responsible to
execute fence action on specified host.

Change-Id: I15bbc7e4a7a297173d3486394ac53587306078b1
Bug-Url: https://bugzilla.redhat.com/1182510
Signed-off-by: Martin Perina <[email protected]>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutor.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutorTest.java
2 files changed, 320 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/65/38965/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutor.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutor.java
new file mode 100644
index 0000000..681795e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutor.java
@@ -0,0 +1,109 @@
+package org.ovirt.engine.core.bll.pm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ovirt.engine.core.common.businessentities.FenceAgent;
+import org.ovirt.engine.core.common.businessentities.FencingPolicy;
+import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.pm.FenceActionType;
+import org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult;
+import 
org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult.Status;
+import org.ovirt.engine.core.common.businessentities.pm.HostPowerStatus;
+
+/**
+ * Manages fence execution for the host
+ */
+public class HostFenceActionExecutor {
+    /**
+     * Host which the action is executed for
+     */
+    private final VDS fencedHost;
+
+    /**
+     * Fencing policy applied during action execution
+     */
+    private final FencingPolicy fencingPolicy;
+
+    public HostFenceActionExecutor(VDS fencedHost) {
+        this(fencedHost, null);
+    }
+
+    public HostFenceActionExecutor(VDS fencedHost, FencingPolicy 
fencingPolicy) {
+        this.fencedHost = fencedHost;
+        this.fencingPolicy = fencingPolicy;
+    }
+
+    /**
+     * Executes specified power management action on the fencedHost using 
specified fence agent
+     *
+     * @param fenceAction
+     *            specified power management action
+     * @return result of the action
+     */
+    public FenceOperationResult fence(FenceActionType fenceAction, FenceAgent 
fenceAgent) {
+        if (fenceAgent == null) {
+            return new FenceOperationResult(
+                    Status.ERROR,
+                    HostPowerStatus.UNKNOWN,
+                    "Invalid fence agent specified.");
+        }
+
+        List<FenceAgent> fenceAgents = new ArrayList<>();
+        fenceAgents.add(fenceAgent);
+        return fence(fenceAction, fenceAgents);
+    }
+
+    /**
+     * Executes specified power management action on the fencedHost using 
fence agents defined for the host
+     *
+     * @param fenceAction
+     *            specified power management action
+     * @return result of the action
+     */
+    public FenceOperationResult fence(FenceActionType fenceAction) {
+        if (fencedHost.getFenceAgents() == null || 
fencedHost.getFenceAgents().isEmpty()) {
+            return new FenceOperationResult(
+                    Status.ERROR,
+                    HostPowerStatus.UNKNOWN,
+                    String.format(
+                            "Invalid fence agents defined for host '%s'.",
+                            fencedHost.getHostName()));
+        }
+        return fence(fenceAction, fencedHost.getFenceAgents());
+    }
+
+    /**
+     * Executes specified power management action using specified fence agents
+     */
+    protected FenceOperationResult fence(FenceActionType fenceAction, 
List<FenceAgent> fenceAgents) {
+        PowerManagementHelper.AgentsIterator iterator = 
createFenceAgentsIterator(fenceAgents);
+        FenceOperationResult result = null;
+        while (iterator.hasNext()) {
+            result = 
createFenceActionExecutor(iterator.next()).fence(fenceAction);
+            if (result.getStatus() == Status.SUCCESS) {
+                break;
+            }
+        }
+        return result;
+
+    }
+
+    /**
+     * Creates fence agents iterator
+     */
+    protected PowerManagementHelper.AgentsIterator 
createFenceAgentsIterator(List<FenceAgent> fenceAgents) {
+        return PowerManagementHelper.getAgentsIterator(fenceAgents);
+    }
+
+    /**
+     * Creates instance of {@code FenceActionExecutor} according to specified 
fence agents
+     */
+    FenceActionExecutor createFenceActionExecutor(List<FenceAgent> 
fenceAgents) {
+        if (fenceAgents.size() == 1) {
+            return new SingleAgentFenceActionExecutor(fencedHost, 
fenceAgents.get(0), fencingPolicy);
+        } else {
+            return new ConcurrentAgentsFenceActionExecutor(fencedHost, 
fenceAgents, fencingPolicy);
+        }
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutorTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutorTest.java
new file mode 100644
index 0000000..f09919f
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/pm/HostFenceActionExecutorTest.java
@@ -0,0 +1,211 @@
+package org.ovirt.engine.core.bll.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.ovirt.engine.core.common.businessentities.FenceAgent;
+import org.ovirt.engine.core.common.businessentities.FencingPolicy;
+import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.pm.FenceActionType;
+import org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult;
+import 
org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult.Status;
+import org.ovirt.engine.core.common.businessentities.pm.HostPowerStatus;
+import org.ovirt.engine.core.compat.Guid;
+
+@RunWith(MockitoJUnitRunner.class)
+public class HostFenceActionExecutorTest {
+    @Mock
+    VDS fencedHost;
+
+    @Mock
+    SingleAgentFenceActionExecutor agentExecutor1;
+
+    @Mock
+    SingleAgentFenceActionExecutor agentExecutor2;
+
+    HostFenceActionExecutor executor;
+
+    List<FenceAgent> fenceAgents;
+
+    @Before
+    public void setup() {
+        doReturn("host1").when(fencedHost).getHostName();
+
+        executor = spy(new HostFenceActionExecutor(fencedHost, new 
FencingPolicy()));
+        doReturn(agentExecutor1)
+                .doReturn(agentExecutor2)
+                .when(executor).createFenceActionExecutor(any(List.class));
+    }
+
+    /**
+     * Test successful fence action when the 1st of 2 sequential fence agents 
returns success
+     */
+    @Test
+    public void successfulFenceWith1stSuccess() {
+        mockFenceAgents();
+
+        // result of fence action invoked on 1st sequential agent
+        mockFenceResult(
+                agentExecutor1,
+                new FenceOperationResult(Status.SUCCESS, HostPowerStatus.ON));
+
+        // result of fence action invoked on 2nd sequential agent - set it to 
error, so we verify that it's not used
+        mockFenceResult(
+                agentExecutor2,
+                new FenceOperationResult(Status.ERROR, 
HostPowerStatus.UNKNOWN));
+
+        FenceOperationResult result = executor.fence(FenceActionType.STATUS);
+
+        assertEquals(Status.SUCCESS, result.getStatus());
+        assertEquals(HostPowerStatus.ON, result.getPowerStatus());
+    }
+
+    /**
+     * Test successful fence action when the 1st of 2 sequential fence agents 
returns error and 2nd one return success
+     */
+    @Test
+    public void successfulFenceWith1stError2ndSuccess() {
+        mockFenceAgents();
+
+        // result of fence action invoked on 1st sequential agent
+        mockFenceResult(
+                agentExecutor1,
+                new FenceOperationResult(Status.ERROR, 
HostPowerStatus.UNKNOWN));
+
+        // result of fence action invoked on 2nd sequential agent
+        mockFenceResult(
+                agentExecutor2,
+                new FenceOperationResult(Status.SUCCESS, HostPowerStatus.ON));
+
+        FenceOperationResult result = executor.fence(FenceActionType.STATUS);
+
+        assertEquals(Status.SUCCESS, result.getStatus());
+        assertEquals(HostPowerStatus.ON, result.getPowerStatus());
+    }
+
+    /**
+     * Test failed fence action when both of 2 sequential fence agents return 
error
+     */
+    @Test
+    public void failedFenceWithAllError() {
+        mockFenceAgents();
+
+        // result of fence action invoked on 1st sequential agent
+        mockFenceResult(
+                agentExecutor1,
+                new FenceOperationResult(Status.ERROR, 
HostPowerStatus.UNKNOWN));
+
+        // result of fence action invoked on 2nd sequential agent
+        mockFenceResult(
+                agentExecutor2,
+                new FenceOperationResult(Status.ERROR, 
HostPowerStatus.UNKNOWN));
+
+        FenceOperationResult result = executor.fence(FenceActionType.STATUS);
+
+        assertEquals(Status.ERROR, result.getStatus());
+        assertEquals(HostPowerStatus.UNKNOWN, result.getPowerStatus());
+    }
+
+    /**
+     * Test successful fence action using specified fence agent
+     */
+    @Test
+    public void successfulFenceWithSpecifiedFenceAgent() {
+        // result of fence action invoked on specified agent
+        mockFenceResult(
+                agentExecutor1,
+                new FenceOperationResult(Status.SUCCESS, HostPowerStatus.ON));
+
+        FenceOperationResult result = executor.fence(FenceActionType.STATUS, 
createFenceAgent(1));
+
+        assertEquals(Status.SUCCESS, result.getStatus());
+        assertEquals(HostPowerStatus.ON, result.getPowerStatus());
+    }
+
+    /**
+     * Test failed fence action using specified fence agent
+     */
+    @Test
+    public void failedFenceWithSpecifiedFenceAgent() {
+        // result of fence action invoked on specified agent
+        mockFenceResult(
+                agentExecutor1,
+                new FenceOperationResult(Status.ERROR, 
HostPowerStatus.UNKNOWN));
+
+        FenceOperationResult result = executor.fence(FenceActionType.STATUS, 
createFenceAgent(1));
+
+        assertEquals(Status.ERROR, result.getStatus());
+        assertEquals(HostPowerStatus.UNKNOWN, result.getPowerStatus());
+    }
+
+    /**
+     * Tests {@code SingleAgentFenceActionExecutor} creation for single fence 
agent
+     */
+    @Test
+    public void testSingleAgentFenceActionExecutorUsage() {
+        HostFenceActionExecutor executor = new 
HostFenceActionExecutor(fencedHost, new FencingPolicy());
+
+        assertTrue(
+                executor.createFenceActionExecutor(createSingleAgentList(1))
+                        instanceof SingleAgentFenceActionExecutor);
+    }
+
+    /**
+     * Tests {@code ConcurrentAgentsFenceActionExecutor} creation for 
concurrent fence agents
+     */
+    @Test
+    public void testConcurrentAgentsFenceActionExecutorUsage() {
+        HostFenceActionExecutor executor = new 
HostFenceActionExecutor(fencedHost, new FencingPolicy());
+
+        assertTrue(
+                
executor.createFenceActionExecutor(createConcurrentAgentsList(2, 1))
+                        instanceof ConcurrentAgentsFenceActionExecutor);
+    }
+
+    protected FenceAgent createFenceAgent(int order) {
+        FenceAgent agent = new FenceAgent();
+        agent.setId(Guid.newGuid());
+        agent.setOrder(order);
+        return agent;
+    }
+
+    protected List<FenceAgent> createSingleAgentList(int order) {
+        List<FenceAgent> fenceAgents = new ArrayList<>();
+        fenceAgents.add(createFenceAgent(order));
+        return fenceAgents;
+    }
+
+    protected List<FenceAgent> createConcurrentAgentsList(int count, int 
order) {
+        List<FenceAgent> fenceAgents = new ArrayList<>();
+        for (int i = 0; i < count; i++) {
+            fenceAgents.add(createFenceAgent(order));
+        }
+        return fenceAgents;
+    }
+
+    protected List<FenceAgent> create2SequentialFenceAgents() {
+        List<FenceAgent> fenceAgents = createSingleAgentList(1);
+        fenceAgents.addAll(createSingleAgentList(2));
+        return fenceAgents;
+    }
+
+    protected void mockFenceResult(FenceActionExecutor executor, 
FenceOperationResult result) {
+        doReturn(result).when(executor).fence(any(FenceActionType.class));
+    }
+
+    protected void mockFenceAgents() {
+        fenceAgents = create2SequentialFenceAgents();
+        doReturn(fenceAgents).when(fencedHost).getFenceAgents();
+    }
+}


-- 
To view, visit https://gerrit.ovirt.org/38965
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I15bbc7e4a7a297173d3486394ac53587306078b1
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Martin Peřina <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to