Repository: hadoop
Updated Branches:
  refs/heads/HDFS-7240 8151f26a1 -> 293c425b2


HDFS-12305. Ozone: SCM: Add StateMachine for pipeline/container. Contributed by 
Xiaoyu Yao.


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/293c425b
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/293c425b
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/293c425b

Branch: refs/heads/HDFS-7240
Commit: 293c425b25b1c2ceff2eaa726e804ede767e371c
Parents: 8151f26
Author: Anu Engineer <aengin...@apache.org>
Authored: Wed Aug 16 14:36:34 2017 -0700
Committer: Anu Engineer <aengin...@apache.org>
Committed: Wed Aug 16 14:36:34 2017 -0700

----------------------------------------------------------------------
 .../InvalidStateTransitionException.java        | 42 +++++++++
 .../helpers/StateMachine/StateMachine.java      | 69 ++++++++++++++
 .../org/apache/hadoop/scm/TestStateMachine.java | 95 ++++++++++++++++++++
 3 files changed, 206 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/293c425b/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/InvalidStateTransitionException.java
----------------------------------------------------------------------
diff --git 
a/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/InvalidStateTransitionException.java
 
b/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/InvalidStateTransitionException.java
new file mode 100644
index 0000000..1fab16b
--- /dev/null
+++ 
b/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/InvalidStateTransitionException.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.hadoop.scm.container.common.helpers.StateMachine;
+
+/**
+ * Class wraps invalid state transition exception.
+ */
+public class InvalidStateTransitionException extends Exception {
+  private Enum<?> currentState;
+  private Enum<?> event;
+
+  public InvalidStateTransitionException(Enum<?> currentState, Enum<?> event) {
+    super("Invalid event: " + event + " at " + currentState + " state.");
+    this.currentState = currentState;
+    this.event = event;
+  }
+
+  public Enum<?> getCurrentState() {
+    return currentState;
+  }
+
+  public Enum<?> getEvent() {
+    return event;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/293c425b/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/StateMachine.java
----------------------------------------------------------------------
diff --git 
a/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/StateMachine.java
 
b/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/StateMachine.java
new file mode 100644
index 0000000..1d5436f
--- /dev/null
+++ 
b/hadoop-hdfs-client/src/main/java/org/apache/hadoop/scm/container/common/helpers/StateMachine/StateMachine.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.hadoop.scm.container.common.helpers.StateMachine;
+
+import com.google.common.base.Supplier;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Template class that wraps simple event driven state machine.
+ * @param <STATE> states allowed
+ * @param <EVENT> events allowed
+ */
+public class StateMachine<STATE extends Enum<?>, EVENT extends Enum<?>> {
+  private STATE initialState;
+  private Set<STATE> finalStates;
+
+  private final Cache<EVENT, Map<STATE, STATE>> transitions =
+      CacheBuilder.newBuilder().build(
+          CacheLoader.from((Supplier<Map<STATE, STATE>>) () -> new HashMap()));
+
+  public StateMachine(STATE initState, Set<STATE> finalStates) {
+    this.initialState = initState;
+    this.finalStates = finalStates;
+  }
+
+  public STATE getInitialState() {
+    return initialState;
+  }
+
+  public Set<STATE> getFinalStates() {
+    return finalStates;
+  }
+
+  public STATE getNextState(STATE from, EVENT e)
+      throws InvalidStateTransitionException {
+    STATE target = transitions.getUnchecked(e).get(from);
+    if (target == null) {
+      throw new InvalidStateTransitionException(from, e);
+    }
+    return target;
+  }
+
+  public void addTransition(STATE from, STATE to, EVENT e)
+      throws InvalidStateTransitionException {
+    transitions.getUnchecked(e).put(from, to);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/293c425b/hadoop-hdfs-client/src/test/java/org/apache/hadoop/scm/TestStateMachine.java
----------------------------------------------------------------------
diff --git 
a/hadoop-hdfs-client/src/test/java/org/apache/hadoop/scm/TestStateMachine.java 
b/hadoop-hdfs-client/src/test/java/org/apache/hadoop/scm/TestStateMachine.java
new file mode 100644
index 0000000..f9e1d5a
--- /dev/null
+++ 
b/hadoop-hdfs-client/src/test/java/org/apache/hadoop/scm/TestStateMachine.java
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership.  The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+
+package org.apache.hadoop.scm;
+
+import org.apache.commons.collections.SetUtils;
+import 
org.apache.hadoop.scm.container.common.helpers.StateMachine.InvalidStateTransitionException;
+import 
org.apache.hadoop.scm.container.common.helpers.StateMachine.StateMachine;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.apache.hadoop.scm.TestStateMachine.STATES.INIT;
+import static org.apache.hadoop.scm.TestStateMachine.STATES.CREATING;
+import static org.apache.hadoop.scm.TestStateMachine.STATES.OPERATIONAL;
+import static org.apache.hadoop.scm.TestStateMachine.STATES.CLOSED;
+import static org.apache.hadoop.scm.TestStateMachine.STATES.CLEANUP;
+import static org.apache.hadoop.scm.TestStateMachine.STATES.FINAL;
+
+public class TestStateMachine {
+
+  public enum STATES {INIT, CREATING, OPERATIONAL, CLOSED, CLEANUP, FINAL};
+
+  public enum EVENTS {ALLOCATE, CREATE, UPDATE, CLOSE, DELETE, TIMEOUT};
+
+  @Rule
+  public ExpectedException exception = ExpectedException.none();
+
+  @Test
+  public void testStateMachineStates() throws InvalidStateTransitionException {
+    Set<STATES> finals = new HashSet<>();
+    finals.add(FINAL);
+
+    StateMachine<STATES, EVENTS> stateMachine =
+        new StateMachine<>(INIT, finals);
+
+    stateMachine.addTransition(INIT, CREATING, EVENTS.ALLOCATE);
+    stateMachine.addTransition(CREATING, OPERATIONAL, EVENTS.CREATE);
+    stateMachine.addTransition(OPERATIONAL, OPERATIONAL, EVENTS.UPDATE);
+    stateMachine.addTransition(OPERATIONAL, CLEANUP, EVENTS.DELETE);
+    stateMachine.addTransition(OPERATIONAL, CLOSED, EVENTS.CLOSE);
+    stateMachine.addTransition(CREATING, CLEANUP, EVENTS.TIMEOUT);
+
+    // Initial and Final states
+    Assert.assertEquals("Initial State", INIT, stateMachine.getInitialState());
+    Assert.assertTrue("Final States", SetUtils.isEqualSet(finals,
+        stateMachine.getFinalStates()));
+
+    // Valid state transitions
+    Assert.assertEquals("STATE should be OPERATIONAL after being created",
+        OPERATIONAL, stateMachine.getNextState(CREATING, EVENTS.CREATE));
+    Assert.assertEquals("STATE should be OPERATIONAL after being updated",
+        OPERATIONAL, stateMachine.getNextState(OPERATIONAL, EVENTS.UPDATE));
+    Assert.assertEquals("STATE should be CLEANUP after being deleted",
+        CLEANUP, stateMachine.getNextState(OPERATIONAL, EVENTS.DELETE));
+    Assert.assertEquals("STATE should be CLEANUP after being timeout",
+        CLEANUP, stateMachine.getNextState(CREATING, EVENTS.TIMEOUT));
+    Assert.assertEquals("STATE should be CLOSED after being closed",
+        CLOSED, stateMachine.getNextState(OPERATIONAL, EVENTS.CLOSE));
+    
+    // Negative cases: invalid transition
+    expectException();
+    stateMachine.getNextState(OPERATIONAL, EVENTS.CREATE);
+
+    expectException();
+    stateMachine.getNextState(CREATING, EVENTS.CLOSE);
+  }
+
+  /**
+   * We expect an InvalidStateTransitionException.
+   */
+  private void expectException() {
+    exception.expect(InvalidStateTransitionException.class);
+    exception.expectMessage("Invalid event");
+  }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to